Spaces:
Sleeping
Sleeping
Add echo streaming endpoint
Browse files
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([
|
|
|
|
|
|
|
|
|
|
| 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)
|