1659 words
8 minutes
Building an API with FastAPI| A Step-by-Step Tutorial for Beginners

Building an API with FastAPI: A Step-by-Step Guide for Beginners#

An Application Programming Interface (API) serves as a messenger, allowing different software applications to communicate and exchange data. APIs are fundamental building blocks of modern web and mobile applications, enabling services to interact, share information, and leverage functionalities from one another. Building APIs facilitates data exchange between a frontend (like a website or mobile app) and a backend server, or between different backend services.

FastAPI is a modern, fast (high-performance) web framework for building APIs with Python 3.7+ based on standard Python type hints. Its key advantages include speed comparable to NodeJS and Go, rapid development time, robust data validation and serialization via Pydantic, and automatic generation of interactive API documentation (Swagger UI and ReDoc). These features make FastAPI an excellent choice for individuals new to API development looking for a Python-based solution.

This article provides a structured, step-by-step tutorial on building a basic API using FastAPI, covering essential concepts and practical implementation.

Essential Concepts in API Development#

Understanding core concepts is crucial before building an API:

  • HTTP Methods: Standard actions performed on resources. Common methods include:
    • GET: Retrieves data from a specified resource.
    • POST: Sends data to a server to create a new resource.
    • PUT: Sends data to a server to update an existing resource.
    • DELETE: Removes a specified resource.
  • Endpoints (Routes): Specific URLs at which an API can be accessed to perform actions on resources. For example, /items might be an endpoint for managing items, and /items/123 might refer to a specific item with ID 123.
  • Request: Data sent by a client to the API. This can include headers, parameters (path, query), and a request body.
  • Response: Data sent back by the API to the client. This typically includes a status code (indicating success or failure, e.g., 200 OK, 404 Not Found) and a response body containing the requested data or confirmation of the action.
  • JSON (JavaScript Object Notation): A lightweight data interchange format that is easy for humans to read and write and easy for machines to parse and generate. It is the standard format for data exchange in web APIs.
  • Virtual Environments: Isolated Python environments that allow managing dependencies for different projects separately, preventing conflicts. Creating a virtual environment is standard practice for new Python projects.
  • Asynchronous Programming: FastAPI supports asynchronous operations (async/await), allowing the API to handle multiple requests concurrently without blocking, leading to improved performance, especially for I/O-bound tasks (like database calls or external API requests).

Step-by-Step Tutorial: Building a Simple FastAPI API#

This tutorial guides through setting up a minimal FastAPI application.

Prerequisites#

  • Python 3.7+ installed on the system.
  • pip, Python’s package installer (usually comes with Python).

Step 1: Set Up a Virtual Environment#

Creating a virtual environment isolates project dependencies.

  1. Open a terminal or command prompt.
  2. Navigate to the desired project directory.
  3. Create a virtual environment (named .venv in this example):
    Terminal window
    python -m venv .venv
  4. Activate the virtual environment:
    • On Windows:
      Terminal window
      .venv\Scripts\activate
    • On macOS and Linux:
      Terminal window
      source .venv/bin/activate
    The terminal prompt should change to indicate the virtual environment is active (e.g., (.venv) $).

Step 2: Install FastAPI and an ASGI Server#

FastAPI requires an ASGI (Asynchronous Server Gateway Interface) server to run the application. Uvicorn is a common choice.

Install the necessary packages using pip within the active virtual environment:

Terminal window
pip install fastapi uvicorn

Step 3: Create the FastAPI Application#

Create a Python file (e.g., main.py) in the project directory.

main.py
from fastapi import FastAPI
# Create a FastAPI application instance
app = FastAPI()

This code imports the FastAPI class and creates an instance named app. This app instance will be the main object for defining the API.

Step 4: Define an Endpoint (Route)#

Add a route to handle incoming requests. This example creates a basic GET endpoint for the root URL (/).

main.py
from fastapi import FastAPI
app = FastAPI()
# Define a GET endpoint for the root URL "/"
@app.get("/")
async def read_root():
"""
Returns a simple greeting message.
"""
return {"message": "Hello World"}
  • @app.get("/"): This is a Python decorator that registers the function read_root to handle GET requests to the root URL (/). FastAPI provides similar decorators for other HTTP methods (@app.post, @app.put, @app.delete, etc.).
  • async def read_root():: Defines an asynchronous function. FastAPI functions can be synchronous or asynchronous, but using async def is recommended for potential performance benefits with I/O-bound operations.
  • return {"message": "Hello World"}: The function returns a Python dictionary. FastAPI automatically converts dictionaries and other Python objects into JSON format in the response body.

Step 5: Run the API#

Use Uvicorn to run the FastAPI application.

In the terminal (with the virtual environment active), execute:

Terminal window
uvicorn main:app --reload
  • uvicorn: The command to run the Uvicorn server.
  • main:app: Tells Uvicorn to find the FastAPI application instance named app inside the main.py file.
  • --reload: This flag enables auto-reloading. The server will restart automatically whenever code changes are saved, which is very useful during development.

The output will show the server starting, typically indicating it’s running on http://127.0.0.1:8000.

Step 6: Test the API and Explore Automatic Documentation#

Open a web browser or an API testing tool (like Postman or curl) and visit:

  • http://127.0.0.1:8000: This accesses the root endpoint defined in Step 4. The browser should display the JSON response: {"message": "Hello World"}.

FastAPI automatically generates interactive API documentation based on the code and type hints. Access the documentation at:

  • http://127.0.0.1:8000/docs: Provides interactive documentation using Swagger UI. This interface allows visualizing and interacting with the API endpoints directly from the browser.
  • http://127.0.0.1:8000/redoc: Provides alternative documentation using ReDoc.

