API Development
First draft!
Please treat this as a very early draft, and be careful with anything that this chapter says! We welcome your pull requests to help refine the material so it actually becomes useful.
Air makes it easy to create powerful REST APIs alongside your HTML pages.
JSON Responses
Unlike FastAPI, Air does not automatically handles JSON responses when you return Python dictionaries. Instead, we use FastAPI's JSONResponse class to return JSON.
from fastapi.responses import JSONResponse
@app.get("/api/status")
def get_status():
return JSONResponse(
content={"status": "ok", "timestamp": datetime.now().isoformat()},
headers={"X-API-Version": "1.0"}
)
Request Bodies
Handle JSON request bodies:
from pydantic import BaseModel
class UserCreate(BaseModel):
name: str
email: str
age: int
@app.post("/api/users")
def create_user(user: UserCreate):
# user is automatically validated against UserCreate schema
return JSONResponse({
"id": 123, # In real app, this would be from database
"name": user.name,
"email": user.email,
"age": user.age
})
API Documentation
Air does not integrate with FastAPI's automatic API documentation. This is one reason why for API work we recommend instantiating a separate FastAPI app called api.
Combining HTML and API
You can easily serve both HTML pages and API endpoints from the same application:
# HTML page
app = air.Air()
api = fastapi.FastAPI()
@app.page
def dashboard():
return air.layouts.mvpcss(
air.Title("Dashboard"),
air.H1("Dashboard"),
# Load data via API call in JavaScript
air.Div(id="api-data"),
air.Script(
"""
fetch('/api/user-data')
.then(response => response.json())
.then(data => {
document.getElementById('api-data').innerHTML = JSON.stringify(data);
});
""",
type="module"
)
)
# API endpoint
@api.get("/user-data")
def get_user_data():
return {"message": "Hello from API", "timestamp": datetime.now()}
app.mount('/api', api)
Now would be a good time to commit your work:
git add .
git commit -m "Add API endpoints and development patterns"