2.9 KiB
2.9 KiB
AGENTS.md
Compact operational guide for OpenCode sessions. See CLAUDE.md for the prose
overview; this file captures what an agent would otherwise get wrong.
Commands
# First-time test env (creates venv/, installs requirements.txt + requirements-test.txt)
./setup_test_env.sh
# Full suite with coverage (activates venv, erases old coverage, builds htmlcov/)
./run_tests.sh
# Manual, from an active venv
python -m pytest tests/ --cov=. --cov-config=.coveragerc -v
# Single test
python -m pytest tests/test_main.py::test_health_check -v
# Dev server (must run from repo root — see Gotchas)
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
There is no lint, typecheck, formatter, or CI config in this repo. Do not
claim to run ruff, mypy, flake8, or black — none are installed or
configured. The only verification step is the pytest suite above.
Gotchas
- Run from repo root.
read_root()andfavicon()opentemplates/index.html/templates/favicon.icovia relative paths (main.py:329,main.py:371). Invoking uvicorn from another cwd 404s the frontend. @lru_cacheon OIDC helpers.get_well_known_config,get_jwks,get_userinfo_endpoint,get_token_endpointare alllru_cache(maxsize=1)(main.py:68-129). When a test patchesrequestswith a different response, callfunc.cache_clear()first or you get the previous mock's cached value. Existing tests do this; new tests must too.- Python 3.14, not 3.7.
.python-versionand the Dockerfile (python:3.14-alpine) target 3.14. The README's "3.7+" claim is stale. .envrcis gitignored and ships real credentials. It exports a liveCLIENT_ID/CLIENT_SECRETfor direnv. Never commit it, never paste its values into code or commits.CLIENT_IDhas no default.main.py:28reads it from env with no fallback; the app and several tests need it set.OIDC_ISSUERdefaults tohttps://login.infomaniak.com;CLIENT_SECRETdefaults to""(breaks/refresh-tokenwith "Client secret not configured").
Architecture essentials
- Single-file backend
main.py(FastAPI) + single-file frontendtemplates/index.html. No package layout, nopyproject.toml, nosetup.cfg. AUTHORIZED_USERS(main.py:33) is a hardcoded{email: secret_phrase}dict — the "protected resource". Not a database.- Token validation:
verify_token(id_token, expected_nonce=None)does JWKS signature verification + audience/issuer checks. Theexpected_nonceparam binds the id_token to the login flow (anti-replay);/validate-tokenforwards the nonce from the request body (main.py:278). Tests intest_token_validation.pyandtest_main.pycover the nonce paths — keep them green when touching auth. - Tests use
fastapi.testclient.TestClient(sync, backed byhttpx) andunittest.mock.patchagainstmain.*. Fixtures live intests/conftest.py. - Coverage config (
.coveragerc) omitsvenv/,tests/,.venv/.