FastAPI: Building a Complete Application
By khoanc, at: 22:33 Ngày 13 tháng 4 năm 2023
FastAPI: Building a Complete Application
FastAPI, that is a modern and high-performance web framework for building APIs with Python, combines the simplicity of Flask with the performance of Node.js frameworks like Express. In this article, we will explore the step-by-step process of building a complete application using FastAPI, focusing on a book store management system as an example.
Check our public repo to get more details
Introduction to FastAPI
FastAPI is known as a highly efficient and easy to use framework. Those two important features (type hints and asynchronous programming) provide a seamless development experience. Its main features are:
- request validation
- dependency injection
- support for websockets
Setting up a FastAPI Project
In this article, we are going to build a bookstore management application using FastAPI.
First, we create a virtual environment to isolate our dependencies.
mkdir bookstore # create a directory
cd bookstore # go to the bookstore directory
python -m venv venv # create a virtualenv
source venv/bin/activate # activate the virtualenv
pip install fastapi uvicorn # Install required packages
Check our public repo to get more details
Defining Models and Database Schema
Lets define the models and database schema. We can use an Object-Relational Mapping (ORM) tool like SQLAlchemy to interact with the database.
Here's an example of how we can define a Book
model:
from sqlalchemy import Column, Integer, String, Float
from database import Base
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True)
title = Column(String, nullable=False)
author = Column(String, nullable=False)
price = Column(Float, nullable=False)
Check our public repo to get more details
Creating Routes and Endpoints
Once we have our models defined, we can start creating routes
and endpoints
for our API. FastAPI uses decorators
to define routes, and type hints to specify the expected request and response types.
Here's an example of how we can define a route to retrieve a list of books:
from fastapi import FastAPI
from typing import List
from models import Book
app = FastAPI()
@app.get("/books", response_model=List[Book])
async def get_books():
# Retrieve books from the database
books = db.query(Book).all()
return books
Check our public repo to get more details
Implementing CRUD Operations
We, then, need to implement CRUD (Create, Read, Update, Delete) operations for managing books. We can create routes for each operation and handle the corresponding requests.
Here's an example of how we can implement the create operation:
@app.post("/books", response_model=Book)
async def create_book(book: BookCreate):
# Create a new book
new_book = Book(title=book.title, author=book.author, price=book.price)
db.add(new_book)
db.commit()
db.refresh(new_book)
return new_book
Check our public repo to get more details
Handling Authentication and Authorization
For a secure application, authentication and authorization should be added to this project. FastAPI provides built-in support (security) for integrating with popular authentication mechanisms like OAuth2 and JWT (JSON Web Tokens).
Here's an example of how we can add authentication to a route:
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from .models import User
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@app.get("/books", response_model=List[Book])
async def get_books(token: str = Depends(oauth2_scheme)):
# Verify the token and retrieve the books
user = await authenticate_user(token)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid authentication credentials",
headers={"WWW-Authenticate": "Bearer"},
)
books = db.query(Book).all()
return books
Check our public repo to get more details
Validating Request Data
FastAPI has powerful request data validation capabilities. We can use Pydantic
models to define the expected request payloads and automatically validate the incoming data. Meaningful error messages are returned in the FastAPI's response.
Here's an example of how we can validate the request data for creating a book:
from pydantic import BaseModel
class BookCreate(BaseModel):
title: str
author: str
price: float
Uploading and Serving Files
In some applications, we may need to handle file uploads and serve the files to clients. That can be easily done by UploadFile
type from the fastapi module. We can define a route that accepts file uploads and saves them to the server.
Here's an example of how we can handle file uploads:
from fastapi import UploadFile, File
@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
contents = await file.read()
# Save the file or process its contents
# ...
return {"filename": file.filename}
Adding Pagination to API Responses
FastAPI provides utilities for adding pagination to API endpoints using page number and limit.
Here's an example of how we can implement pagination:
@app.get("/books")
async def get_books(page: int = 1, limit: int = 10):
offset = (page - 1) * limit
books = db.query(Book).offset(offset).limit(limit).all()
return books
Implementing Real-time Communication with WebSockets
FastAPI also supports real-time communication through WebSockets. We can create WebSocket routes and handle incoming WebSocket connections. This allows us to build interactive and event-driven applications.
Here's an example of how we can implement a WebSocket route:
from fastapi import WebSocket
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await websocket.send_text(f"You said: {data}")
Writing Tests for FastAPI Applications
Testing is an essential part of any software development process. FastAPI provides tools for writing tests to ensure the correctness and reliability of our applications. We can use the TestClient
class from the fastapi.testclient
module to simulate HTTP requests and validate the responses.
Here's an example of how we can write tests for our FastAPI application:
from fastapi.testclient import TestClient
from .main import app
client = TestClient(app)
def test_get_books():
response = client.get("/books")
assert response.status_code == 200
assert response.json() == []
Containerizing and Deploying FastAPI Applications
We can containerize it using tools like Docker and deploy it to a production environment. Containerization allows us to package our application and its dependencies into a portable and isolated environment. We can then deploy the container to cloud platforms like AWS or Google Cloud.
Here's an example of how we can create a Dockerfile for our FastAPI application:
dockerfile
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
COPY ./app /app
Conclusion
In this article, we have explored the process of building a complete application with FastAPI. We started by setting up a project, defining models and database schema, and creating routes and endpoints. We implemented CRUD operations, handled authentication and authorization, validated request data, and added advanced features like file uploads, pagination, and WebSockets. We also discussed writing tests for FastAPI applications and containerizing and deploying them. FastAPI's simplicity and performance make it an excellent choice for building modern web applications.
Check our public repo to get more details
FAQs
Q1: What is FastAPI?
FastAPI is a modern and high-performance web framework for building APIs with Python. It combines the simplicity of Flask with the performance of Node.js frameworks like Express.
Q2: Is FastAPI suitable for large-scale applications?
Yes, FastAPI is suitable for large-scale applications. Its asynchronous nature and performance optimizations make it well-suited for handling high traffic and demanding workloads.
Q3: Can I use FastAPI with a different database?
Yes, FastAPI is compatible with various databases. It works seamlessly with SQL databases like PostgreSQL and MySQL, as well as NoSQL databases like MongoDB.
Q4: Does FastAPI support authentication out of the box?
Yes, FastAPI provides built-in support for integrating with popular authentication mechanisms like OAuth2 and JWT (JSON Web Tokens). It makes it easy to secure your API endpoints.
Q5: How can I deploy a FastAPI application to production?
FastAPI applications can be deployed to production using various methods. You can containerize your application using tools like Docker and deploy it to cloud platforms like AWS or Google Cloud. Alternatively, you can deploy it to a traditional web server using ASGI servers like Uvicorn or Gunicorn.
Q6: Can I build a website with FastAPI?
Yes, you can build a website with FastAPI. While FastAPI is primarily designed for building APIs, it can also be used to serve web pages. FastAPI supports the creation of HTML templates and can render dynamic content for building server-side rendered websites.
Q7: How do I organize my FastAPI project?
Organizing your FastAPI project depends on your preferences and the size of your project. However, a common approach is to follow a modular structure. You can organize your project into separate modules or packages, each responsible for a specific area or functionality. This helps maintain a clean codebase and allows for better scalability and reusability. There are few blog posts suggesting best practices to organize a FastAPI project, ex: https://github.com/zhanymkanov/fastapi-best-practices
Q8: Is FastAPI good for bigger projects?
Yes, FastAPI is well-suited for bigger projects. Its performance and asynchronous capabilities make it a powerful choice for handling complex and high-traffic applications. FastAPI's use of modern Python features, such as type hints and dependency injection, also promotes maintainability and scalability.
Q9: Can I use FastAPI for the backend?
Yes, FastAPI is primarily designed for building backend applications. It excels at creating high-performance web APIs and can handle various backend tasks, such as processing requests, interacting with databases, and implementing business logic. FastAPI is a great choice for developing the backend of your applications.
Q10: What is the fastest backend API language?
The speed of a backend API language depends on various factors, including the specific implementation, hardware, and workload. However, FastAPI, built with Python, is known for its impressive performance. It leverages asynchronous programming and modern Python features, making it one of the fastest backend API frameworks available.
Reference
- https://github.com/ycd/manage-fastapi
- https://github.com/zhanymkanov/fastapi-best-practices
- https://fastapi.tiangolo.com/lo/
- https://flask.palletsprojects.com/en/2.3.x/
- https://nodejs.org/en
- https://www.sqlalchemy.org/