The automatic documentation is a significant advantage, providing a clear, always-up-to-date reference for API consumers and developers.

Step 7: Add More Complex Endpoints#

Building API with FastAPI often involves handling dynamic data and input from clients.

Path Parameters#

Endpoints can capture values from the URL path.

# main.py (add to the existing code)
@app.get("/items/{item_id}")
async def read_item(item_id: int):
"""
Retrieves an item by its unique ID.
Args:
item_id: The unique identifier of the item (integer).
"""
return {"item_id": item_id}
  • {item_id} in the path defines a path parameter.
  • item_id: int in the function signature defines item_id as a parameter and uses a type hint (int). FastAPI automatically validates that the value captured from the URL is an integer.

Accessing http://127.0.0.1:8000/items/5 would return {"item_id": 5}. Accessing http://127.0.0.1:8000/items/abc would return a validation error, demonstrating FastAPI’s automatic data validation.

Request Body (POST Request)#

To send data to the API (e.g., creating a new resource), a request body is used, typically in JSON format for RESTful APIs. FastAPI leverages Pydantic for defining data models and handling request bodies.

First, install Pydantic (it’s a core FastAPI dependency, often installed with pip install fastapi but explicit import requires it):

Terminal window
# Already installed if you followed Step 2, but good to be aware
# pip install pydantic

Define a Pydantic model:

# main.py (add these imports and class)
from typing import Union
from pydantic import BaseModel
# Define a Pydantic model for an Item
class Item(BaseModel):
name: str
price: float
is_offer: Union[bool, None] = None # Optional field
  • BaseModel: Pydantic models inherit from this class.
  • Attributes (name, price, is_offer) define the expected fields in the request body.
  • Type hints (str, float, Union[bool, None]) define the data types and whether a field is optional. Pydantic provides powerful data validation and serialization based on these type hints.

Now, define a POST endpoint that accepts an Item in the request body:

# main.py (add this endpoint)
@app.post("/items/")
async def create_item(item: Item):
"""
Creates a new item.
Args:
item: The item data based on the Item Pydantic model.
"""
# In a real application, this would save the item to a database
# Returning the received item as confirmation
return item
  • @app.post("/items/"): Defines a POST endpoint at /items/.
  • item: Item: Defines a parameter named item with the type hint Item (the Pydantic model). FastAPI automatically reads the request body, validates it against the Item model using Pydantic, provides clear error messages if validation fails, and passes the validated data as an Item object to the function.

Using the automatic documentation (/docs), a user can see this new endpoint, the expected request body structure, and even test it by providing JSON data.

Practical Application: A Basic Task List API#

Consider building a simple API to manage a list of tasks. This demonstrates using GET for listing and POST for creating, leveraging the concepts covered.

While a real-world task list API would use a database, this example uses a simple in-memory list for demonstration.

# tasks_api.py (Example file)
from typing import List
from pydantic import BaseModel
from fastapi import FastAPI
app = FastAPI()
# Pydantic model for a Task
class Task(BaseModel):
title: str
description: str = None
completed: bool = False
# In-memory storage for tasks
tasks_db = []
next_task_id = 1
@app.get("/tasks/", response_model=List[Task])
async def get_tasks():
"""
Retrieves the list of all tasks.
"""
return tasks_db
@app.post("/tasks/", response_model=Task, status_code=201) # Use 201 for creation success
async def create_task(task: Task):
"""
Creates a new task.
"""
global next_task_id
# Add a simple ID (simulating database ID)
task_with_id = task.dict() # Convert Pydantic model to dictionary
task_with_id["id"] = next_task_id
next_task_id += 1
tasks_db.append(task_with_id) # Store the dict
return task_with_id # Return the created task
# Example: Get a specific task by ID (would need search logic if using list)
# @app.get("/tasks/{task_id}", response_model=Task)
# async def get_task(task_id: int):
# # Implement logic to find task by ID in tasks_db
# pass # For brevity

To run this example:

  1. Save the code as tasks_api.py.
  2. Activate the virtual environment.
  3. Run: uvicorn tasks_api:app --reload.
  4. Access http://127.0.0.1:8000/docs to interact with the /tasks/ endpoints.
    • Using the POST /tasks/ endpoint with a request body like {"title": "Learn FastAPI", "description": "Complete the tutorial"} will add a task.
    • Using the GET /tasks/ endpoint will retrieve the current list of tasks.

This basic example demonstrates how to define models, handle request bodies, manage in-memory data (as a placeholder for database interaction), and return structured responses, illustrating the practical aspects of building API with FastAPI for fundamental operations.

Key Takeaways#

  • Building API with FastAPI leverages Python’s simplicity and performance.
  • FastAPI provides automatic data validation (using Pydantic) and interactive API documentation (Swagger UI, ReDoc), significantly speeding up development and improving clarity.
  • HTTP methods (GET, POST, PUT, DELETE) define the actions performed on API resources.
  • Endpoints are specific URLs where API functions are accessible.
  • Path parameters and request bodies are used to send data to the API.
  • Pydantic models define the structure and data types of request bodies and responses, enabling automatic validation and serialization.
  • Running the API typically involves an ASGI server like Uvicorn.
  • Virtual environments are essential for managing project dependencies.
Building an API with FastAPI| A Step-by-Step Tutorial for Beginners
https://dev-resources.site/posts/building-an-api-with-fastapi-a-stepbystep-tutorial-for-beginners/
Author
Dev-Resources
Published at
2025-06-26
License
CC BY-NC-SA 4.0