This repository contains a step-by-step tutorial on building a simple To-Do List API using FastAPI, a modern, fast (high-performance) web framework for building APIs with Python. The tutorial covers installation, basic setup, routes, error handling, Pydantic models, and more. It's designed for beginners to get started with FastAPI quickly.
- Why Use FastAPI?
- Installation and Getting Started
- GET and POST Routes
- Handling HTTP Errors
- JSON Requests and Path Parameters
- Pydantic Models
- Response Models
- Interactive Documentation
- FastAPI vs Flask vs Django
- Contributing
- License
- Author
FastAPI is an excellent choice for building APIs due to its:
- Easy to learn: Intuitive syntax and automatic interactive documentation.
- Fast development: Automatic data validation, serialization, and documentation.
- High performance: Asynchronous by default, powered by Starlette and Pydantic.
- Python 3.7 or higher.
- pip (Python package installer).
Open your terminal and run:
pip install fastapi uvicornFastAPI: The framework itself.Uvicorn: An ASGI server to run and test your FastAPI applications.
- Create a new directory for your project.
- Inside the directory, create a file named
main.pywith the following code:
from fastapi import FastAPI
# Create an app
app = FastAPI()
# Define a path for HTTP GET method
@app.get("/")
def root():
return {"Hello": "World"}- Run the server:
uvicorn main:app --reload- The
--reloadoption automatically reloads the server on file changes. - Open your browser and visit http://127.0.0.1:8000. You should see:
{"Hello": "World"}.
Routes in FastAPI define the URLs your app responds to. Let's build a simple to-do list application.
- After
app = FastAPI(), add an empty list for items:
items = []- Add a POST route to create items:
@app.post("/items")
def create_item(item: str):
items.append(item)
return item-
Test with curl:
curl -X POST -H "Content-Type: application/json" 'http://127.0.0.1:8000/items?item=apple'
-
Add another item, e.g., "orange".
- Add a GET route to retrieve a specific item:
@app.get("/items/{item_id}")
def get_item(item_id: int) -> str:
item = items[item_id]
return item-
Test with curl:
curl -X GET http://127.0.0.1:8000/items/0
-
Trying an invalid index (e.g.,
/items/7) will result in an "Internal Server Error".
To handle errors gracefully, use HTTPException.
- Import it:
from fastapi import FastAPI, HTTPException- Update the GET route:
@app.get("/items/{item_id}")
def get_item(item_id: int) -> str:
if item_id < len(items):
return items[item_id]
else:
raise HTTPException(status_code=404, detail=f"Item {item_id} not found")-
Test an invalid index again:
curl -X GET http://127.0.0.1:8000/items/7
Response:
{"detail": "Item 7 not found"}
For more on HTTP status codes, see MDN Documentation.
Add a GET route to list items with a query parameter limit:
@app.get("/items/")
def list_items(limit: int = 10):
return items[0:limit]-
Test (after adding at least 10 items):
curl -X GET 'http://127.0.0.1:8000/items?limit=3'
Pydantic provides data validation and structure. Import BaseModel:
from pydantic import BaseModelAdd a model after app = FastAPI():
class Item(BaseModel):
text: str
is_done: bool = FalseUpdate routes to use the model:
@app.post("/items")
def create_item(item: Item):
items.append(item)
return item
@app.get("/items/{item_id}")
def get_item(item_id: int) -> Item:
if item_id < len(items):
return items[item_id]
else:
raise HTTPException(status_code=404, detail=f"Item {item_id} not found")-
Test create_item with JSON:
curl -X POST -H "Content-Type: application/json" -d '{"text":"apple"}' 'http://127.0.0.1:8000/items'
Make text required by removing the default value.
Specify response types for better structure:
@app.get("/items", response_model=list[Item])
def list_items(limit: int = 10):
return items[0:limit]
@app.get("/items/{item_id}", response_model=Item)
def get_item(item_id: int) -> Item:
if item_id < len(items):
return items[item_id]
else:
raise HTTPException(status_code=404, detail=f"Item {item_id} not found")This is useful for frontend integrations.
FastAPI auto-generates interactive docs:
- Swagger UI: http://127.0.0.1:8000/docs
- ReDoc: http://127.0.0.1:8000/redoc
Use these to explore endpoints, parameters, and test requests.
- FastAPI: Async by default for high concurrency; simple route definitions, validation, and exceptions.
- Flask: More flexible but requires more boilerplate; synchronous by default.
- Django: Full-featured (ORM, admin panel) but heavier and slower for simple APIs.
FastAPI shines for performance-critical APIs.
Contributions are welcome! Fork the repo, make changes, and submit a pull request. For major changes, open an issue first.
This project is licensed under the MIT License - see the LICENSE file for details.
By Kadhem SELLAMI. Based on the tutorial from Teknolabs.