Skip to main content

Prerequisites

Before you begin, ensure you have:
  • Python 3.8 or higher installed
  • FastrAPI installed (see Installation)
  • A text editor or IDE
  • Basic knowledge of Python and APIs

Your first FastrAPI application

Let’s create a simple “Hello World” API to get started.
1

Create a new file

Create a new file called main.py:
main.py
from fastrapi import FastrAPI

app = FastrAPI()

@app.get("/")
def hello():
    return {"Hello": "World"}

if __name__ == "__main__":
    app.serve("127.0.0.1", 8080)
2

Run the application

Run your application:
python main.py
Your API is now running on http://127.0.0.1:8080!
3

Test the endpoint

Open a new terminal and test your API:
curl http://127.0.0.1:8080/
You should see:
{"Hello": "World"}
Unlike FastAPI which requires a separate ASGI server like Uvicorn, FastrAPI has a built-in server powered by Rust’s Axum framework. Just call app.serve() and you’re ready to go!

Adding more endpoints

Let’s expand your API with multiple HTTP methods and endpoints.
main.py
from fastrapi import FastrAPI

app = FastrAPI()

@app.get("/hello")
def hello():
    return {"Hello": "World"}

@app.post("/echo")
def echo(data):
    return {"received": data}

@app.put("/update")
def update(data):
    return {"updated": data, "status": "success"}

@app.delete("/remove")
def remove(data):
    return {"deleted": data, "timestamp": "2025-09-28"}

if __name__ == "__main__":
    app.serve("127.0.0.1", 8080)

Testing different methods

curl http://127.0.0.1:8080/hello

Working with Pydantic models

FastrAPI integrates seamlessly with Pydantic for request validation and serialization.
main.py
from pydantic import BaseModel
from fastrapi import FastrAPI

api = FastrAPI()

class User(BaseModel):
    name: str
    age: int

class Address(BaseModel):
    street: str
    city: str
    zip: str

@api.post("/register")
def register(user: User, address: Address):
    return {
        "msg": f"Registered {user.name}, age {user.age}, living at {address.street}, {address.city} {address.zip}"
    }

if __name__ == "__main__":
    api.serve("127.0.0.1", 8080)
Test it with:
curl -X POST http://127.0.0.1:8080/register \
  -H "Content-Type: application/json" \
  -d '{
    "user": {"name": "John Doe", "age": 30},
    "address": {"street": "123 Main St", "city": "Springfield", "zip": "12345"}
  }'
FastrAPI automatically validates request data against your Pydantic models. If validation fails, it returns a 422 Unprocessable Entity error with details about what went wrong.

Response types

FastrAPI supports different response types for various content formats.
main.py
from fastrapi import FastrAPI
from fastrapi.responses import HTMLResponse, JSONResponse

api = FastrAPI()

@api.get("/html")
def get_html() -> HTMLResponse:
    return HTMLResponse("<h1>Hello, FastrAPI!</h1>")

@api.get("/json")
def get_json() -> JSONResponse:
    return JSONResponse({"message": "This is JSON", "status": "ok"})

if __name__ == "__main__":
    api.serve("127.0.0.1", 8080)
Available response types:
  • JSONResponse - JSON content (default)
  • HTMLResponse - HTML content
  • PlainTextResponse - Plain text
  • RedirectResponse - HTTP redirects

WebSockets

FastrAPI includes built-in WebSocket support for real-time bidirectional communication.
websocket.py
from fastrapi import FastrAPI
from fastrapi.websocket import websocket

app = FastrAPI()

@app.websocket("/ws")
async def websocket_endpoint(ws):
    await ws.accept()
    
    try:
        while True:
            data = await ws.receive_text()
            print(f"Client said: {data}")
            
            await ws.send_json({"reply": "Message received", "echo": data})
            
    except Exception as e:
        print(f"Connection closed: {e}")

if __name__ == "__main__":
    app.serve(host="0.0.0.0", port=8000)
Test the WebSocket with a client:
const ws = new WebSocket('ws://localhost:8000/ws');

ws.onopen = () => {
    console.log('Connected');
    ws.send('Hello from client!');
};

ws.onmessage = (event) => {
    console.log('Received:', JSON.parse(event.data));
};

Adding middleware

FastrAPI supports various middleware for cross-cutting concerns.
middleware.py
from fastrapi import FastrAPI
from fastrapi.responses import JSONResponse
from fastrapi.middleware import (
    CORSMiddleware,
    TrustedHostMiddleware,
    GZipMiddleware,
    SessionMiddleware
)

app = FastrAPI()

# CORS Middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["GET", "POST"],
    allow_headers=["*"],
    allow_credentials=False
)

# GZip Middleware
app.add_middleware(
    GZipMiddleware, 
    minimum_size=500,
    compresslevel=9
)

# TrustedHost Middleware
app.add_middleware(
    TrustedHostMiddleware, 
    allowed_hosts=["127.0.0.1", "localhost"],
    www_redirect=True
)

# Session Middleware
app.add_middleware(
    SessionMiddleware,
    secret_key="your-secret-key-here",
    session_cookie="fastrapi_session",
    max_age=3600,
    https_only=False
)

@app.get("/")
def index() -> JSONResponse:
    return JSONResponse({"status": "running"})

if __name__ == "__main__":
    app.serve("127.0.0.1", 8000)
Middleware is applied in the order it’s added. The first middleware added wraps all subsequent middleware and route handlers.

OpenAPI documentation

FastrAPI automatically generates OpenAPI documentation for your API.
main.py
from fastrapi import FastrAPI

# Customize OpenAPI URL
api = FastrAPI(openapi_url="/api-docs/openapi.json")

@api.get("/users")
def get_users():
    return {"users": []}

if __name__ == "__main__":
    api.serve("127.0.0.1", 8080)
Access your OpenAPI schema at: http://127.0.0.1:8080/api-docs/openapi.json

Complete example

Here’s a complete example combining everything we’ve learned:
app.py
from pydantic import BaseModel
from fastrapi import FastrAPI
from fastrapi.responses import JSONResponse
from fastrapi.middleware import CORSMiddleware, GZipMiddleware

app = FastrAPI(openapi_url="/api/openapi.json")

# Add middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"]
)

app.add_middleware(GZipMiddleware, minimum_size=1000)

# Define models
class Item(BaseModel):
    name: str
    description: str | None = None
    price: float
    quantity: int

class ItemResponse(BaseModel):
    id: int
    name: str
    price: float

# In-memory storage
items_db = []

@app.get("/")
def root():
    return {"message": "Welcome to FastrAPI!"}

@app.get("/items")
def list_items() -> JSONResponse:
    return JSONResponse({"items": items_db, "count": len(items_db)})

@app.post("/items")
def create_item(item: Item) -> JSONResponse:
    item_dict = item.dict()
    item_dict["id"] = len(items_db) + 1
    items_db.append(item_dict)
    return JSONResponse(item_dict)

@app.get("/items/{item_id}")
def get_item(item_id: int):
    for item in items_db:
        if item["id"] == item_id:
            return item
    return {"error": "Item not found"}

if __name__ == "__main__":
    print("Starting FastrAPI server on http://127.0.0.1:8080")
    app.serve("127.0.0.1", 8080)

Next steps

Migration guide

Migrate your existing FastAPI application

Advanced features

Explore advanced FastrAPI features

API reference

Complete API documentation

Examples

Browse more code examples

Build docs developers (and LLMs) love