Source code for mdvtools.websocket
from flask import Flask, Request as FlaskRequest
from flask_socketio import SocketIO
from datetime import datetime
from typing import Optional
[docs]
def log(msg: str):
now = datetime.now()
date_str = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"[[[ socket.io ]]] [{date_str}] - {msg}")
[docs]
socketio: Optional[SocketIO] = None
# This is a map of chat request IDs to user IDs, used to track which user is associated with which chat session.
# something of a placeholder
# chat_sid_map: dict[str, str] = {}
[docs]
class SocketIOContextRequest(FlaskRequest):
"""
Represents the Flask request object when in a Flask-SocketIO event context.
This protocol ensures the 'sid' (session ID) attribute is recognized by type checkers.
"""
# namespace: Optional[str]
# event: Optional[str]
[docs]
def mdv_socketio(app: Flask):
"""
Experimental and not to be trusted pending design work etc.
Do we have a SocketIO for the entire app and route messages internally,
- yes probably.
What `path` should it use? We'll need to make sure it is compatible with
- the vite dev server proxy
- the app not being at the root of the domain
!! What about cors? We had a wildcard for previous experiment - should be reviewed before getting pushed online.
^^^^
"""
global socketio
# allow cors for localhost:5170-5179
# cors = [f"http://localhost:{i}" for i in range(5170,5180)]
socketio = SocketIO(app, cors_allowed_origins="*")
log("socketio initialized with cors_allowed_origins wildcard")
# @socketio.on("message")
# def message(data):
# # 'hello world'... if we have need for more logic here, we'll probably use a dictionary of functions for each message type.
# if data['type'] == "popout":
# log(f"popout: {data}")
# if data['type'] == "ping":
# log(f"ping: {data}")
# # socketio.emit("message", {"type": "ping", "message": "bleep bloop I'm a robot"})
# # how about getting it to respond only to the client that sent the message?
# # socketio.emit("message", {"type": "ping", "message": "bleep bloop I'm a robot"}, to=request.sid)
# # ... or maybe I should stick to REST for now.
# sid = request.args.get("sid")
# # error asyncio.run() cannot be called from a running event loop
# # asyncio.run(response(sid, data.get('message')))
# # response(sid, data.get('message'))