FastAPI: A Comprehensive Guide

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. In this guide, we'll walk through setting up FastAPI and implementing all the basic CRUD operations. Installation and Setup First, let's set up a virtual environment and install FastAPI: Create a virtual environment python -m venv venv Activate the virtual environment On Windows: venv\Scripts\activate On macOS/Linux: source venv/bin/activate Install FastAPI with all dependencies pip install "fastapi[standard]" Basic FastAPI Application Let's create a movie API example instead of books. Create a file called app.py: from fastapi import FastAPI app = FastAPI() MOVIES = [ {"title": "Inception", "director": "Christopher Nolan", "genre": "sci-fi"}, {"title": "The Shawshank Redemption", "director": "Frank Darabont", "genre": "drama"}, {"title": "The Dark Knight", "director": "Christopher Nolan", "genre": "action"}, {"title": "Pulp Fiction", "director": "Quentin Tarantino", "genre": "crime"}, {"title": "Parasite", "director": "Bong Joon-ho", "genre": "drama"} ] Running the Application Start the server with: uvicorn app:app --reload The --reload flag enables auto-reload when you make code changes. Visit http://127.0.0.1:8000/docs to see the interactive Swagger UI documentation. Implementing CRUD Operations 1. GET Request (Read All) @app.get('/movies') async def read_all_movies(): return MOVIES This endpoint returns the entire list of movies. The @app.get decorator defines a GET request at the /movies endpoint 2. Path Parameters (Read One) @app.get('/movies/{movie_title}') async def get_movie(movie_title: str): for movie in MOVIES: if movie.get("title").casefold() == movie_title.casefold(): return movie return {"error": "Movie not found"} This endpoint retrieves a single movie by its title. The {movie_title} in the path is a path parameter that captures the movie title from the URL. 3. Query Parameters (Filtering) @app.get('/movies/') async def read_movies_by_genre(genre: str): movies_to_return = [] for movie in MOVIES: if movie.get('genre').casefold() == genre.casefold(): movies_to_return.append(movie) return movies_to_return if movies_to_return else {"message": "No movies found in this genre"} This endpoint filters movies by genre using a query parameter. The genre parameter is passed in the URL as a query string (e.g., /movies/?genre=drama). 4. POST Request (Create) from fastapi import Body @app.post('/movies/create_movie') async def create_movie(new_movie=Body()): MOVIES.append(new_movie) return {"message": "Movie added successfully", "movie": new_movie} This endpoint adds a new movie to the list. The Body dependency extracts the JSON body from the request, which contains the new movie's details. 5. PUT Request (Update) @app.put('/movies/update_movie') async def update_movie(updated_movie=Body()): for i in range(len(MOVIES)): if MOVIES[i].get('title').casefold() == updated_movie.get('title').casefold(): MOVIES[i] = updated_movie return {"message": "Movie updated successfully"} return {"error": "Movie not found"} This endpoint updates an existing movie's details. It searches for the movie by title and replaces it with the updated movie data. 6. DELETE Request @app.delete('/movies/delete_movie/{movie_title}') async def delete_movie(movie_title: str): for i in range(len(MOVIES)): if MOVIES[i].get('title').casefold() == movie_title.casefold(): deleted_movie = MOVIES.pop(i) return {"message": "Movie deleted successfully", "deleted_movie": deleted_movie} return {"error": "Movie not found"} This endpoint deletes a movie by its title. It searches for the movie and removes it from the list if found. Best Practices Always use virtual environments Organize your code with routers as your app grows Add input validation using Pydantic models Implement proper error handling Consider adding authentication for production APIs

Mar 29, 2025 - 21:03
 0
FastAPI: A Comprehensive Guide

FastAPI is a modern, fast (high-performance), web framework for building APIs with Python 3.7+ based on standard Python type hints. In this guide, we'll walk through setting up FastAPI and implementing all the basic CRUD operations.

Installation and Setup

First, let's set up a virtual environment and install FastAPI:

Create a virtual environment

python -m venv venv

Activate the virtual environment

On Windows:

venv\Scripts\activate

On macOS/Linux:

source venv/bin/activate

Install FastAPI with all dependencies

pip install "fastapi[standard]"

Basic FastAPI Application

Let's create a movie API example instead of books. Create a file called app.py:

from fastapi import FastAPI

app = FastAPI()

MOVIES = [
    {"title": "Inception", "director": "Christopher Nolan", "genre": "sci-fi"},
    {"title": "The Shawshank Redemption", "director": "Frank Darabont", "genre": "drama"},
    {"title": "The Dark Knight", "director": "Christopher Nolan", "genre": "action"},
    {"title": "Pulp Fiction", "director": "Quentin Tarantino", "genre": "crime"},
    {"title": "Parasite", "director": "Bong Joon-ho", "genre": "drama"}
]

Running the Application

Start the server with:

uvicorn app:app --reload

The --reload flag enables auto-reload when you make code changes.

Visit http://127.0.0.1:8000/docs to see the interactive Swagger UI documentation.

Implementing CRUD Operations

1. GET Request (Read All)

@app.get('/movies')
async def read_all_movies():
    return MOVIES

This endpoint returns the entire list of movies. The @app.get decorator defines a GET request at the /movies endpoint

2. Path Parameters (Read One)

@app.get('/movies/{movie_title}')
async def get_movie(movie_title: str):
    for movie in MOVIES:
        if movie.get("title").casefold() == movie_title.casefold():
            return movie
    return {"error": "Movie not found"}

This endpoint retrieves a single movie by its title. The {movie_title} in the path is a path parameter that captures the movie title from the URL.

3. Query Parameters (Filtering)

@app.get('/movies/')
async def read_movies_by_genre(genre: str):
    movies_to_return = []
    for movie in MOVIES:
        if movie.get('genre').casefold() == genre.casefold():
            movies_to_return.append(movie)
    return movies_to_return if movies_to_return else {"message": "No movies found in this genre"}

This endpoint filters movies by genre using a query parameter. The genre parameter is passed in the URL as a query string (e.g., /movies/?genre=drama).

4. POST Request (Create)

from fastapi import Body

@app.post('/movies/create_movie')
async def create_movie(new_movie=Body()):
    MOVIES.append(new_movie)
    return {"message": "Movie added successfully", "movie": new_movie}

This endpoint adds a new movie to the list. The Body dependency extracts the JSON body from the request, which contains the new movie's details.

5. PUT Request (Update)

@app.put('/movies/update_movie')
async def update_movie(updated_movie=Body()):
    for i in range(len(MOVIES)):
        if MOVIES[i].get('title').casefold() == updated_movie.get('title').casefold():
            MOVIES[i] = updated_movie
            return {"message": "Movie updated successfully"}
    return {"error": "Movie not found"}

This endpoint updates an existing movie's details. It searches for the movie by title and replaces it with the updated movie data.

6. DELETE Request

@app.delete('/movies/delete_movie/{movie_title}')
async def delete_movie(movie_title: str):
    for i in range(len(MOVIES)):
        if MOVIES[i].get('title').casefold() == movie_title.casefold():
            deleted_movie = MOVIES.pop(i)
            return {"message": "Movie deleted successfully", "deleted_movie": deleted_movie}
    return {"error": "Movie not found"}

This endpoint deletes a movie by its title. It searches for the movie and removes it from the list if found.

Best Practices

  1. Always use virtual environments
  2. Organize your code with routers as your app grows
  3. Add input validation using Pydantic models
  4. Implement proper error handling
  5. Consider adding authentication for production APIs