Description
The example from #24 demonstrates a console log I'm seeing from Brython, "empty stack".
This seems innocuous in this case (as the callback's "self" parameter is well-formed).
But I'm also seeing it when using vue-socketio, and when using it there. Not only that, but callbacks don't seem to have a "self".
I've tried to make a minimal example below, but appreciate that setting up websockets is a bit non-standard.
This example also demonstrate's vue-socketio's inability to call the mutation functions in the Store object.
I wrote a JS equivalent of this which exhibited no issues, so it's clearly the py<->js interop.
server.py
import os
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from starlette.responses import FileResponse
import socketio
def relative_dir(path):
return os.path.join(os.path.dirname(__file__), path)
app = FastAPI()
app.sio = socketio.AsyncServer(async_mode='asgi')
app.mount('/ws', socketio.ASGIApp(app.sio))
app.mount("/static", StaticFiles(directory=relative_dir('static')), name="static")
@app.get("/")
async def read_index():
return FileResponse(relative_dir('static/index.html'))
@app.sio.event()
def connect(sid, *args, **kwargs):
print(f'{sid} connected')
@app.sio.event()
def disconnect(sid, *args, **kwargs):
print(f'{sid} disconnected')
if __name__ == '__main__':
import uvicorn
uvicorn.run("basic_server:app", host="127.0.0.1", port=5000, log_level="info")
index.html
<html>
<head>
<title>TEST</title>
</head>
<body onload="brython({cache: true, pythonpath: ['/static']})">
<div id="app"></div>
<!-- socketio -->
<script src="https://cdn.jsdelivr.net/npm/socket.io@4.5.0/client-dist/socket.io.min.js"></script>
<!-- vue -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex@3.6.2/dist/vuex.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.4/dist/vue-router.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-socket.io@3.0.10/dist/vue-socketio.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/brython@3.10.6/brython.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/brython@3.10.6/brython_stdlib.min.js"></script>
<script type="text/python">
from textwrap import dedent
from browser import window, document, load, html
from vue import Vue, VueStore, VueComponent, data, computed, mutation
from vue.decorators.base import VueDecorator, pyjs_bridge
class Sockets(VueDecorator):
__key__ = "sockets"
def __init__(self, fn, name=None):
self.__id__ = name or fn.__name__
self.__value__ = pyjs_bridge(fn)
def sockets(fn):
if callable(fn):
return Sockets(fn)
name = fn
def inner(fn):
return Sockets(fn, name)
return inner
class Store(VueStore):
@mutation
def socket_connect(self):
print(f'Store.socket_connect()')
@mutation
def socket_set_username(self, username):
print(f'Store.socket_set_username({username})')
class App(VueComponent):
template = '<div>Hello</div>'
@sockets
def connect(self, *args, **kwargs):
print(f'App.connect({self}, {args}, {kwargs})')
store_ = Store()
Vue.use(window.VueSocketIO.new({
'debug': True,
'connection': window.io({
'path': '/ws/socket.io',
'transports': ["websocket"],
}),
'vuex': {
'store': store_,
'actionPrefix': 'socket_',
'mutationPrefix': 'socket_'
},
}))
App("#app", store=store_)
</script>
</body>
</html>
Browser console output:
Vue-Socket.io: Received socket.io-client instance
Vue-Socket.io: Vuex adapter enabled
Vue-Socket.io: Vuex socket mutations enabled
Vue-Socket.io: Vuex socket actions enabled
Vue-Socket.io: Vue-Socket.io plugin enabled
Vue-Socket.io: #connect subscribe, component: undefined
vue.min.js:6 Error: callback must be a function
at t.value (vue-socketio.min.js:14:12327)
at vue-socketio.min.js:14:9569
at Array.forEach (<anonymous>)
at Cn.mounted (vue-socketio.min.js:14:9495)
at Be (vue.min.js:6:11407)
at Qt (vue.min.js:6:25438)
at vue.min.js:6:68707
at Cn.$mount (vue.min.js:6:68726)
at Cn.$mount (vue.min.js:6:94030)
at Cn.t._init (vue.min.js:6:33111)
Vue-Socket.io: Broadcasting: #connect, Data:
empty stack
App.connect(None, (), {})
There are a few things here:
-
The "callback must be a function" error.
Which is being triggered here in vue-socketio. -
The callback in App prints 'None' for its value of 'self'
-
The "empty stack" warning from Brython when using callbacks.
I appreciate vue-socketio isn't your library, but I'm not sure where else to go for assistance.
I've tried poking around inside the vue.py, but I simply don't understand most of what it is attempting to do.