steffenc commited on
Commit
728d41d
·
1 Parent(s): 1321e38

Add echo streaming endpoint

Browse files
Files changed (1) hide show
  1. server.py +71 -2
server.py CHANGED
@@ -3,6 +3,7 @@
3
 
4
  import os
5
  import re
 
6
  import asyncio
7
  import json
8
  import traceback
@@ -24,6 +25,9 @@ from aiohttp.web_response import Response
24
  curl -X POST http://0.0.0.0:10000/chat/ -H "api_key: hello" -d '{"k": 5, "timeout": 3, "roles": ["user"], "messages": ["hello world"]}'
25
 
26
  curl -X POST http://0.0.0.0:10000/chat/ -H "api_key: hey-michal" -d '{"k": 5, "timeout": 3, "roles": ["user"], "messages": ["on what exact date did the 21st century begin?"]}'
 
 
 
27
  ```
28
 
29
  TROUBLESHOOT
@@ -31,11 +35,17 @@ check if port is open
31
  ```
32
  sudo ufw allow 10000/tcp
33
  sudo ufw allow 10000/tcp
34
- ```
35
  # run
36
  ```
37
  EXPECTED_ACCESS_KEY="hey-michal" pm2 start app.py --interpreter python3 --name app -- --neuron.model_id mock --wallet.name sn1 --wallet.hotkey v1 --netuid 1 --neuron.tasks math --neuron.task_p 1 --neuron.device cpu
38
  ```
 
 
 
 
 
 
39
  """
40
 
41
  EXPECTED_ACCESS_KEY = os.environ.get('EXPECTED_ACCESS_KEY')
@@ -210,6 +220,62 @@ async def chat(request: web.Request) -> Response:
210
 
211
 
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
  class ValidatorApplication(web.Application):
215
  def __init__(self, *a, **kw):
@@ -218,7 +284,10 @@ class ValidatorApplication(web.Application):
218
 
219
 
220
  validator_app = ValidatorApplication()
221
- validator_app.add_routes([web.post('/chat/', chat)])
 
 
 
222
 
223
  bt.logging.info("Starting validator application.")
224
  bt.logging.info(validator_app)
 
3
 
4
  import os
5
  import re
6
+ import time
7
  import asyncio
8
  import json
9
  import traceback
 
25
  curl -X POST http://0.0.0.0:10000/chat/ -H "api_key: hello" -d '{"k": 5, "timeout": 3, "roles": ["user"], "messages": ["hello world"]}'
26
 
27
  curl -X POST http://0.0.0.0:10000/chat/ -H "api_key: hey-michal" -d '{"k": 5, "timeout": 3, "roles": ["user"], "messages": ["on what exact date did the 21st century begin?"]}'
28
+
29
+ # stream
30
+ curl --no-buffer -X POST http://129.146.127.82:10000/echo/ -H "api_key: hey-michal" -d '{"k": 3, "timeout": 0.2, "roles": ["user"], "messages": ["i need to tell you something important but first"]}'
31
  ```
32
 
33
  TROUBLESHOOT
 
35
  ```
36
  sudo ufw allow 10000/tcp
37
  sudo ufw allow 10000/tcp
38
+ ```
39
  # run
40
  ```
41
  EXPECTED_ACCESS_KEY="hey-michal" pm2 start app.py --interpreter python3 --name app -- --neuron.model_id mock --wallet.name sn1 --wallet.hotkey v1 --netuid 1 --neuron.tasks math --neuron.task_p 1 --neuron.device cpu
42
  ```
43
+
44
+ basic testing
45
+ ```
46
+ EXPECTED_ACCESS_KEY="hey-michal" python app.py --neuron.model_id mock --wallet.name sn1 --wallet.hotkey v1 --netuid 1 --neuron.tasks math --neuron.task_p 1 --neuron.device cpu
47
+ ```
48
+ add --mock to test the echo stream
49
  """
50
 
51
  EXPECTED_ACCESS_KEY = os.environ.get('EXPECTED_ACCESS_KEY')
 
220
 
221
 
222
 
223
+ async def echo_stream(request):
224
+
225
+ bt.logging.info(f'echo_stream()')
226
+ # Check access key
227
+ access_key = request.headers.get("api_key")
228
+ if EXPECTED_ACCESS_KEY is not None and access_key != EXPECTED_ACCESS_KEY:
229
+ bt.logging.error(f'Invalid access key: {access_key}')
230
+ return Response(status=401, reason="Invalid access key")
231
+
232
+ try:
233
+ request_data = await request.json()
234
+ except ValueError:
235
+ bt.logging.error(f'Invalid request data: {request_data}')
236
+ return Response(status=400)
237
+
238
+ bt.logging.info(f'Request data: {request_data}')
239
+ k = request_data.get('k', 1)
240
+ exclude = request_data.get('exclude', [])
241
+ timeout = request_data.get('timeout', 0.2)
242
+ message = '\n\n'.join(request_data['messages'])
243
+
244
+ # Create a StreamResponse
245
+ response = web.StreamResponse(status=200, reason='OK', headers={'Content-Type': 'text/plain'})
246
+ await response.prepare(request)
247
+
248
+ completion = ''
249
+ # Echo the message k times with a timeout between each chunk
250
+ for _ in range(k):
251
+ for word in message.split():
252
+ chunk = f'{word} '
253
+ await response.write(chunk.encode('utf-8'))
254
+ completion += chunk
255
+ time.sleep(timeout)
256
+ bt.logging.info(f"Echoed: {chunk}")
257
+
258
+ completion = completion.strip()
259
+
260
+ # Prepare final JSON chunk
261
+ json_chunk = json.dumps({
262
+ "uids": [0],
263
+ "completion": completion,
264
+ "completions": [completion.strip()],
265
+ "timings": [0],
266
+ "status_messages": ['Went well!'],
267
+ "status_codes": [200],
268
+ "completion_is_valid": [True],
269
+ "task_name": 'echo',
270
+ "ensemble_result": {}
271
+ })
272
+
273
+ # Send the final JSON as part of the stream
274
+ await response.write(f"\n\nJSON_RESPONSE_BEGIN:\n{json_chunk}".encode('utf-8'))
275
+
276
+ # Finalize the response
277
+ await response.write_eof()
278
+ return response
279
 
280
  class ValidatorApplication(web.Application):
281
  def __init__(self, *a, **kw):
 
284
 
285
 
286
  validator_app = ValidatorApplication()
287
+ validator_app.add_routes([
288
+ web.post('/chat/', chat),
289
+ web.post('/echo/', echo_stream)
290
+ ])
291
 
292
  bt.logging.info("Starting validator application.")
293
  bt.logging.info(validator_app)