Skip to content

Quick Start¶

Learn the basics of Cello in 5 minutes.

Create Your First App¶

1. Create a file¶

app.py
from cello import App, Response

app = App()

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

@app.get("/users/{id}")
def get_user(request):
    user_id = request.params["id"]
    return {"id": user_id, "name": "John Doe"}

@app.post("/users")
def create_user(request):
    data = request.json()
    return Response.json({"id": 1, **data}, status=201)

if __name__ == "__main__":
    app.run()

2. Run the app¶

python app.py

Output:

🚀 Cello running at http://127.0.0.1:8000

3. Test it¶

# GET request
curl http://127.0.0.1:8000/
# {"message": "Hello, Cello!"}

# GET with path parameter
curl http://127.0.0.1:8000/users/123
# {"id": "123", "name": "John Doe"}

# POST request
curl -X POST http://127.0.0.1:8000/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Jane"}'
# {"id": 1, "name": "Jane"}

Core Concepts¶

Routes¶

Define routes using decorators:

@app.get("/path")      # GET request
@app.post("/path")     # POST request
@app.put("/path")      # PUT request
@app.patch("/path")    # PATCH request
@app.delete("/path")   # DELETE request

Path Parameters¶

Capture dynamic parts of the URL:

@app.get("/users/{user_id}/posts/{post_id}")
def get_post(request):
    user_id = request.params["user_id"]
    post_id = request.params["post_id"]
    return {"user_id": user_id, "post_id": post_id}

Query Parameters¶

Access query string values:

# GET /search?q=python&limit=10
@app.get("/search")
def search(request):
    query = request.query.get("q", "")
    limit = int(request.query.get("limit", "10"))
    return {"query": query, "limit": limit}

Request Body¶

Parse JSON request bodies:

@app.post("/items")
def create_item(request):
    data = request.json()  # Parse JSON body
    name = data.get("name")
    price = data.get("price")
    return {"name": name, "price": price}

Response Types¶

Return different response types:

# JSON (default - just return a dict)
return {"key": "value"}

# Explicit JSON with status
return Response.json({"created": True}, status=201)

# Text
return Response.text("Hello, World!")

# HTML
return Response.html("<h1>Welcome</h1>")

# Redirect
return Response.redirect("/new-location")

# No content (204)
return Response.no_content()

Headers¶

Access and set headers:

@app.get("/headers")
def headers(request):
    # Read header
    auth = request.get_header("Authorization")

    # Set header in response
    response = Response.json({"auth": auth})
    response.set_header("X-Custom", "value")
    return response

Async Handlers¶

Use async handlers for I/O operations:

@app.get("/async")
async def async_handler(request):
    # Await async operations
    data = await fetch_from_database()
    return {"data": data}

Middleware¶

Enable built-in middleware:

app = App()

# CORS
app.enable_cors()

# Logging
app.enable_logging()

# Compression
app.enable_compression()

# Rate limiting (100 requests per minute)
app.enable_rate_limit(requests=100, window=60)

Blueprints¶

Organize routes with blueprints:

from cello import App, Blueprint

# Create blueprint
api = Blueprint("/api/v1")

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

@api.get("/users/{id}")
def get_user(request):
    return {"id": request.params["id"]}

# Register blueprint
app = App()
app.register_blueprint(api)

CLI Options¶

Run with different options:

# Custom host and port
python app.py --host 0.0.0.0 --port 8080

# Production mode with workers
python app.py --env production --workers 4

# Development with hot reload
python app.py --env development --reload

# Debug mode
python app.py --debug

What's Next?¶

  • First Application


    Build a complete REST API step by step

    First App

  • Features


    Explore all Cello features

    Features

  • Security


    Add authentication and security

    Security

  • Tutorials


    Learn through hands-on tutorials

    Learn