Each call into opencloud_token_store is wrapped in its own asyncio.run() (app/app_config.py, main.py's token popover), so every call gets a fresh event loop. The asyncpg connection pool is bound to the loop it was created in, so the next asyncio.run() could try to reuse a connection from an already-closed loop and fail — unrelated to actual DB availability, but the broad except Exception in resolve_opencloud_access_token() silently swallowed it and fell through to "token not found", masking the real cause. - add_token/get_token/remove_token/list_usernames now call engine.dispose() in a finally block so each asyncio.run() starts with a clean pool. - resolve_opencloud_access_token() now surfaces the real exception via st.error() before falling back to the .env token (kept only for local dev without a DB). - Added tests/unit/test_opencloud_token_store.py covering that dispose() is called after every store operation, including when commit() raises.
19 lines
314 B
Plaintext
19 lines
314 B
Plaintext
streamlit==1.41.1
|
|
raisa-streamlit-oauth==1.0.3
|
|
python-dotenv==1.1.1
|
|
ruff==0.12.7
|
|
black==24.4.2
|
|
isort==5.13.2
|
|
pre-commit==3.7.1
|
|
openpyxl
|
|
xlsxwriter==3.2.0
|
|
pytest
|
|
pytest-asyncio
|
|
requests==2.32.4
|
|
pydantic-settings==2.10.1
|
|
sqlalchemy>=2.0.32,<2.1
|
|
asyncpg==0.30.0
|
|
aiosqlite==0.20.0
|
|
alembic==1.16.1
|
|
cryptography==43.0.3
|