Skip to main content

AltAPI

A simple and fast ASGI microframework for Python with WebSocket support.

PyPI Python License Documentation PyPI Downloads

Changelog

v2.2.0

  • Added request validation via PyDantic models.()

v2.1.0

  • Added CORSMiddleware (altapi.middleware.cors.CORSMiddleware) by @VxidDev in #7
  • Remaked OpenAPI instegration, by generating docs from Pydantic models.(wirhout data validation for now)

v2.0.0

  • Added OpenAPI and SwaggerUI integration.
  • Added CLI
  • Internal optimizations
  • Migrated from ujson to orjson
  • Full test coverage

Installation

pip install altapi

Requirements:

  • Python >= 3.10
  • uvicorn >= 0.30.0
  • anyio >= 4.0.0
  • jinja2 >= 3.0.0
  • orjson
  • Cython >= 3.0.0

Quick Start

Minimal Example

from altapi import AltAPI
from altapi.http import JSONResponse

app = AltAPI()


@app.get("/")
async def home(request):
    return JSONResponse({"message": "Hello, World!"})


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)

Run:

python app.py

Or via uvicorn:

uvicorn app:app --reload

Features

  • ✅ ASGI compliant
  • ✅ JSON, HTML, and text responses
  • ✅ Typed path parameters ({id:int}, {name:str}, {value:float}, {path:path})
  • ✅ Sync and async handlers
  • ✅ Full WebSocket support
  • ✅ Built-in server (app.run()) with multi-worker support
  • ✅ Jinja2 templates
  • ✅ Response caching with per-worker InMemoryCache
  • ✅ Rate limiting with Shared Memory optimization
  • ✅ Dependency Injection with automatic cleanup
  • ✅ Request State for middleware-to-handler data passing
  • ✅ Static file mounting
  • ✅ Optimized Cython router
  • ✅ GC optimizations for better performance
  • ✅ All HTTP methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE, CONNECT

Usage Examples

Path Parameters

from altapi.http import JSONResponse


@app.get("/users/{id:int}")
async def get_user(request):
    user_id = request.path_params["id"]  # automatically int
    return JSONResponse({"id": user_id, "name": f"User {user_id}"})


@app.get("/items/{name:str}")
async def get_item(request):
    name = request.path_params["name"]  # str
    return JSONResponse({"name": name})


@app.get("/files/{path:path}")
async def get_file(request):
    file_path = request.path_params["path"]  # captures full path with slashes
    return JSONResponse({"path": file_path})

Handling POST Requests

@app.post("/api/echo")
async def echo(request):
    data = await request.json()
    return JSONResponse({"echo": data})

WebSocket

from altapi.websocket import WebSocket


@app.websocket("/ws/echo")
async def websocket_echo(ws: WebSocket):
    await ws.accept()
    while True:
        text = await ws.receive_text()
        await ws.send_text(f"Echo: {text}")

Caching

from altapi.caching import cache

app = AltAPI()


@app.get("/api/data")
@cache(expires=3600)  # cache for 1 hour
async def get_data(request):
    return JSONResponse({"data": "cached"})

Rate Limiting

from altapi.ratelimit import rate_limit

app = AltAPI()


@app.get("/api/data")
@rate_limit(limit=10, period=60)  # 10 requests per minute
async def get_data(request):
    return JSONResponse({"data": "value"})


# Multiple limits on same endpoint
from altapi.ratelimit import rate_limit_batch


@app.get("/api/strict")
@rate_limit_batch([
    (10, 60),      # 10 per minute
    (100, 3600),   # 100 per hour
    (1000, 86400)  # 1000 per day
])
async def strict_endpoint(request):
    return JSONResponse({"data": "rate limited"})

Dependency Injection

from altapi import AltAPI
from altapi.http import JSONResponse
from altapi.depends import Depends
import sqlite3


def get_db():
    """Generator-based dependency with automatic cleanup."""
    conn = sqlite3.connect("app.db")
    try:
        yield conn
    finally:
        conn.close()


def get_user_repo(db=Depends(get_db)):
    """Nested dependency."""
    return UserRepository(db)


@app.get("/users")
async def list_users(repo=Depends(get_user_repo)):
    users = repo.get_all()
    return JSONResponse({"users": users})

See full example: examples/database_example.py

Jinja2 Templates

from altapi.templating import Jinja2Templates

app = AltAPI(templates_directory="templates")
templates = Jinja2Templates(directory="templates")


@app.get("/")
async def home(request):
    return templates.TemplateResponse(
        "index.html",
        {"request": request, "title": "Home Page"}
    )

Static Files

# Automatically serves files at /static
app = AltAPI(static_directory="static")

Multi-Worker Server

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, workers=4, access_log=True)

Response Types

from altapi.http import (
    JSONResponse,      # JSON response
    HTMLResponse,      # HTML response
    PlainTextResponse, # Plain text response
    StreamingResponse, # Streaming response
    FileResponse,      # File download with range support
    RedirectResponse,  # Redirect
)

Documentation

Full documentation is available in DOCS.md.

License

AGPLv3, see LICENSE.txt for details.

Metadata

Release files for AltAPI 2.2.0

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

Source distribution (sdist)

Source distribution for AltAPI 2.2.0
File Size Uploaded Provenance Actions
altapi-2.2.0.tar.gz 542.9 kB With provenance Details for altapi-2.2.0.tar.gz

Release files / altapi-2.2.0.tar.gz

Download URL altapi-2.2.0.tar.gz
Size 542.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f0828e9d177ce92f10ea50809768624fb2f3bf08f0ba95e091d74a7d585dbe1a
BLAKE2b-256 checksum
How to use checksums
1d8c6f29b4dafe6ecea80c7988b1f1a8875a68fbbf36bd87fb24d63fd62c5ee5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 19, 2026.

Transparency log

Security for AltAPI 2.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 1 file in this release has been uploaded with provenance metadata.

Attestation for altapi-2.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Apr 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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