Capstone Project - Blog Posts API
Problem Statement In this capstone project, you will develop a REST API to manage blog posts. Each blog post contains:- ID
- Title
- Description
- Author
- Created At
- Create a Post
- View All Posts
- View a Post
- Update a Post
- Delete a Post
Learning Objectives
After completing this project, you will be able to:- Build RESTful APIs using FastAPI.
- Organize applications using a modular project structure.
- Configure SQLite with SQLAlchemy ORM.
- Design database models using SQLAlchemy.
- Validate requests and responses using Pydantic Schemas.
- Implement database session dependencies.
- Handle data persistence using CRUD routines.
- Manage database schema changes using Alembic migrations.
- Migrate database engines from SQLite to PostgreSQL.
Step 1: Create the Project
Objective Create a new project directory and prepare the development environment. Instructions- Create a new project directory named
blog-api. - Navigate to the project directory.
- Initialize the project using uv.
Solution
Solution
- The project directory has been created.
- A
pyproject.tomlfile has been generated.
Step 2: Create a Virtual Environment
Objective Initialize and activate a virtual environment to isolate project dependencies. Instructions- Create the virtual environment using
uv venv. - Activate the virtual environment based on your operating system.
Solution
Solution
Create the virtual environmentActivate the virtual environmentFor Windows:For macOS / Linux:
- The virtual environment folder
.venvis created. - The command prompt is updated, indicating the virtual environment is active.
Step 3: Install Required Packages
Objective Install all the libraries required to build the Blog Posts API. Instructions- Install
fastapi,uvicorn[standard], andsqlalchemyusing uv.
Solution
Solution
- All packages are installed successfully.
- The
pyproject.tomlfile contains the installed dependencies.
Step 4: Create the Project Structure
Objective Organize the application into a modular structure to separate concerns. Instructions- Create the following folder structure to house files like API routes, models, schemas, and helpers.
Solution
Solution
- The
app/folder is initialized. - Subdirectories and placeholders for modular code are created.
Step 5: Configure the Database
Objective Configure SQLAlchemy so the application can communicate with the database. Instructions- Define the
DATABASE_URLto point to a SQLite file namedblog.db. - Initialize the SQLAlchemy engine and configure the Session factory.
- Define the Declarative Base class
Base.
Solution
Solution
File:
app/database.py- The database module compiles cleanly.
SessionLocalis set up to issue database connections.
Step 6: Create the Blog ORM Model
Objective Define the structure of theposts table using a SQLAlchemy model class.
Instructions
- Create a
Postclass inapp/models.pythat inherits fromBase. - Declare Mapped types for columns:
id,title,description,author, andcreated_at.
Solution
Solution
File:
app/models.py- Column types map appropriately to target values (e.g.
String(200)andText). - The imports reference the database base configuration module correctly.
Step 7: Create the Database Tables
Objective Generate the SQLite database and create theposts table during application startup.
Instructions
- Set up
app/main.py. - Import the database metadata and initialize the tables using
Base.metadata.create_all.
Solution
Solution
File:
app/main.py- Start the application using:
- Confirm that
blog.dbhas been created in your root workspace folder and contains thepoststable.
Step 8: Create the Pydantic Schemas
Objective Define data schemas using Pydantic models to validate API requests and serialize responses. Instructions- Define
PostBasewith common attributes. - Inherit from it to create
PostRequestandPostResponseschemas. - Turn on
from_attributesinside response models for direct ORM serialization.
Solution
Solution
File:
app/schemas.py- The schema schemas are correctly configured.
from_attributesmatches compatibility rules for SQLAlchemy queries.
Step 9: Implement the Database Dependency
Objective Expose a reusable database session dependency that manages session lifecycles automatically. Instructions- Create
app/dependencies.py. - Implement
get_dbyielding a database session and safely closing it when finished.
Solution
Solution
File:
app/dependencies.py- The generator function closes connections even if an exception occurs during request execution.
Step 10: Implement the CRUD Layer
Objective Write standard data access functions using SQLAlchemy ORM queries for the posts. Instructions- Define functions for: creating, updating, retrieving (all/single), and deleting posts.
- Use the modern SQLAlchemy 2.0 select statement for reading queries.
Solution
Solution
File:
app/crud.py- All functions compile without syntax errors.
- Query statements call correct filter rules.
Step 11: Register the Router
Objective Create the router layer endpoints and link it to the main FastAPI application. Instructions- Build API endpoint handlers in
app/api/posts.pyusingAPIRouter. - Use modern
Annotatedsyntax to inject database sessions. - Mount the router on the FastAPI application instance in
app/main.py.
Solution
Solution
File: File:
app/api/posts.pyapp/main.py- Endpoint handlers map correctly to HTTP verbs.
- Routing endpoints return expected status codes.
Step 12: Run & Verify the APIs
Objective Validate the REST API endpoints using the interactive documentation page. Instructions- Start the application server.
- Navigate to the Swagger UI page in your browser.
- Perform tests for all HTTP operations.
Solution
Solution
Start the server:Open interactive docs page:Verify following payloadsPOST Request Body:PUT Request Body:
- POST requests yield HTTP 200 with auto-generated id.
- Invalid requests (e.g. referencing a missing ID) yield HTTP 404.
Step 13: Configure Alembic
Objective Initialize Alembic migration environment to track future database changes. Instructions- Install
alembicpackage. - Initialize migration files layout.
- Bind the engine configuration URL and project Base model metadata inside Alembic scripts.
Solution
Solution
Install Alembic package:Initialize Alembic folders:File: File:
alembic.inialembic/env.py- Alembic successfully reads target metadata configuration.
- The
alembicsubdirectory and its files are initialized.
Step 14: Create Database Migrations
Objective Generate database migrations scripts and upgrade the SQLite structure. Instructions- Use revision
--autogenerateto compare model metadata against SQLite file. - Perform upgrade to sync the database version.
Solution
Solution
Generate migration version script:Apply migrations:
- Version files are added to
alembic/versions/. alembic_versiontracking table is created inside SQLite database.
Step 15: Switch to PostgreSQL
Objective Transition the database system settings from SQLite to PostgreSQL engine. Instructions- Add psycopg binary database driver.
- Adjust
DATABASE_URLconfigurations. - Update settings in both
app/database.pyandalembic.ini.
Solution
Solution
Install driver:File: File: Sync database scheme:
app/database.pyalembic.ini- PostgreSQL connects without errors.
- Alembic tables are created on the target PostgreSQL server instance.