A simple and fast ASGI microframework for Python with WebSocket support.
Project description
AltAPI
A simple and fast ASGI microframework for Python with WebSocket support.
Changelog
v1.3.0
- Added rate limiting with
@rate_limitand@rate_limit_batchdecorators(right now, please dont use them, they are very unoptimized) - Added shared manager for multi-worker rate limiting support
- Added support for all HTTP methods: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS, TRACE, CONNECT
v1.2.0
- Added
workersparameter toapp.run()for multi-process support - Added
access_logparameter to enable/disable request logging - GC optimizations now apply to all workers automatically
Installation
pip install altapi
Requirements:
- Python >= 3.10
- uvicorn >= 0.30.0
- anyio >= 4.0.0
- jinja2 >= 3.0.0
- ujson
- 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 manager
- ✅ 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"})
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.
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
altapi-1.3.0.tar.gz
(128.5 kB
view details)
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 altapi-1.3.0.tar.gz.
File metadata
- Download URL: altapi-1.3.0.tar.gz
- Upload date:
- Size: 128.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
626c01da440217ab073c1b18a373b1bdc9140f3503f657247579750f0720a281
|
|
| MD5 |
173137bfc5ce57e5ede4c9d71d857edc
|
|
| BLAKE2b-256 |
bc30430a7f6329bb036d8d699d0cbaeb7bba16e47ef62a103b559580a10932a9
|
File details
Details for the file altapi-1.3.0-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: altapi-1.3.0-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 171.0 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f152fe22fe237cb0150f6b78cfbb599e5507a84b3ae1b931d261257b29090494
|
|
| MD5 |
b26b5b7c620c76b78a51e37236d46669
|
|
| BLAKE2b-256 |
75eeb5be2b2cc730f10bb9a5a7d145ba7c04e34a70a8fee83da41bcbe5faecf0
|