Pathrule

Flask Production Applications

Pathrule2 Rules • 2 Memories

Flask's small surface makes it easy to start and equally easy to hide global state, bind extensions too early, perform work outside an active context, or ship the development server as if it were an application server. This pattern places factory and extension decisions in the application package, constrains request-context usage in service code, and records how configuration and error translation cross blueprint boundaries. It differs from Django's batteries-included conventions and FastAPI's typed asynchronous surface by focusing on Flask factories, contexts, WSGI deployment, and deliberately assembled extensions.

Suggested path map

Pathrule places each piece on the matching path, so your assistant only sees it where it belongs. This is the scoping you get on import; you can adjust it in your workspace.

/ workspace root
app/
Construct Flask through an application factory
Blueprints partition transport ownership, not domain ownership
The development server is a local feedback tool
services/
Do not let request context leak into service code

Rules

2
Construct Flask through an application factory/apphighstrictCreate configuration, extensions, blueprints, and handlers in a factory so tests and workers can build isolated app instances.
1A module-global application freezes configuration at import time and turns imports into initialization order. A factory makes the instance boundary explicit and lets each process or test create the application it actually needs.
2 
3- Create the Flask object inside `create_app`, load configuration before binding extensions, then register blueprints and error handlers in a stable order.
4- Instantiate extension objects without an app at module scope and bind them with `init_app`; this keeps models importable without constructing the server.
5- Pass environment-specific configuration into the factory instead of mutating global config after modules have already read it.
6- Keep CLI commands and background-worker bootstraps dependent on the factory so they use the same extension setup without importing a running web process.
7 
8See /tests for the adjacent decision or procedure that completes this constraint.
Do not let request context leak into service code/app/serviceshighstrictPass identity and input explicitly into services; reserve request, session, and g proxies for the HTTP adapter layer.
1Flask's context-local proxies look like globals but only resolve while the relevant context is active. A service that reads them directly becomes unusable in a job, CLI command, test, or deferred callback.
2 
3- Resolve the authenticated actor, locale, and request data in the route or decorator, then pass typed values to the service function.
4- Do not capture `request`, `session`, or `g` in a closure that outlives the response. Copy only the specific immutable value the later task needs.
5- Open database sessions and transactions around service work with explicit cleanup; do not rely on a request teardown hook for code that also runs outside HTTP.
6- Use an explicit application context only for framework integration during CLI or worker boot, not as a blanket fix for hidden request dependencies.
7 
8See /app for the adjacent decision or procedure that completes this constraint.

Memories

2
Blueprints partition transport ownership, not domain ownership/appUse blueprints for route, template, and handler composition while keeping reusable business behavior in services.
1A blueprint is a registration unit for Flask surfaces. Treating it as a complete business module often causes models and services to import the blueprint object, creating circular dependencies and preventing the same behavior from being called elsewhere.
2 
3- Keep route functions, request schemas, response formatting, and blueprint-local error mapping inside the blueprint package.
4- Move business transitions and repository calls to services that do not import Flask request or response objects.
5- Register shared error translation at the application level and blueprint-specific errors only where their representation genuinely differs.
6- Use URL prefixes and blueprint names as public routing decisions; changing them should not move or rename the domain code they adapt.
7 
8See /app/services for the rule or workflow that puts this decision into practice.
The development server is a local feedback tool/appProduction serves the factory through a supervised WSGI server with bounded workers, timeouts, and trusted proxy configuration.
1Flask's built-in server optimizes for reload and debugging, not process supervision, worker management, slow-client defense, or graceful restarts. Production topology belongs outside the application while remaining documented beside it.
2 
3- Serve the factory through a production WSGI server and size workers from measured CPU, memory, blocking I/O, and database-pool capacity rather than a copied formula.
4- Disable the interactive debugger and never expose a debug PIN path to a network, even behind authentication.
5- If a reverse proxy supplies forwarding headers, apply proxy middleware with the exact trusted hop counts instead of accepting arbitrary public headers.
6- Keep health checks cheap and independent from a full dependency transaction; readiness can test critical connectivity without turning every probe into load.
7 
8See /app for the rule or workflow that puts this decision into practice.

Why this pattern

AI agents often create a module-global Flask app, import it from every service, access request globals in background work, or run the development server in production.

Built for Python teams building Flask APIs and web applications with blueprints and database extensions.

Keeps your assistant from:

  • Creating circular imports around a global application object
  • Using request or session proxies outside their active context
  • Binding extensions before test configuration is available
  • Deploying the debug server behind a public endpoint
License
Apache-2.0
Version
1.0.0
Updated
2026-08-25
View source