A robust Chat REST API built with FastAPI, following the Domain-Driven Design (DDD) pattern. This project is containerized using Docker, employs GitHub Actions for continuous integration, integrates Loki for centralized logging, and utilizes a Makefile for streamlined project management.
- FastAPI: High-performance web framework for building APIs with Python 3.13.
- Domain-Driven Design (DDD): Structured approach to software design that emphasizes domain modeling.
- MongoDB & Mongo Express: NoSQL database for storing chat data, with a web-based MongoDB admin interface.
- Nginx: Reverse proxy server for handling client requests.
- Loki: Centralized logging system integrated for log aggregation and monitoring.
- Pre-commit Hooks: Code quality tools including flake8, autoflake, add-trailing-comma, and isort.
- Mypy: Static type checker for Python.
- GitHub Actions: Automated workflows for testing and formatting on each push and pull request.
- Docker & Docker Compose: Containerization for easy setup and deployment.
- Makefile: Simplifies common tasks such as setup, testing, and running the application.
- Optimized Docker Image: Reduced FastAPI Docker image size from 700MB to 205MB for development container and 185MB for production container by implementing multi-stage builds.
Note: Each service (loggers, servers, app, storages) is configured in its own Docker Compose file. This modular setup ensures optimal performance and easier troubleshooting, reducing potential conflicts.
- Getting Started
- Makefile Commands
- Docker
- Project Structure
- Health Check Endpoint
- API Endpoints
- Testing
- Contributing
- License
Ensure you have the following installed:
- Docker
- Makefile Execution Requirements: Ensure that
makeis installed on your system. Most UNIX-like systems have it pre-installed.
-
Clone the Repository:
git clone https://github.com/abstract-333/chat-api.git cd chat-api -
Set Up Environment Variables:
Copy the example environment variables file and modify as needed:
cp .env.example .env
-
Run Make Commands:
It will start the app, just FastAPI application:
make app
The project includes a Makefile for simplified management. Refer to the Makefile Commands
section for details.
The Makefile provides a set of commands to manage and run various parts of the application:
-
Start All Services - Development:
make all
Starts the application, storages, server, and loggers in development mode.
-
Start All Services - Production:
make all-prod
Starts the application, storages, server, and loggers in production mode.
-
Start Only the Application - Development:
make app
Starts the main application container - FastAPI in development mode.
-
Start Only the Application - Production:
make app-prod
Starts the main application container - FastAPI in production mode.
-
Start the Server:
make server
Starts the Nginx server, which serves as a reverse proxy.
-
Start Storages:
make storages
Starts MongoDB and Mongo Express. Mongo Express can be accessed at http://localhost:28081.
-
Start Storages Without Admin Interface - MongoExpress:
make storages-pure
Starts only MongoDB.
-
Start Loggers:
make loggers
Builds and starts Loki and Grafana for centralized logging and monitoring.
-
Stop the Application - Development:
make app-down
Stops the application container.
-
Stop the Application - Production:
make app-prod-down
Stops the application container.
-
Stop the Server:
make server-down
Stops the Nginx server.
-
Stop Loggers:
make loggers-down
Stops Loki and Grafana.
-
Stop Storages:
make storages-down
Stops MongoDB and Mongo Express without erasing data.
-
Stop Storages:
make storages-pure-down
Stops MongoDB without erasing data.
-
Stop All Services - Development:
make all-down
Stops all running services.
-
Stop All Services - Production:
make all-prod-down
Stops all running services.
-
View Application Logs:
make app-logs
Displays logs from the application container.
-
Run Tests:
make testExecutes the test suite.
This project includes Docker configurations for both development and production environments. The Docker images
are built using two different Dockerfiles, dev.Dockerfile for development and prod.Dockerfile for production, with
the configuration driven by environment variables defined in .env files.
-
prod.Dockerfile: Used for building the Docker image in the production environment. It runs with Gunicorn and UvicornWorker for handling multiple requests efficiently in a production setting. No file watching or reloading is enabled. This environment only includes the production dependencies, ensuring a minimal and optimized setup for performance. -
dev.Dockerfile: Used for building the Docker image in the development environment. It runs with Uvicorn in reload mode and is configured to watch file changes, making it suitable for active development. In this environment, development dependencies (including testing tools likepytest) are installed, allowing you to run tests and develop in an interactive manner.
- The environment files (
.env,.env.prod) are used to provide dynamic configuration based on the environment.
-
make app-prod: Builds and runs the production environment by using.env.prodfor configuration. The app will run with Gunicorn( without reloading or volume watching) to handle production-level traffic. It uses only production dependencies, ensuring a lightweight and optimized container.make app-prod
-
make app: Builds and runs the development environment by using.envfor configuration. The app will run with Uvicorn in reload mode, allowing live code reloading and volume watching for a smoother development experience. In this environment, development dependencies are installed, including tools likepytestfor testing purposes. This setup allows you to perform tests within the development container, not in production.make app
π¦ chat-api
βββ π .github
β βββ π workflows
β βββ π ci.yml # GitHub Actions CI workflow
βββ π app
β βββ π application
β βββ π domain
β βββ π infra
β βββ π logic
β βββ π settings
β βββ π tests
β βββ π utils
βββ π config
β βββ π loki-config.yaml # Configuration for Loki logger
β βββ π nginx.yaml # Configuration for Nginx logger
β βββ π protmail-config.yaml # Configuration for Protmail logger
βββ π docker_compose
β βββ π app.yaml # Main App
β βββ π loggers.yml # Loggers - Protmail, Granafa and Loki
β βββ π server.yml # Proxy Server - Nginx
β βββ π storages.yml # Storages - Mongo DB
β βββ π storages_ui.yml # Storages Admin Interface - Mongo Express
.
.
.
βββ π .pre-commit-config.yaml # Pre-commit hooks configuration
βββ π Dockerfile
βββ π Makefile
βββ π mypy.ini # MyPy configuration
βββ π pyproject.toml # Python project configuration
βββ π ruff.toml # Ruff linter configuration
βββ π uv.lock # UV dependency lock file
The application includes a health check endpoint to monitor the system's overall status, specifically the health of the MongoDB connection. The health check is provided through a dedicated router, which can be queried to determine whether the system and MongoDB are running properly.
- Method:
GET - Tags: Health
- Response Model:
HealthOut(custom schema for structured health check response) - Description: This endpoint performs a system-wide health check, including verifying MongoDB's availability by attempting to ping the database.
- The health check route is defined in the
Healthrouter. - The system attempts to ping MongoDB using the
mongo_db_clientto ensure that the database is up and running. - If MongoDB responds successfully, the status is considered healthy, and the system will return a
healthystatus with detailed MongoDB health info. - If MongoDB is not available or an error occurs during the ping, the system will return a status indicating that MongoDB is down and provide the error details.
{
"status": "healthy",
"detail": {
"mongodb": "Ok"
}
}If MongoDB is unavailable:
{
"status": "MongoDB is down",
"detail": {
"mongodb": "error: <error_message>"
}
}- This endpoint can be used to monitor the health of the application, especially MongoDB.
- Typically, it can be integrated into monitoring tools or queried periodically to ensure the system is functioning correctly.
This endpoint ensures that the core components of your system are functioning and allows for efficient monitoring and troubleshooting.
The Chat API provides the following endpoints:
- Chats:
POST /chat/: Create a new chat.POST /chat/{chat_oid}/message: Send a message in a chat.
- Health:
Get /Health/: health check.
For detailed request and response schemas, refer to the API Documentation.
The project includes extensive testing capabilities, designed to validate business logic independently of the database. This ensures that core functionalities can be tested efficiently without requiring a connection to MongoDB or other external services.
- Unit Tests: Focused on individual components, testing business logic in isolation.
- Integration Tests: Verify that different parts of the system work together as expected.
- Database-Free Testing: The architecture allows for testing business logic independently of the database. Mocking or in-memory databases can be used to simulate data operations.
Run the test suite with:
make testEnsure that all tests pass before committing new code.
Contributions are welcome! Please follow these steps:
-
Fork the Repository: Click the 'Fork' button at the top right of this page.
-
Clone Your Fork:
git clone https://github.com/your-username/chat-api.git cd chat-api -
Create a Branch:
git checkout -b feature/your-feature-name
-
Make Changes: Implement your feature or bug fix.
-
Run Tests: Ensure all tests pass.
-
Commit Changes:
git commit -m "Add feature: your feature name" -
Push to GitHub:
git push origin feature/your-feature-name
-
Create a Pull Request: Navigate to your fork on GitHub and create a pull request to the main repository.
This project is licensed under the MIT License. See the LICENSE file for details.