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 — annotation-driven.

redantic is a lightweight 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 redantic import Redantic
from 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; 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, 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 redantic.raises:

from 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 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/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.1.0.tar.gz (65.3 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.1.0-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: flask_redantic-0.1.0.tar.gz
  • Upload date:
  • Size: 65.3 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.1.0.tar.gz
Algorithm Hash digest
SHA256 48bcded68a1c44a9ca63a596809b8f688a186b1db92c51fe45df3e64b358cdea
MD5 62332be50a3c16cd3905cb3fd5e8e7ac
BLAKE2b-256 2067eff7523581247bac6e1f6deb75eda39b012a1fed3ec5eafae35ced3c6eb1

See more details on using hashes here.

Provenance

The following attestation bundles were made for flask_redantic-0.1.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.1.0-py3-none-any.whl.

File metadata

  • Download URL: flask_redantic-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.2 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 acf84d295d5546f14de40cb2bbfb61fb9d6ae8f84596268d2a823d1e068216ac
MD5 cc869c58bb7ba05df1816b8c7c59f900
BLAKE2b-256 84bdd110dfc5ba897fbf8d14225c45194e66d5b57b2f58700eb735c34387525c

See more details on using hashes here.

Provenance

The following attestation bundles were made for flask_redantic-0.1.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