Skip to content

[core] Build the default application lazily#1144

Merged
frankrousseau merged 1 commit into
cgwire:mainfrom
frankrousseau:lazy-app
Jul 7, 2026
Merged

[core] Build the default application lazily#1144
frankrousseau merged 1 commit into
cgwire:mainfrom
frankrousseau:lazy-app

Conversation

@frankrousseau

Copy link
Copy Markdown
Contributor

Problem

  • Importing zou.app or any submodule built the whole application as a side effect: CLI commands, RQ worker settings and remote runners paid the full boot (Redis config sync, 592 routes, plugins) even when they only needed helpers or config
  • create_app() existed but nothing could skip the import-time build, and the test suite received an app it never explicitly constructed

Solution

  • Build the module-level app lazily through a PEP 562 getattr on first access: from zou.app import app and the gunicorn zou.app:app entry point keep working unchanged, while importing zou.app becomes side-effect free
  • Stop importing app at module scope in services and utils (constants read from the config module, runtime access through a local import or current_app), so a service imported first can no longer trigger the build mid-import
  • Make entry points (debug server, event stream, test conftest) call create_app() explicitly, and add a fresh-interpreter test asserting imports stay build-free

Importing zou.app (or any submodule) no longer wires the whole API:
the module-level app is built on first access through a PEP 562
__getattr__, so 'from zou.app import app' and the gunicorn zou.app:app
entry point keep working unchanged. Services and utils stop importing
the app at module scope (config constants come from the config module,
runtime access goes through a local import or current_app), which is
what makes the lazy build safe against partial-import cycles. Entry
points (debug server, event stream, test suite) now call create_app()
explicitly. CLI commands and RQ job settings that only need helpers or
config no longer pay the full boot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@frankrousseau frankrousseau merged commit 26d62e6 into cgwire:main Jul 7, 2026
14 checks passed
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