Skip to main content

apiquart

The minimalistic API framework for Quart — declarative request/response validation and automatic OpenAPI 3.1 docs, built on Pydantic v2.

apiquart brings APIFlask-style ergonomics to Quart's async-native world. It is a thin layer over vanilla Quart and Pydantic: an APIQuart app is a quart.Quart subclass, your schemas are plain Pydantic models, and removing every decorator still leaves a working route.

  • @app.input — parse and validate the request (json/query/form/files/ headers/cookies/path); the validated model instance is injected as an argument.
  • @app.output — serialize the return value (ORM object, dict, or model) through Pydantic.
  • @app.doc — attach OpenAPI operation metadata.
  • @app.auth_required — first-class auth via quart-httpauth.
  • OpenAPI 3.1 generated straight from your Pydantic models, with four interactive doc UIs behind a single /docs endpoint.

Installation

pip install apiquart

The distribution name is apiquart; the import name is apiquart. Optional extras: apiquart[auth] (quart-httpauth), apiquart[yaml] (YAML spec output).

Quickstart

from apiquart import APIQuart, BaseModel, abort

app = APIQuart(__name__, title="Pets API", version="1.0.0")


class PetIn(BaseModel):
    name: str
    category: str = "other"


class PetOut(PetIn):
    id: int


pets: dict[int, dict] = {}


@app.post("/pets")
@app.input(PetIn, arg_name="pet")
@app.output(PetOut, status_code=201)
async def create_pet(pet):                      # pet is a validated PetIn
    pet_id = len(pets) + 1
    pets[pet_id] = {"id": pet_id, **pet.model_dump()}
    return pets[pet_id]


@app.get("/pets/<int:pet_id>")
@app.output(PetOut)
async def get_pet(pet_id):
    if pet_id not in pets:
        abort(404, message="Pet not found")
    return pets[pet_id]

Run it with any ASGI server:

hypercorn module:app
  • OpenAPI spec: GET /openapi.json
  • Interactive docs: GET /docs (Swagger UI by default; try ?ui=redoc, ?ui=rapidoc, ?ui=elements)

Input locations

@app.input(Model, location=...) supports json (default), query, form, files, form_and_files, headers, cookies and path. The validated model is injected as f"{location}_data" unless you pass arg_name=. Multiple @app.input decorators stack for different locations. Invalid input yields a 422 with the standard error envelope.

Output

@app.output(Model, status_code=200) validates and serializes the handler's return value (model.model_validate(obj).model_dump(mode="json")). Handlers may return obj, (obj, status), or (obj, status, headers). Use EmptyModel with status_code=204 to document an empty response.

Errors

Every error is a single JSON envelope:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The request contains invalid data",
    "detail": {"json": [{"loc": ["name"], "msg": "Field required", "type": "missing"}]}
  }
}

Raise one with abort(404, message="Pet not found") or raise HTTPError(...). Quart's own HTTPExceptions are reshaped into the same envelope. Customize the shape with @app.error_processor.

Authentication

from quart_httpauth import HTTPTokenAuth
from apiquart import APIQuart

app = APIQuart(__name__)
auth = HTTPTokenAuth(scheme="Bearer")


@auth.verify_token
async def verify(token):
    return await User.from_token(token)


@app.get("/admin/stats")
@app.auth_required(auth, roles="admin")
async def stats():
    return {"user": auth.current_user()}

apiquart introspects the auth object and registers the matching OpenAPI security scheme (Basic → http/basic, Bearer → http/bearer, custom header → apiKey).

Pagination

from apiquart import BaseModel, PaginationMeta, pagination_builder


class PetsPage(BaseModel):
    data: list[PetOut]
    pagination: PaginationMeta


@app.get("/pets")
@app.input(PetQuery, location="query")
@app.output(PetsPage)
async def list_pets(query_data):
    items, total = await Pet.paginate(query_data.page, query_data.per_page)
    return {
        "data": items,
        "pagination": pagination_builder(query_data.page, query_data.per_page, total),
    }

Blueprints and class-based views

APIBlueprint carries the same decorators so blueprint routes contribute to the spec. Quart's MethodView is supported — decorate the HTTP methods directly.

See examples/ for runnable apps.

License

MIT.

Release files for apiquart 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for apiquart 0.0.1
File Size Uploaded
apiquart-0.0.1.tar.gz 161.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for apiquart 0.0.1
File Interpreter ABI Platform
apiquart-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 186.1 kB

Release files / apiquart-0.0.1.tar.gz

Download URL apiquart-0.0.1.tar.gz
Size 161.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0e0eb1926855f43414e6e34f6c76d08e62c1474572a0f04283b128c845e6b140
BLAKE2b-256 checksum
How to use checksums
9ff0bb701c3d7ae0aa5b679cda6fb52f900560361902bc4f57677e4f1842cd47
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / apiquart-0.0.1-py3-none-any.whl

Download URL apiquart-0.0.1-py3-none-any.whl
Size 24.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bdff2d39e7a0ed144a7a74c837a9f42af9c9ab2876df33f3c82df5633ab81703
BLAKE2b-256 checksum
How to use checksums
cd27b576b732829bc47f52047f915dbc23601508f506a400057e0c704d130e4f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page