Skip to main content

Typed-first Python web framework for blazingly fast, stable APIs.

Project description

BlazeAPI

CI PyPI version codecov Python 3.12+ uv Ruff ty License: Apache-2.0

BlazeAPI — Typed-first Python web framework for blazingly fast, stable APIs. Built on Granian and Pydantic.

Alpha -- BlazeAPI is under active development. APIs may change between releases. Not recommended for production use yet.

Quick Start

uv add blazeapi
from blazeapi import BlazeAPI, Request, JSONResponse

app = BlazeAPI()

@app.get("/")
async def index(request: Request) -> JSONResponse:
    return JSONResponse({"message": "hello, world"})

@app.get("/users/{user_id:int}")
async def get_user(request: Request, user_id: int) -> JSONResponse:
    return JSONResponse({"id": user_id})

Features

  • Typed path parameters -- {id:int}, {slug:str}, {amount:float}, {uid:uuid}, {filepath:path}
  • Pydantic serialization -- return Pydantic models directly from JSONResponse
  • Sync and async handlers -- sync handlers run in a thread executor automatically
  • Strict mode -- comprehensive handler signature validation at registration time
  • Middleware -- standard ASGI middleware wrapping
  • CLI -- blazeapi dev and blazeapi run commands powered by Granian

Handlers

Handlers receive a Request object and any matched path parameters as keyword arguments:

@app.post("/items")
async def create_item(request: Request) -> JSONResponse:
    data = await request.json()
    return JSONResponse(data, status_code=201)

Sync handlers work too -- they're offloaded to a thread pool so they don't block the event loop:

@app.get("/sync")
def health(request: Request) -> JSONResponse:
    return JSONResponse({"status": "ok"})

Return dicts or lists directly and they'll be serialized as JSON:

@app.get("/simple")
async def simple(request: Request) -> dict:
    return {"works": True}

Strict Mode

Catch handler signature mistakes at import time instead of at request time:

from pydantic import BaseModel

app = BlazeAPI(strict=True)

class Item(BaseModel):
    name: str
    price: float

# Return type must be Response/JSONResponse or a BaseModel subclass
@app.get("/x")
def bad(request: Request) -> dict:  # TypeError
    return {}

# Non-path parameters must be BaseModel subclasses
@app.post("/items")
async def create(request: Request, item: Item) -> JSONResponse:  # OK
    return JSONResponse(item)

# Path parameters just need a type annotation
@app.get("/users/{user_id:int}")
async def get_user(request: Request, user_id: int) -> JSONResponse:  # OK
    return JSONResponse({"id": user_id})

Strict mode validates at route registration time:

  1. Every handler must have a return type annotation
  2. Return type must be a Response subclass or BaseModel subclass (not dict, list, or primitives)
  3. All parameters must have type annotations
  4. Non-path parameters must be BaseModel subclasses (not dict, list, or bare primitives)
  5. Path parameters (matching {name} in the route) may use primitive types like int or str

Running the App

BlazeAPI provides a CLI with two commands: dev for development and run for production.

Development

blazeapi dev main.py

This starts the server on http://127.0.0.1:8000 with auto-reload, debug logging, and access logs enabled.

# Custom host and port
blazeapi dev main.py --host 0.0.0.0 --port 3000

# Disable auto-reload
blazeapi dev main.py --no-reload

blazeapi dev options

Option Default Description
PATH main.py Python file or module:var target
--host 127.0.0.1 Bind address
--port 8000 Bind port
--reload / --no-reload --reload Auto-reload on code changes

Dev mode automatically sets debug-level logging and enables access logs.

Production

blazeapi run main.py --host 0.0.0.0 --port 8000 --workers 4

Or use Granian directly for full control over threading, TLS, and other options:

granian --interface asgi --host 0.0.0.0 --port 8000 --workers 4 app:app

blazeapi run options

Option Default Description
PATH main.py Python file or module:var target
--host 127.0.0.1 Bind address
--port 8000 Bind port
--workers 1 Number of worker processes

Target resolution

The PATH argument accepts two forms:

  • File path -- main.py, app.py, etc. BlazeAPI auto-discovers the app instance by looking for variables named app or application, then falls back to any BlazeAPI instance.
  • Module:var -- myapp:app, server:application, etc. Used directly.

Middleware

Standard ASGI middleware pattern -- a function that takes an app and returns an app:

def add_cors(inner_app):
    async def middleware(scope, receive, send):
        async def custom_send(message):
            if message["type"] == "http.response.start":
                headers = list(message.get("headers", []))
                headers.append((b"access-control-allow-origin", b"*"))
                message = {**message, "headers": headers}
            await send(message)
        await inner_app(scope, receive, custom_send)
    return middleware

app.add_middleware(add_cors)

Contributing

Prerequisites

  • Python 3.12+
  • uv for package management

Setup

git clone https://github.com/ritwiktiwari/blazeapi.git
cd blazeapi
make install

Running Tests

make test

# With coverage
make test-cov

# Across all Python versions
make test-matrix

Code Quality

# Run all checks (lint, format, type-check)
make verify

# Auto-fix lint and format issues
make fix

Documentation

make docs-serve

License

This project is licensed under the Apache-2.0 License - see the LICENSE file for details.

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

blazeapi-0.0.3.tar.gz (15.9 kB view details)

Uploaded Source

Built Distribution

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

blazeapi-0.0.3-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file blazeapi-0.0.3.tar.gz.

File metadata

  • Download URL: blazeapi-0.0.3.tar.gz
  • Upload date:
  • Size: 15.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for blazeapi-0.0.3.tar.gz
Algorithm Hash digest
SHA256 55d308848509ebb93eaba9decaa3271ebca3fc3284b57e80cfd66a1fe149bdc6
MD5 ac897be6848770b2e92b5919c332468e
BLAKE2b-256 92c7940035d1f325b76ceaa754829604257868a282a4ceb67b4059e8d4fc5b6d

See more details on using hashes here.

Provenance

The following attestation bundles were made for blazeapi-0.0.3.tar.gz:

Publisher: release.yml on ritwiktiwari/blazeapi

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

File details

Details for the file blazeapi-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: blazeapi-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 18.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for blazeapi-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 e633ae37353e702bc41ca647798b6eccd549d9fa53285ae9564a4649aa7edc8e
MD5 121beb570aa35d56081dd01f0593be60
BLAKE2b-256 74660b35eada6e413d198eb2f5f68e65a24bd4c4f2e7258233cc81ef3c78fa98

See more details on using hashes here.

Provenance

The following attestation bundles were made for blazeapi-0.0.3-py3-none-any.whl:

Publisher: release.yml on ritwiktiwari/blazeapi

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