Getting Started with Python FastAPI: Build High-Performance APIs in Half an Hour

leo 05/12/2025

FastAPI is one of the hottest web frameworks in the Python ecosystem, known for its high performance, automatic documentation generation, and strong type hints. It’s especially suitable for building RESTful APIs and data interfaces. This guide will take you from zero to proficiency using 8 code examples, step-by-step!

I. Environment Setup

First, install the required libraries (Python 3.7+):

bash

pip install fastapi uvicorn
  • fastapi: The core framework.
  • uvicorn: An ASGI server (used to run FastAPI applications).

II. Hello World: Your First FastAPI App

Create a file main.py and write the following code:

python

from fastapi import FastAPI

# Create a FastAPI instance
app = FastAPI()

# Define a route: GET request + root path
@app.get("/")
def read_root():
    return {"message": "Hello FastAPI!"}

# Startup command (run in terminal):
# uvicorn main:app --reload

Run it:

  1. After running the startup command in the terminal, you’ll see output like this:textINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [xxxxx] using WatchFiles
  2. Visit http://127.0.0.1:8000 in your browser. You’ll see the JSON response: {"message": "Hello FastAPI!"}
  3. Automatically generated API docs: Visit http://127.0.0.1:8000/docs for Swagger UI interactive documentation (allows direct API testing). Visit http://127.0.0.1:8000/redoc for a cleaner ReDoc version.

III. Core Features: Path Parameters & Query Parameters

3.1 Path Parameters (Parameters in the URL)

Used for passing required resource identifiers (e.g., user ID, product ID).

python

from fastapi import FastAPI

app = FastAPI()

# Path parameter: `item_id` is part of the path, type-hinted as `int`
@app.get("/items/{item_id}")
def read_item(item_id: int, q: str = None):
    return {"item_id": item_id, "q": q}

3.2 Query Parameters (Parameters after ? in the URL)

Used for passing optional filtering criteria (e.g., pagination, search keywords).

python

# Example request: /items/5?q=apple
# Response: {"item_id": 5, "q": "apple"}

# Without `q`: /items/5
# Response: {"item_id": 5, "q": null}

3.3 Type Validation & Default Values

FastAPI automatically performs data validation based on type hints.

python

# If you visit /items/abc (where item_id is not an int), a 422 error is returned:
# {"detail": [{"loc": ["path", "item_id"], "msg": "value is not a valid integer", "type": "type_error.integer"}]}

IV. Request Body: Receiving JSON Data

Used for passing complex data when creating resources (e.g., user registration, form submission). Uses Pydantic for data validation.

python

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# Define a request body model (Pydantic)
class Item(BaseModel):
    name: str        # Required field (no default value)
    price: float     # Required field
    is_offer: bool = None  # Optional field (default is None)

# Handle POST request + JSON body
@app.post("/items/")
def create_item(item: Item):
    return {"item_name": item.name, "item_price": item.price}

How to test:

  1. Go to http://127.0.0.1:8000/docs, find the /items/ endpoint, click “Try it out”, and input this JSON:json{ “name”: “iPhone”, “price”: 5999.9, “is_offer”: true }
  2. Click “Execute”. Response: {"item_name": "iPhone", "item_price": 5999.9}.
  3. If required fields are missing (e.g., name), a 422 error is automatically returned with details.

V. Comprehensive Example: Book Management API

A complete CRUD example showcasing practical FastAPI use.

python

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional

app = FastAPI()

# 1. Define a data model
class Book(BaseModel):
    id: Optional[int] = None  # ID is optional (auto-generated on creation)
    title: str
    author: str
    price: float

# 2. Mock database (use MySQL/PostgreSQL in real projects)
books = [
    Book(id=1, title="Python Programming", author="张三", price=59.9),
    Book(id=2, title="FastAPI Guide", author="李四", price=49.9)
]

# 3. CRUD Endpoint Implementations
# Get all books
@app.get("/books", response_model=List[Book])
def get_all_books():
    return books

# Get a single book (by ID)
@app.get("/books/{book_id}", response_model=Book)
def get_book(book_id: int):
    for book in books:
        if book.id == book_id:
            return book
    # If not found, return a 404 error
    raise HTTPException(status_code=404, detail="Book not found")

# Create a book
@app.post("/books", response_model=Book)
def create_book(book: Book):
    # Generate a new ID (last book's ID + 1, or 1 if list is empty)
    new_id = books[-1].id + 1 if books else 1
    new_book = Book(id=new_id, **book.dict())
    books.append(new_book)
    return new_book

# Update a book
@app.put("/books/{book_id}", response_model=Book)
def update_book(book_id: int, updated_book: Book):
    for idx, book in enumerate(books):
        if book.id == book_id:
            # Keep original ID, update other fields
            books[idx] = Book(id=book_id, **updated_book.dict())
            return books[idx]
    raise HTTPException(status_code=404, detail="Book not found")

# Delete a book
@app.delete("/books/{book_id}")
def delete_book(book_id: int):
    for idx, book in enumerate(books):
        if book.id == book_id:
            books.pop(idx)
            return {"detail": "Book deleted"}
    raise HTTPException(status_code=404, detail="Book not found")

Testing:

  • Visit http://127.0.0.1:8000/docs to test all endpoints interactively.
  • For example, when creating a book, the input JSON is automatically validated for field types.
  • Responses strictly follow the format defined by response_model.

VI. Useful Feature: Dependency Injection

FastAPI’s dependency injection system simplifies code reuse (e.g., for authorization, database connections).

python

from fastapi import FastAPI, Depends

app = FastAPI()

# Define a dependency (reusable logic)
def get_current_user():
    # In a real project, parse user info from a token here
    return {"username": "admin", "role": "admin"}

# Use the dependency in an endpoint
@app.get("/users/me")
def read_current_user(user: dict = Depends(get_current_user)):
    return user

Run it: Visit /users/me, response: {"username": "admin", "role": "admin"}.

VII. CORS (Cross-Origin Resource Sharing)

If your frontend (e.g., Vue/React) needs to call the API, you must handle CORS.

python

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# Configure allowed origins, methods, headers
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # In production, specify exact domains (e.g., ["http://localhost:8080"])
    allow_credentials=True,
    allow_methods=["*"],  # Allow all HTTP methods
    allow_headers=["*"],  # Allow all headers
)

@app.get("/")
def read_root():
    return {"message": "CORS configured"}

VIII. Deployment for Production

Development uses --reload for auto-restarts. Production requires optimized configuration.

bash

# Production startup command (using Gunicorn as a reverse proxy)
pip install gunicorn

# Run: workers = (CPU cores * 2) + 1
gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app

Summary

FastAPI’s core advantages:

  1. High Performance: Built on ASGI, supports async, performance close to Node.js/Go.
  2. Automatic Documentation: Generates interactive API docs with no extra configuration.
  3. Strong Type Validation: Pydantic ensures data validity, reducing debugging effort.
  4. Ease of Use: Clean syntax, gentle learning curve.