Typed-first Python web framework for blazingly fast, stable APIs.
Project description
BlazeAPI
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 devandblazeapi runcommands 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:
- Every handler must have a return type annotation
- Return type must be a
Responsesubclass orBaseModelsubclass (notdict,list, or primitives) - All parameters must have type annotations
- Non-path parameters must be
BaseModelsubclasses (notdict,list, or bare primitives) - Path parameters (matching
{name}in the route) may use primitive types likeintorstr
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 namedapporapplication, then falls back to anyBlazeAPIinstance. - 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
55d308848509ebb93eaba9decaa3271ebca3fc3284b57e80cfd66a1fe149bdc6
|
|
| MD5 |
ac897be6848770b2e92b5919c332468e
|
|
| BLAKE2b-256 |
92c7940035d1f325b76ceaa754829604257868a282a4ceb67b4059e8d4fc5b6d
|
Provenance
The following attestation bundles were made for blazeapi-0.0.3.tar.gz:
Publisher:
release.yml on ritwiktiwari/blazeapi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
blazeapi-0.0.3.tar.gz -
Subject digest:
55d308848509ebb93eaba9decaa3271ebca3fc3284b57e80cfd66a1fe149bdc6 - Sigstore transparency entry: 910343759
- Sigstore integration time:
-
Permalink:
ritwiktiwari/blazeapi@7c498dc9931df2b8dbc8eb5409c7270240e893a5 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/ritwiktiwari
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7c498dc9931df2b8dbc8eb5409c7270240e893a5 -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e633ae37353e702bc41ca647798b6eccd549d9fa53285ae9564a4649aa7edc8e
|
|
| MD5 |
121beb570aa35d56081dd01f0593be60
|
|
| BLAKE2b-256 |
74660b35eada6e413d198eb2f5f68e65a24bd4c4f2e7258233cc81ef3c78fa98
|
Provenance
The following attestation bundles were made for blazeapi-0.0.3-py3-none-any.whl:
Publisher:
release.yml on ritwiktiwari/blazeapi
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
blazeapi-0.0.3-py3-none-any.whl -
Subject digest:
e633ae37353e702bc41ca647798b6eccd549d9fa53285ae9564a4649aa7edc8e - Sigstore transparency entry: 910343761
- Sigstore integration time:
-
Permalink:
ritwiktiwari/blazeapi@7c498dc9931df2b8dbc8eb5409c7270240e893a5 -
Branch / Tag:
refs/tags/v0.0.3 - Owner: https://github.com/ritwiktiwari
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7c498dc9931df2b8dbc8eb5409c7270240e893a5 -
Trigger Event:
push
-
Statement type: