Building Your First FastAPI Application: Step-by-Step Tutorial
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. It leverages the latest Python features to provide an intuitive and efficient way to develop APIs. This step-by-step tutorial will guide you through the process of building your first FastAPI application, covering fundamental concepts, usage methods, common practices, and best practices.
Table of Contents
- Prerequisites
- Installation
- Building a Simple FastAPI Application
- Adding Path Parameters
- Query Parameters
- Request Body
- Data Validation
- Error Handling
- Testing Your FastAPI Application
- Deployment
- Best Practices
- Conclusion
- References
Prerequisites
- Basic knowledge of Python programming.
- Familiarity with RESTful API concepts.
Installation
First, you need to install FastAPI and Uvicorn (a lightning-fast ASGI server). You can use pip to install them:
pip install fastapi uvicorn
Building a Simple FastAPI Application
Let’s start by creating a simple “Hello, World!” FastAPI application.
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"Hello": "World"}
To run the application, use the following command in your terminal:
uvicorn main:app --reload
Now, open your browser and go to http://127.0.0.1:8000. You should see a JSON response {"Hello": "World"}.
Adding Path Parameters
Path parameters are variables in the path of the URL. For example, let’s create an API to get an item by its ID.
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int):
return {"item_id": item_id}
Here, item_id is a path parameter of type int. If you access http://127.0.0.1:8000/items/42, you’ll get {"item_id": 42}.
Query Parameters
Query parameters are used to pass additional information in the URL after the ? symbol. Let’s modify our previous example to accept an optional q query parameter.
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
if q:
return {"item_id": item_id, "q": q}
return {"item_id": item_id}
Now, if you access http://127.0.0.1:8000/items/42?q=test, you’ll get {"item_id": 42, "q": "test"}.
Request Body
To receive data in the request body, you can use Pydantic models. Let’s create an API to create an item.
# main.py
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
is_offer: bool = None
@app.post("/items/")
def create_item(item: Item):
return item
You can use tools like curl or Postman to send a POST request with a JSON body. For example:
curl -X POST "http://127.0.0.1:8000/items/" -H "Content-Type: application/json" -d '{"name": "Foo", "price": 42.0}'
Data Validation
FastAPI uses Pydantic for data validation. If the input data doesn’t match the expected type or format, it will automatically return a 422 Unprocessable Entity response. For example, if you try to send an invalid item_id (non-integer) in the previous path parameter example, you’ll get an error response.
Error Handling
FastAPI provides built-in error handling. However, you can also define custom error handlers. For example, let’s handle a specific exception.
# main.py
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/items/{item_id}")
def read_item(item_id: int):
if item_id < 0:
raise HTTPException(status_code=400, detail="Item ID cannot be negative")
return {"item_id": item_id}
Now, if you access http://127.0.0.1:8000/items/-1, you’ll get a 400 Bad Request response with the custom error message.
Testing Your FastAPI Application
You can use the TestClient from fastapi.testclient to test your application.
# test_main.py
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_read_item():
response = client.get("/items/42")
assert response.status_code == 200
assert response.json() == {"item_id": 42}
You can run the tests using a test runner like pytest:
pytest test_main.py
Deployment
There are several ways to deploy a FastAPI application. One common approach is to use a cloud provider like Heroku or Google Cloud Platform. You can also use Docker to containerize your application. Here’s a simple example of a Dockerfile:
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
Then, you can build and run the Docker image:
docker build -t my-fastapi-app .
docker run -p 80:80 my-fastapi-app
Best Practices
- Use Type Hints: FastAPI relies on Python type hints for data validation and automatic documentation generation.
- Organize Your Code: Use modules and packages to keep your codebase organized, especially for larger applications.
- Write Tests: Testing your API helps catch bugs early and ensures its reliability.
- Secure Your API: Implement authentication and authorization mechanisms to protect your API endpoints.
Conclusion
In this tutorial, we’ve covered the essential steps to build your first FastAPI application. We’ve explored path parameters, query parameters, request bodies, data validation, error handling, testing, and deployment. FastAPI’s simplicity and performance make it a great choice for building modern APIs with Python. By following the best practices, you can develop robust and scalable applications.