This project demonstrates the use of FastAPI to build a REST API for managing users and their personal contacts. Project is built with SQLAlchemy ORM for relational PostgreSQL database operations, Alembic for schema migrations, and other technologies. It is packed inside of Docker container and uses Redis for caching and Cloudinary to store image files.
The main goal for the app is to store and manage user contacts.
- JWT-based authentication
- User email verification
- Role-based access control (USER / MODERATOR / ADMIN / SUPERADMIN)
- Full CRUD for contacts (user-isolated)
- Redis caching (contacts, users, counters)
- Rate limiting for sensitive endpoints
- Avatar upload via Cloudinary
- Dockerized dev & prod environments
The project follows a layered architecture:
- API layer (FastAPI routers)
- Service layer (business logic, validation, permissions)
- Repository layer (SQLAlchemy ORM)
- Providers (cache, external services, email, avatars)
- DTOs for data transfer
- Centralized domain event logging
- Key Features
- Architecture Overview
- Task Requirements
- Task Solution
- License
Create a REST API for storing and managing personal contacts. The API must be built with FastAPI and use SQLAlchemy to work with a database.
Design a database to store contact information.
Each contact record must include:
- First name
- Last name
- Email address
- Phone number
- Birthday
- Additional information (optional)
Develop an API, that should support basic data operations.
It must support following functions and provide endpoints to:
- Create a new contact
- Retrieve a list of all contacts
- Retrieve a single contact by its ID
- Update an existing contact
- Delete a contact
In addition to standard CRUD operations, the API must also:
- Allow searching contacts by first name, last name, or email using query parameters.
- Provide an endpoint to retrieve contacts who have birthdays within the next 7 days.
- Use FastAPI to implement the REST API.
- Use SQLAlchemy ORM for database operations.
- Use PostgreSQL as the database.
- Support CRUD operations for contacts.
- Store each contact's birthday.
- Expose Swagger documentation for the REST API.
- Validate request data with Pydantic models.
- Implement user authentication using JWT tokens (all operations with contacts are available for authenticated users only).
- Use has access for their own contacts and operations with those contacts.
- Implement user email verification for registered users.
- Limit number of requests to the
/meroute. - Turn on CORS for the REST API.
- Implement possibility of avatar update (user Cloudinary service).
The solution consists of a PostgreSQL database running in a Docker container, a FastAPI server for handling HTTP API requests and managing contacts in the database, and Swagger/OpenAPI documentation that describes all available endpoints and allows you to try out requests directly from the documentation.
This guide will help you set up the environment and run the project.
Before you begin, make sure you have the following installed:
- Python 3.12.* (tested with Python 3.12.3) — Required to run the application locally.
- Poetry - To manage dependencies in virtual environment.
- Docker using PostgreSQL (tested with PostgreSQL 17.5) — Used to containerize the application in a unified environment using Docker or Docker Compose.
- Email that allows you to send messages using API calls (meta.ua was used and test for this build as a practical example, but it may be other as meta.ua requires ukrainian mobile phone number)
- Registered account at cloudinary and its API keys.
- Optional - for local development:
- Clone repository:
or download the ZIP archive from GitHub Repository and extract it.
git clone https://github.com/oleksandr-romashko/goit-pythonweb-hw-10.git cd goit-pythonweb-hw-10 - Install project dependencies:
poetry install
The application requires several environment variables to operate correctly.
Note on Production environment
In production, environment variables and secrets must be provided externally (e.g., GitHub Actions, Docker environment variables, deployment platform, etc.). The application in production does not load .env files.
Development environment
For local development, copy .env.example → .env.
This file contains all required configuration values.
Some variables have mandatory validation (mostly security-related).
If left with their default placeholder values, the application will refuse to start (see ./src/config/app_config.py for more information on required variables).
These mandatory variables include:
"AUTH_JWT_SECRET"
"CACHE_PASSWORD"
"DB_ADMIN_USER"
"DB_ADMIN_USER_PASSWORD"
"DB_APP_USER_PASSWORD"
"DB_ADMIN_PANEL_PASSWORD"
"MAIL_JWT_SECRET"
"MAIL_USERNAME"
"MAIL_PASSWORD"
"CLOUDINARY_NAME"
"CLOUDINARY_API_KEY"
"CLOUDINARY_API_SECRET"
When such variables contain invalid/default values, the application will print detailed log messages describing which variable must be fixed. Check the api service container logs for guidance.
Our app solution uses Docker to run our app and other necessary services in a Docker compose environment. That includes:
- Our FastApi api application
- Redis cache service
- Postgres database
- PgAdmin to access database
We may use makefile to build and run our environment in Docker.
- For the production setup run this command while in the project root directory:
make prod - or for the development setup run other command:
make devDev environment allows additional features:- auto-reload of the app upon code changes while develop
- extra details on errors as part of response and
debugerror logging level - extra http header with processing time of the request handling
- CORS allows all origins
- database and cache ports are exposed and accessible from outside of compose environment
- Compose run not in daemon mode
In prod environment you won't have direct access to the application database or cache services. However in dev environment respective ports will be forwarded and you may access them directly.
Before we may start our FastAPI application it is wise to check our application settings. Check your .env file and change FastApi application settings if necessary.
Then start FastApi application by using following command:
make devThis will start application and it will be accessible at http://0.0.0.0:8000 (depending on your WEB_PORT settings).
You may access Swagger API documentation at http://0.0.0.0:8000/docs and make API requests from there.
Example API Request
POST /api/auth/register
Content-Type: application/json
{
"username": "john_doe",
"email": "john@example.com",
"password": "strong_password"
}Happy coding!
This project is licensed under the MIT License. You are free to use, modify, and distribute this software in accordance with the terms of the license.
