Skip to main content

Automatic Pydantic validation and ReDoc documentation generation for Flask endpoints

Project description

flask-redantic

Automatic Pydantic validation and ReDoc API documentation for Flask.

flask-redantic is a Flask library that:

  • Validates request bodies and query parameters by reading your type annotations
  • Injects validated Pydantic model instances directly into your view functions
  • Auto-generates interactive ReDoc API documentation - no YAML, no manual schema config
  • Requires zero boilerplate - your annotations and docstrings are the source of truth

Installation

uv add flask-redantic

Quick Start

from flask import Flask, jsonify
from pydantic import BaseModel, Field
from flask_redantic import Redantic
from flask_redantic.raises import HTTP_404, HTTP_422

app = Flask(__name__)
api = Redantic(title="Quark's Bar API", version="v1.0")

class ItemIn(BaseModel):
    name: str = Field(..., min_length=1)
    category: str
    price_slips: int = Field(..., ge=0)

class ItemOut(BaseModel):
    id: int
    name: str
    category: str
    price_slips: int

class ErrorOut(BaseModel):
    message: str

@app.post("/inventory")
@api.validate(
    tags=["inventory"],
    raises=[HTTP_422()],
    success_status=201,
)
def create_item(body: ItemIn) -> ItemOut:
    """
    Acquire new stock for Quark's.

    The body is validated and injected automatically.
    """
    return jsonify({"id": 1, **body.model_dump()}), 201

@app.get("/inventory/<int:item_id>")
@api.validate(tags=["inventory"], raises=[HTTP_404(ErrorOut)])
def get_item(item_id: int) -> ItemOut:
    """Retrieve an item by ID."""
    item = db.get(item_id)
    if not item:
        return jsonify({"message": "Not found"}), 404
    return jsonify(item)

api.init_app(app)

Visit:

  • http://localhost:5000/docs → Interactive ReDoc documentation
  • http://localhost:5000/docs/openapi.json → Raw OpenAPI 3.0 JSON spec

How It Works

Everything is driven by standard Python type annotations:

Annotation Effect
body: MyModel JSON body validated → body is a MyModel instance
query: MyModel Query-string params validated → query is a MyModel instance
item_id: int (Flask path param) Passed through unchanged by Flask
-> MyModel Documents the success response schema
raises=[HTTP_404(ErrorOut)] Documents error response schemas

Body injection

@app.post("/inventory")
@api.validate(tags=["inventory"], success_status=201)
def create_item(body: ItemIn) -> ItemOut:
    # `body` is a fully validated ItemIn instance — ready to use
    return jsonify({"id": 1, **body.model_dump()}), 201

Body + path parameter

Flask path parameters are passed normally; flask-redantic injects body/query alongside them:

@app.put("/inventory/<int:item_id>")
@api.validate(tags=["inventory"], raises=[HTTP_404(ErrorOut)])
def update_item(item_id: int, body: ItemIn) -> ItemOut:
    # item_id comes from Flask routing
    # body is injected by redantic
    ...

Query parameters

Use a parameter named query annotated with a BaseModel:

class ItemFilter(BaseModel):
    category: str | None = None
    max_price: int | None = Field(None, ge=0)

@app.get("/inventory")
@api.validate(tags=["inventory"])
def list_items(query: ItemFilter) -> ItemOut:
    if query.category:
        ...

@api.validate Parameters

Parameter Type Description
raises list[RaisesSpec] Error response declarations (see below)
tags list[str] Group endpoints in the ReDoc sidebar
summary str | None One-line description. Auto-detected from first docstring line if omitted
deprecated bool Mark endpoint as deprecated in docs
success_status int Success HTTP status code (default: 200). Override to 201 for creation endpoints

Validation errors

When a request body or query fails validation, flask-redantic automatically returns:

HTTP 422 Unprocessable Entity

{
  "detail": [
    {
      "loc": ["name"],
      "msg": "String should have at least 1 character",
      "type": "string_too_short"
    }
  ]
}

raises — Declaring Error Responses

Import the pre-built HTTP error helpers from flask_redantic.raises:

from flask_redantic.raises import HTTP_400, HTTP_401, HTTP_403, HTTP_404, HTTP_409, HTTP_422, HTTP_500

@api.validate(raises=[
    HTTP_404(ErrorOut),   # 404 with ErrorOut schema
    HTTP_403(),           # 403 with no body
    HTTP_422,             # 422 with no body (no parentheses needed)
])
def my_endpoint(...): ...

Available helpers: HTTP_400, HTTP_401, HTTP_403, HTTP_404, HTTP_409, HTTP_422, HTTP_429, HTTP_500, HTTP_503

Note: A 422 Unprocessable Entity response is automatically added to the spec whenever a body or query model is present. You don't need to add it manually.


Application Factory Pattern

from flask_redantic import Redantic

api = Redantic(
    title="My API",
    version="v1.0",
    description="Supports **Markdown** in the overview section.",
    path="doc",   # /docs UI, /docs/openapi.json spec
)

from extensions import api
from flask import Flask

def create_app():
    app = Flask(__name__)
    # ... register routes ...
    api.init_app(app)   # call AFTER all routes are registered
    return app

Redantic Configuration

api = Redantic(
    app,               # optional Flask app; pass later via init_app()
    title="My API",    # shown in ReDoc header
    version="v2.0",    # shown in ReDoc version badge
    description="...", # Markdown shown in ReDoc overview
    path="doc",        # URL prefix; /docs UI, /docs/openapi.json spec
)

Running the Example

pip install -e .
python examples/app.py
# → http://localhost:5050/docs

Project Structure

flask-redantic/
├── src/flask_redantic/
│   ├── __init__.py    # Public API: Redantic
│   ├── core.py        # Redantic class + Flask Blueprint
│   ├── decorator.py   # @validate decorator + signature inspection
│   ├── spec.py        # OpenAPI 3.0 spec builder
│   ├── raises.py      # HTTP_xxx error-response helpers
│   └── templates.py   # ReDoc HTML template
└── examples/
    └── app.py         # Runnable Quark's Bar demo

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flask_redantic-0.2.0.tar.gz (60.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flask_redantic-0.2.0-py3-none-any.whl (12.3 kB view details)

Uploaded Python 3

File details

Details for the file flask_redantic-0.2.0.tar.gz.

File metadata

  • Download URL: flask_redantic-0.2.0.tar.gz
  • Upload date:
  • Size: 60.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for flask_redantic-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a9c761282ff9184a9038199796f68ac084be311c5b48cf3577f5d099a1ead456
MD5 3ae59240a633b76ee722d1e960002d59
BLAKE2b-256 320086d4e99f6758023c239e1c2b9339e8f01b1da9b11a9ad526d1eda23d21bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for flask_redantic-0.2.0.tar.gz:

Publisher: publish.yml on wagnercder/flask-redantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flask_redantic-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: flask_redantic-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 12.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for flask_redantic-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 56c760d9dcc14579a37220a0bf964e9ed80a3c9fedc70ec16abba4afdf6ae39a
MD5 9677bf43ad1a57feac498fbf14e3a86b
BLAKE2b-256 3482ba4212966760a938dadf1beb10ee2f5795416496a9d668cc78d767beab11

See more details on using hashes here.

Provenance

The following attestation bundles were made for flask_redantic-0.2.0-py3-none-any.whl:

Publisher: publish.yml on wagnercder/flask-redantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page