Creating a REST API using FastAPI Python is no longer a trending but very common practice among developers today. FastAPI Python boasts speed, simplicity, and latest technologies that make working with APIs simpler for everyone. Whether it is an app, service integration, or developing a web backend, learning FastAPI for creating a REST API expands your horizons.
FastAPI is a high-performance Python framework for building APIs. It uses Python type hints. That means you get automatic data validation and interactive documentation for free. That makes it great for beginners as well as for experienced programmers. This tutorial on fastapi python for beginners will walk you through all these steps. You will learn to structure your project, endpoints, and then learn data handling. At the end, you will be able to develop your own working API.
Project Setup
Before we create RESTful API using FastAPI Python, we need to prepare our development environment. Follow these simple steps to get started. Before we create RESTful API using FastAPI Python, we need to prepare our development environment.
Create a Project Directory
Create a new folder for your project. This keeps your files organised and easy to manage.
mkdir fastapi-rest-api
cd fastapi-rest-api
Set Up a Virtual Environment
A virtual environment keeps your project dependencies separate from other projects. This prevents conflicts and keeps things clean.
// Ubuntu
python -m venv venv
source venv/bin/activate
//Windows
venv\Scripts\activate
It will setup virtual environment for your dependancies.
Install FastAPI and Uvicorn
Next thing, we need to do is to install FastAPI with Uvicorn. FastAPI needs an ASGI server to run. Uvicorn is a lightning-fast option that works perfectly with FastAPI.
Open terminal and enter below command to install:
pip install fastapi uvicorn pydantic
Project Structure
Before writing code, let us organise our project properly. A clean structure makes your code easier to maintain and scale. Create the following files and folders in your project directory.
fastapi-rest-api/
├── venv/
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── models.py
│ ├── database.py
│ └── routes/
│ ├── __init__.py
│ └── post.py
Building Your First REST API with Practical Example
Now let’s move to the exciting part. We will build REST API with FastAPI from scratch using a real-world scenario. Imagine you are building a simple blog platform that needs to manage posts. This python fastapi api example step by step shows you the complete process with organised code.
Creating the Data Model
Open app/models.py and define how a blog post looks in your system. Pydantic handles data validation automatically which saves you from writing extra code.
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
class PostBase(BaseModel):
title: str
content: str
author: str
published: Optional[bool] = False
class PostCreate(PostBase):
pass
class PostUpdate(BaseModel):
title: Optional[str] = None
content: Optional[str] = None
author: Optional[str] = None
published: Optional[bool] = None
class PostResponse(PostBase):
id: int
created_at: str
class Config:
from_attributes = True
We created four model classes here. The PostBase class contains common fields. The PostCreate class handles new post creation. The PostUpdate class allows partial updates. The PostResponse class defines what data users receive back.
Setting Up the Database
For this tutorial, we use a simple in-memory storage. Open app/database.py and add the following code.
from datetime import datetime
class Database:
def __init__(self):
self.posts = {}
self.counter = 0
def get_all_posts(self):
return list(self.posts.values())
def get_post_by_id(self, post_id: int):
return self.posts.get(post_id)
def create_post(self, post_data: dict):
self.counter += 1
post = {
"id": self.counter,
"title": post_data["title"],
"content": post_data["content"],
"author": post_data["author"],
"published": post_data.get("published", False),
"created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
self.posts[self.counter] = post
return post
def update_post(self, post_id: int, post_data: dict):
if post_id not in self.posts:
return None
existing_post = self.posts[post_id]
for key, value in post_data.items():
if value is not None:
existing_post[key] = value
return existing_post
def delete_post(self, post_id: int):
if post_id in self.posts:
del self.posts[post_id]
return True
return False
db = Database()
The Database class provides methods for all CRUD operations. CRUD stands for Create, Read, Update, and Delete. These are the four basic operations every API needs. We create a single instance called db at the bottom. This instance stays alive as long as your server runs. In production applications, you would replace this with a real database like PostgreSQL or MongoDB.
Creating Post Routes
Now let us create the API endpoints. Open app/routes/post.py and add the following code.
from fastapi import APIRouter, HTTPException, status
from typing import List
from app.models import PostCreate, PostUpdate, PostResponse
from app.database import db
router = APIRouter(prefix="/posts", tags=["Posts"])
@router.get("/", response_model=List[dict])
def get_all_posts():
posts = db.get_all_posts()
return posts
@router.get("/{post_id}")
def get_single_post(post_id: int):
post = db.get_post_by_id(post_id)
if not post:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Post with id {post_id} not found"
)
return post
@router.post("/", status_code=status.HTTP_201_CREATED)
def create_new_post(post: PostCreate):
post_data = post.model_dump()
new_post = db.create_post(post_data)
return {
"message": "Post created successfully",
"post": new_post
}
@router.put("/{post_id}")
def update_existing_post(post_id: int, post: PostUpdate):
post_data = post.model_dump(exclude_unset=True)
updated_post = db.update_post(post_id, post_data)
if not updated_post:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Post with id {post_id} not found"
)
return {
"message": "Post updated successfully",
"post": updated_post
}
@router.delete("/{post_id}", status_code=status.HTTP_200_OK)
def delete_existing_post(post_id: int):
success = db.delete_post(post_id)
if not success:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Post with id {post_id} not found"
)
return {"message": "Post deleted successfully"}
We use APIRouter to group related endpoints together. The prefix /posts applies to all routes in this file. Tags help organise the documentation. Each endpoint handles a specific task. The GET endpoints fetch data. The POST endpoint creates new posts. The PUT endpoint updates existing posts. The DELETE endpoint removes posts from the system.
Creating the Main Application
At Last, let’s connect everything together. Open app/main.py and modify as below.
from fastapi import FastAPI
from app.routes import post
app = FastAPI(
title="Blog Post API",
description="A simple REST API for managing blog posts",
version="1.0.0"
)
app.include_router(post.router)
@app.get("/")
def read_root():
return {
"message": "Welcome to the Blog Post API",
"documentation": "/docs",
"endpoints": {
"posts": "/posts"
}
}
@app.get("/health")
def health_check():
return {"status": "healthy"}
The include_router method adds all post routes to your application. You can add more routers as your API grows. This keeps your main file clean and manageable. We also added a health check endpoint. This is useful for monitoring your API in production environments.
Running and Testing Your API
Start your server with Uvicorn from the project root directory.
uvicorn app.main:app --reload
Visit http://127.0.0.1:8000 to see the welcome message. Now all endpoints like /health for health check and /posts for getting all posts.
Conclusion
You have successfully attained the skills required to develop a REST API with FastAPI. All these have been done without using third-party tools. FastAPI simplifies and makes all these processes enjoyable and easy. It undertakes a variety of complex operations on your behalf. Automatic data validation, error handling, and generation of documentation occur. You will save on coding time and error considerations.
You can then extend your API in a number of ways. Include functionality for connecting your database. Create an authentication system so that your endpoints are secure. You can include more complicated business logics.
