Skip to content

fix(web): create_app() boots without the security extra (v26.06.06)#32

Merged
ancongui merged 1 commit into
mainfrom
fix/web-create-app-optional-security-import
Jun 5, 2026
Merged

fix(web): create_app() boots without the security extra (v26.06.06)#32
ancongui merged 1 commit into
mainfrom
fix/web-create-app-optional-security-import

Conversation

@ancongui
Copy link
Copy Markdown
Contributor

@ancongui ancongui commented Jun 5, 2026

Summary

Both web adapters (pyfly.web.adapters.starlette and pyfly.web.adapters.fastapi) collected OAuth2 login routes during create_app() via an unconditional import:

from pyfly.security.oauth2.login import OAuth2LoginHandler

That module imports pyjwt at load time. So a pyfly[web]-only install (no pyfly[security]) — exactly what pyfly new --archetype web-api / fastapi-api generates — crashed at app-build time with:

ModuleNotFoundError: No module named 'jwt'

Fix

Make the import lazy and guarded (try/except ImportError, matching the repo's existing optional-dependency idiom in pyfly.observability). When the security extra is absent there can be no OAuth2LoginHandler bean anyway, so the route loop is simply skipped; when pyfly[security] is installed, OAuth2 login routes still mount.

Fixed in both adapters (Starlette app.py:_collect_context_routes, FastAPI app.py:_install_context_routes).

Tests

  • New tests/web/test_web_only_boot.py (both adapters) — simulates a pyfly[web]-only install and asserts create_app() boots and serves. Verified it fails without the fix (ModuleNotFoundError: import of pyfly.security.oauth2.login halted) and passes with it.
  • Existing security / oauth2 / idp suites still pass, confirming OAuth2 login routes still mount when security is present.

End-to-end verification

A true pyfly[web]-only install (pyjwt present: False) → pyfly new order-api --archetype web-api → boot → GET /health/200 {"status":"UP"}, POST/GET /todos/201/200, /docs200.

Gates

ruff ✓ · ruff format ✓ · mypy --strict (src/pyfly/web) ✓ · full suite 3617 passed, 1 skipped.

Bumps v26.06.05 → v26.06.06 (pyproject / __init__ / README), adds CHANGELOG entry, syncs uv.lock.

Both web adapters (starlette + fastapi) collected OAuth2 login routes during
create_app() via an unconditional `from pyfly.security.oauth2.login import
OAuth2LoginHandler`. That module imports pyjwt at load, so a pyfly[web]-only
install (what `pyfly new --archetype web-api|fastapi-api` generates) crashed at
app-build time with ModuleNotFoundError: No module named 'jwt'.

The import is now lazy + guarded (try/except ImportError): web-only services
boot, and OAuth2 login routes still mount when pyfly[security] is installed and
an OAuth2LoginHandler bean is registered. Adds tests/web/test_web_only_boot.py
(starlette + fastapi). Verified end-to-end: a true pyfly[web]-only scaffold now
boots and serves /health, /todos CRUD, and /docs.

Gates: ruff + ruff format + mypy --strict (src/pyfly/web) clean; full suite
3617 passed, 1 skipped.
@ancongui ancongui merged commit e91087d into main Jun 5, 2026
5 checks passed
@ancongui ancongui deleted the fix/web-create-app-optional-security-import branch June 5, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant