Back to Posts
MacBook Pro on a desk displaying code from a 'Building REST APIs with Python and FastAPI tutorial' on screen with API testing application Postman in view.

FastAPI Tutorial: Creating REST APIs in Python

Crafting a deep dive into REST APIs with Python and FastAPI entails covering several foundational and advanced topics to provide a thorough understanding. This blog post will navigate through what REST APIs are, their principles, and how to implement one using Python with the FastAPI framework. FastAPI is chosen for its performance, ease of use, and support for asynchronous programming, making it an excellent choice for modern web applications.

Introduction to REST APIs

REST, or Representational State Transfer, is an architectural style for designing networked applications. It relies on a stateless, client-server communication model in which web services are viewed as resources, and these resources are manipulated using a set of operations (verbs) like GET, POST, PUT, DELETE, and PATCH.

A RESTful API exposes a web application’s resources to clients in a performant, scalable, and stateless manner. Each resource is identified by URIs (Uniform Resource Identifiers) and can be accessed and manipulated using the standard HTTP methods. This architectural style is widely adopted due to its simplicity, scalability, and compatibility with the web.

Key Principles of REST

REST APIs are built around six key principles:

  1. Uniform interface: Ensuring the interface between client and server is uniform and consistent.
  2. Stateless operations: Each request from the client to the server must contain all the information needed to understand and complete the request.
  3. Cacheable responses: Responses should be explicitly labelled as cacheable or not to improve client-side performance.
  4. Client-server architecture: Separating the user interface concerns from the data storage concerns improves the portability of the user interface across multiple platforms.
  5. Layered system: A client cannot ordinarily tell whether it is connected directly to the end server or to an intermediary along the way.
  6. Code on demand (optional): Servers can extend client functionality by transferring executable code.

Building a REST API with FastAPI

FastAPI is a modern, fast (high-performance) web framework for building APIs with Python 3.6+ based on standard Python type hints. The key features of FastAPI include:

  • Fast to code: Increase the speed to develop features thanks to its simplicity.
  • Type checking: Reduce errors with the built-in support for request and response data validation.
  • Asynchronous support: Leverage modern Python’s asynchronous features to handle concurrent requests in a scalable way.

Installation

First, ensure you have Python 3.8 or later. Install FastAPI and an ASGI server, such as uvicorn, to serve your application. The documentation suggests using pip to install the application:

pip install fastapi uvicorn

But I much prefer to use Poetry to manage my packages, you can check out how here: https://www.arjancodes.com/blog/managing-python-project-dependencies-with-poetry/

Once your Poetry environment is set up, you can install the packages using poetry add fastapi uvicorn

Example: A simple CRUD API

Let’s create a simple CRUD (Create, Read, Update, Delete) API for managing books. The API will allow clients to perform basic operations on a book resource.

Step 1: Define the FastAPI app and model

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
from uuid import uuid4, UUID

app = FastAPI()

class Book(BaseModel):
    id: Optional[UUID] = uuid4()
    title: str
    author: str
    description: Optional[str] = None

# In-memory storage
books_db: List[Book] = []

@app.get("/")
async def read_root():
    return {"Hello": "World"}

Step 2: Add CRUD operations

@app.post("/books/", response_model=Book)
async def create_book(book: Book):
    books_db.append(book)
    return book

@app.get("/books/", response_model=List[Book])
async def read_books():
    return books_db

@app.get("/books/{book_id}", response_model=Book)
async def read_book(book_id: UUID):
    for book in books_db:
        if book.id == book_id:
            return book
    raise HTTPException(status_code=404, detail="Book not found")

@app.put("/books/{book_id}", response_model=Book)
async def update_book(book_id: UUID, book: Book):
    for index, stored_book in enumerate(books_db):
        if stored_book.id == book_id:
            books_db[index] = book
            return book
    raise HTTPException(status_code=404, detail="Book not found")

@app.delete("/books/{book_id}", response_model=Book)
async def delete_book(book_id: UUID):
    for index, book in enumerate(books_db):
        if book.id == book_id:
            return books_db.pop(index)
    raise HTTPException(status_code=404, detail="Book not found")

Step 3: Run the API server

Run the following command in your terminal:

uvicorn main:app --reload

This command runs the application on localhost at port 8000. The --reload flag makes the server restart after code changes, simplifying the development process.

Testing your API

You can test your API using tools like curl, Postman, or directly through the documentation interface provided by FastAPI at http://localhost:8000/docs.

Pasted_image_20240404120403.png

Final thoughts

This post covered the basics of REST APIs, the principles that guide their design, and a practical example of building a simple CRUD API with Python and FastAPI. FastAPI’s design and features make it an excellent choice for developing modern web applications and APIs that adhere to the REST architectural style. As you build more complex applications, you’ll appreciate the simplicity, flexibility, and performance FastAPI offers.

Whether you’re building APIs for web applications, microservices, or data services, understanding REST principles and leveraging modern frameworks like FastAPI can significantly enhance your development workflow and application performance.

Improve your code with my 3-part code diagnosis framework

Watch my free 30 minutes code diagnosis workshop on how to quickly detect problems in your code and review your code more effectively.

When you sign up, you'll get an email from me regularly with additional free content. You can unsubscribe at any time.

Recent posts