Concepts 🚀 Project 🧮 Labs
📚 Learn / Build OpenBenchML — Step by Step / Your First FastAPI Route
🚀 Step 1 of 10

Your First FastAPI Route

Start with one Python file. Define an async function, decorate it with @app.get, visit it in the browser. This is the atom of every web app.

🎯 Goal — what you'll achieve in this step Run `python main.py`, open http://localhost:8000/health, and see {"status":"ok"} in the browser.
📖 The basic concept Learn this first. It's the pure Python/HTML idea, stripped of all app complexity.
# The basic concept: a function that returns data

def health():
    return {'status': 'ok'}

print(health())  # {'status': 'ok'}

# FastAPI adds two things:
#   1. @app.get('/path') decorator  ->  registers the function as a route
#   2. async  ->  the function can await I/O without blocking other requests
🧮 Apply it to OpenBenchML
📄 main.py python
# Step 1: A FastAPI app with one route
from fastapi import FastAPI
import uvicorn

app = FastAPI(title='OpenBenchML')

@app.get('/health')
async def health():
    return {'status': 'ok'}

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)
📄 run.sh bash
# Install FastAPI + uvicorn
pip install fastapi uvicorn

# Run the server
python main.py

# In another terminal (or browser):
curl http://localhost:8000/health
# {"status":"ok"}

# FastAPI also gives you free docs at:
# http://localhost:8000/docs

How it works

Every web app is just functions that return data when a URL is hit. FastAPI's job is to (a) listen for HTTP requests, (b) match the URL to a registered function, (c) call that function, and (d) send the return value back as JSON. The @app.get('/health') decorator is what registers the function — without it, health() is just a regular Python function that nothing calls. The async keyword means the function can yield control to the event loop while waiting for I/O (database, HTTP, file) — so one worker can handle thousands of concurrent requests. In step 1, there's no I/O, so async is just a convention; it becomes essential in step 3 when we add a database.

✏️ Try yourself Add a second route @app.get('/about') that returns {'name': 'OpenBenchML', 'version': '0.1'}. Visit http://localhost:8000/about. Then add @app.get('/users/{user_id}') that returns {'user_id': user_id} — notice FastAPI extracts the path parameter automatically.
⚠️ Common mistakes to avoid
  • Forgetting `async` (or `def`) — the function must be one or the other, FastAPI won't accept a bare expression.
  • Running `python main.py` without installing fastapi + uvicorn first — `pip install fastapi uvicorn`.
  • Using `return` with a string — FastAPI wraps dicts as JSON, but a bare string gets quoted twice. Always return a dict (or a Pydantic model).
  • Binding to `host='127.0.0.1'` in production — use `0.0.0.0` so the app listens on all interfaces, or it's unreachable from outside the container.
🔍 Where this is used in OpenBenchML app/main.py — the /health endpoint is exactly this. Every other route in the app follows the same pattern.
Next — Step 2
HTML + Jinja2 Templates — Your First Page
→