What is FastAPI?
FastAPI is a modern web framework for building APIs with Python 3.7+ based on standard Python type hints. Inherently asynchronous, FastAPI is designed to be fast, efficient, and easy to use. It leverages Python type annotations to provide rapid development, automatic validation, serialization, and interactive API documentation through Swagger UI and ReDoc.
Key Features of FastAPI
-
Fast: As the name implies, FastAPI is built on Starlette for asynchronous capabilities and Pydantic for data validation. This results in high performance, comparable to Node.js and Go.
-
Automatic Documentation: FastAPI auto-generates interactive API documentation using OpenAPI, making it easy to explore and test APIs directly from the generated interface.
-
Data Validation: By using Pydantic, FastAPI ensures data is validated automatically based on type annotations, which enhances reliability in API responses.
-
Asynchronous Capabilities: Built on Python’s
asyncio, FastAPI supports asynchronous request handling, which improves scalability and responsiveness. -
Easy Integration: FastAPI integrates seamlessly with other libraries like SQLAlchemy for database operations, allowing developers to build complex applications without major hurdles.
-
Dependency Injection: FastAPI offers a simple and robust system for handling dependencies, making code more modular and reusable.
Getting Started with FastAPI
Prerequisites
Before starting with FastAPI, ensure you have the following installed:
- Python 3.7+
- pip package manager
- Basic knowledge of Python programming
Installation
Install FastAPI along with an ASGI server, like uvicorn, which is needed to run applications:
pip install fastapi uvicorn
Creating Your First FastAPI Application
-
Project Structure:
Create a new project directory:
mkdir fastapi-example cd fastapi-example touch main.py -
Basic Application:
Open
main.pyand add the following code:from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} -
Running the Application:
Use the
uvicorncommand to run your application:uvicorn main:app --reloadWith the
--reloadflag, the server automatically reloads when code changes are detected. Open your browser and navigate to http://127.0.0.1:8000/ to see the JSON response.
Path Parameters and Query Parameters
FastAPI allows you to create dynamic paths in your API. Here’s how to incorporate path and query parameters:
-
Path Parameters:
Modify your
main.pyto include a path parameter:@app.get("/items/{item_id}") def read_item(item_id: int): return {"item_id": item_id}Access this in your browser by going to
/items/42, where42can be replaced with any integer. -
Query Parameters:
To define optional query parameters, update your function to include a query parameter:
@app.get("/items/") def read_items(skip: int = 0, limit: int = 10): return {"skip": skip, "limit": limit}You can now navigate to
/items/?skip=1&limit=5, and it will return the specified skip and limit values.
Request Body with Pydantic Models
FastAPI utilizes Pydantic models to validate incoming request bodies effectively. Here’s how to define a request body:
-
Defining Pydantic Models:
Create a model for the items:
from pydantic import BaseModel class Item(BaseModel): id: int name: str description: str = None price: float tax: float = None -
Using the Model in a Path:
Incorporate the Pydantic model in one of your API endpoints:
@app.post("/items/") def create_item(item: Item): return itemWhen you POST data to
/items/, FastAPI automatically validates the request body against theItemmodel.
Response Models
FastAPI also allows you to define response models to ensure that the correct data structure is returned to clients:
@app.get("/items/{item_id}", response_model=Item)
def read_item(item_id: int):
return {"id": item_id, "name": "Item Name", "price": 10.0}
This ensures that the response will conform to the structure of the Item model.
Dependency Injection
FastAPI simplifies managing dependencies with dependency injection. Define a dependency function, for example:
def query_param_dependency(q: str = None):
return q
@app.get("/dependency-example/")
def dependency_example(q: str = Depends(query_param_dependency)):
return {"q": q}
Using Depends, you can easily test functions or share dependencies across multiple endpoints.
Handling CORS
When building APIs that interact with front-end applications from different origins, Cross-Origin Resource Sharing (CORS) must be handled. This can be done using the fastapi.middleware.cors.CORSMiddleware:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Database Integration
Integrating a database is essential for most applications. FastAPI works effectively with ORM libraries like SQLAlchemy. Here’s a brief overview:
-
Installation:
If using SQLAlchemy, install it alongside a database driver:
pip install sqlalchemy databases[postgresql] -
Database Configuration:
Add database models and connection configuration:
from sqlalchemy import create_engine, Column, Integer, String, Float from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker DATABASE_URL = "postgresql://user:password@localhost/dbname" engine = create_engine(DATABASE_URL) Base = declarative_base() class Item(Base): __tablename__ = 'items' id = Column(Integer, primary_key=True, index=True) name = Column(String, index=True) price = Column(Float) Base.metadata.create_all(bind=engine) -
CRUD Operations:
With SQLAlchemy, implement standard CRUD (Create, Read, Update, Delete) operations for your models. Use FastAPI routes to expose these functionalities.
Testing Your FastAPI Application
FastAPI supports testing through the httpx library. Here’s a basic example of how to set up tests:
-
Install Testing Dependencies:
pip install pytest httpx -
Create a Test File:
Inside your project directory, create a
test_main.py:from fastapi.testclient import TestClient from main import app client = TestClient(app) def test_read_root(): response = client.get("/") assert response.status_code == 200 assert response.json() == {"Hello": "World"} -
Run Your Tests:
Execute your tests with:
pytest
Deploying FastAPI
Once your application is complete, consider deploying it. Various options include:
- Docker: Package your FastAPI app as a Docker container.
- Cloud Services: Deploy on platforms like Heroku, AWS, or DigitalOcean.
- Static Hosting: Consider using platforms like Vercel for static sites frontending your FastAPI.
Final Thoughts
FastAPI offers a compelling choice for building RESTful APIs in Python, thanks to its performance, ease of use, and robust features. By leveraging Python type hints, automatic validation, and easy integration with popular libraries, you can develop high-quality APIs in significantly less time. With the rise of asynchronous programming in Python, FastAPI positions itself as a leader in modern web development practices. Dive into the FastAPI documentation for deeper insights, advanced features, and community support, empowering you to build scalable APIs efficiently.