Environment
- Package:
lark-oapi 1.6.7 (Python)
- Python: 3.9+
- Affected path:
lark_oapi/ws/client.py
Summary
lark_oapi/ws/client.py captures the event loop at module import time via a module-level global. If the module is first imported while an event loop is already running (e.g. inside asyncio.run()), the subsequent loop.run_until_complete(...) raises RuntimeError: This event loop is already running, and the WebSocket long-connection fails immediately.
Root Cause
client.py lines 30-34 run at import time:
try:
loop = asyncio.get_event_loop()
except RuntimeError:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
Under Python 3.9, asyncio.get_event_loop() returns the currently running loop when called from within a coroutine / asyncio.run() context, so the module-level loop captures an already-running loop.
client.py then uses this global in start():
# client.py:163, 169, 171, 176
loop.run_until_complete(self._connect())
...
loop.run_until_complete(_select())
Calling run_until_complete on an already-running loop raises RuntimeError: This event loop is already running.
Reproduction
import asyncio
async def main():
from lark_oapi.ws.client import Client # first import here captures the running loop
Client(...).start() # RuntimeError: This event loop is already running
asyncio.run(main())
Real-world Trigger
Host applications that lazily import lark_oapi.channel (which transitively imports lark_oapi.ws.client) from within their asyncio main loop hit this unconditionally on first startup.
Suggested Fix
Remove the module-level loop global; create a dedicated event loop per Client instance inside the worker thread in start(), isolating the WS client from the caller's event loop.
Environment
lark-oapi1.6.7 (Python)lark_oapi/ws/client.pySummary
lark_oapi/ws/client.pycaptures the event loop at module import time via a module-level global. If the module is first imported while an event loop is already running (e.g. insideasyncio.run()), the subsequentloop.run_until_complete(...)raisesRuntimeError: This event loop is already running, and the WebSocket long-connection fails immediately.Root Cause
client.pylines 30-34 run at import time:Under Python 3.9,
asyncio.get_event_loop()returns the currently running loop when called from within a coroutine /asyncio.run()context, so the module-levelloopcaptures an already-running loop.client.pythen uses this global instart():Calling
run_until_completeon an already-running loop raisesRuntimeError: This event loop is already running.Reproduction
Real-world Trigger
Host applications that lazily import
lark_oapi.channel(which transitively importslark_oapi.ws.client) from within their asyncio main loop hit this unconditionally on first startup.Suggested Fix
Remove the module-level
loopglobal; create a dedicated event loop perClientinstance inside the worker thread instart(), isolating the WS client from the caller's event loop.