Agent RulesAgent Rules
Builder
Options
Browse all rules by language and framework
Templates
Pre-built rule sets ready to use
Popular Rules
Top community-ranked rules leaderboard
GuidesAnalyzePricingContact
Builder
OptionsTemplatesPopular Rules
GuidesAnalyzePricingContact

Product

  • Builder
  • Templates
  • Browse Rules
  • My Library

Learn

  • What are AI Agent Rules?
  • Guides
  • FAQ
  • About

Resources

  • Terms
  • Privacy Policy
  • Pricing
  • Contact
  • DMCA Policy

Support

Help keep this project free.

Agent RulesAgent Rules Builder
© 2026 Aurora Algorithm Inc.
Back to Templates

Python + Flask

Rules for Flask applications covering blueprints, extensions, and production patterns.

pythonPython/flaskFlask
python
flask
rest-api
lightweight
Customize in Builder

Details

Language
pythonPython
Framework
flaskFlask

Rules Content

AGENTS.md
Edit in Builder

Python + Flask Agent Rules

Project Context

You are building a Flask application using the application factory pattern with Blueprint-based modular routing, SQLAlchemy for ORM, Flask-Migrate for schema management, and Marshmallow or Pydantic for request validation.

Code Style & Structure

- Follow PEP 8. Format with `ruff format`. Lint with `ruff check`. Configure both in `pyproject.toml`.
- Add type hints to all function signatures and return types. Use `from __future__ import annotations`.
- Keep route handlers under 15 lines. Delegate business logic to service functions.
- Use `pathlib.Path` for file system operations.

Project Structure

```
project/
app/
__init__.py # create_app() factory
extensions.py # db, migrate, mail, limiter — init_app() pattern
models/ # SQLAlchemy models, one file per aggregate
api/
auth/
routes.py # Blueprint(prefix='/auth')
services.py # Business logic
schemas.py # Marshmallow/Pydantic schemas
users/
<domain>/
errors.py # Error handlers and custom exceptions
middleware.py # @app.before_request hooks
migrations/
tests/
conftest.py
test_auth/
test_users/
config.py # BaseConfig, DevelopmentConfig, ProductionConfig, TestingConfig
```

Application Factory

- Always use the factory pattern: `def create_app(config_name='development') -> Flask`.
- Register blueprints, error handlers, shell context, and CLI commands inside `create_app`.
- Initialize extensions in `extensions.py` and bind them with `ext.init_app(app)` inside the factory.
- Load configuration with `app.config.from_object(config)`. Never hardcode secrets.
- Use `python-dotenv` to load `.env` files. Use `pydantic-settings` for typed, validated config.

Routes & Blueprints

- One Blueprint per domain area with its own URL prefix: `Blueprint('users', prefix='/api/v1/users')`.
- Use `@bp.get`, `@bp.post`, `@bp.put`, `@bp.delete` (Flask 2.2+) for explicit HTTP method declarations.
- Return `jsonify(data)` with explicit `status` argument: `return jsonify(data), 201`.
- Return a consistent envelope: `{ "data": ..., "meta": ... }` for success; `{ "error": { "code", "message", "details" } }` for failure.
- Use `@bp.before_request` for blueprint-scoped pre-request work (auth verification, request logging).

SQLAlchemy & Migrations

- Use Flask-SQLAlchemy 3.x with explicit `db.Mapped` column annotations (SQLAlchemy 2.0 style).
- Use Flask-Migrate (Alembic) for all schema changes. Review generated migration scripts before applying.
- Write explicit `downgrade()` functions in every migration. Blind migrations break rollbacks.
- Use `uuid` primary keys on public-facing models to prevent sequential ID enumeration.
- Add `index=True` on all columns used in filter conditions. Add multi-column indexes via `__table_args__`.
- Prefer `db.session.execute(select(User).where(...))` over legacy `User.query.filter(...)`.
- Use `joinedload` and `subqueryload` to avoid N+1 queries. Profile with `sqlalchemy-utils` query count tracking.
- Wrap multi-step mutations in `try: db.session.commit() except: db.session.rollback(); raise`.

Request Validation

- Validate all incoming data with Marshmallow schemas or Pydantic v2 models.
- Define separate schema classes: `CreateUserSchema`, `UpdateUserSchema`, `UserResponseSchema`.
- Return `422` with field-level error details on validation failure.
- Use `@validates` in Marshmallow or `@field_validator` in Pydantic for cross-field rules.
- Strip unknown fields: `class Meta: unknown = RAISE` (Marshmallow) or `model_config = ConfigDict(extra='forbid')` (Pydantic).

Authentication

- Use Flask-JWT-Extended for stateless API auth with short access tokens (15 minutes) and rotating refresh tokens.
- Hash passwords with `werkzeug.security.generate_password_hash` using the `scrypt` or `pbkdf2:sha256` method.
- Use `@jwt_required()` decorator. Access the current user with `current_user` after injecting a `user_lookup_callback`.
- Store sensitive cookie flags: `JWT_COOKIE_SECURE = True`, `JWT_COOKIE_SAMESITE = 'Strict'`.

Error Handling

- Register error handlers for `400`, `401`, `403`, `404`, `422`, `429`, `500` with `@app.errorhandler`.
- Define domain exceptions: `class ResourceNotFoundError(Exception): status_code = 404`.
- Register custom exception handlers: `@app.errorhandler(ResourceNotFoundError)`.
- Log `500` errors with full stack traces using `app.logger.exception`. Use `python-json-logger` in production.
- Never return Python exception messages or stack traces in HTTP responses.

Testing

- Use `pytest` with Flask's `test_client()`. Create a test app via `create_app('testing')` in `conftest.py`.
- Reset the database between tests: truncate all tables in a `session`-scoped fixture.
- Create test data with `factory_boy` factories. Use `SQLAlchemyModelFactory` with `Session` scoping.
- Test each blueprint: valid request → correct response, validation error → 422, unauthenticated → 401.
- Mock external calls with `unittest.mock.patch`. Never make real HTTP calls in unit or integration tests.

Performance & Deployment

- Use Gunicorn with `--workers $(nproc)` in production. Use `gevent` workers for I/O-heavy apps.
- Configure `SQLALCHEMY_POOL_SIZE`, `SQLALCHEMY_MAX_OVERFLOW`, and `SQLALCHEMY_POOL_RECYCLE`.
- Apply `Flask-Caching` with Redis for expensive view-level and function-level caching.
- Apply `Flask-Limiter` with Redis for distributed rate limiting. Use stricter limits on auth endpoints.
- Serve static files through Nginx or a CDN. Never let Flask serve statics in production.

Related Templates

python

Python + FastAPI

High-performance Python API development with FastAPI, Pydantic, and async patterns.

python

Python + Django

Django web development with class-based views, ORM best practices, and DRF.

python

Python + ML/Data Science

Machine learning and data science with Python, PyTorch, and scikit-learn.