This project is a RESTful API built with FastAPI for managing a book collection. It provides comprehensive CRUD (Create, Read, Update, Delete) operations for books with proper error handling, input validation, and documentation.
It includes CI/CD setup for testing and deplyment using Nginx as a reverse proxy.
- π Book management (CRUD operations)
- β Input validation using Pydantic models
- π Enum-based genre classification
- π§ͺ Complete test coverage
- π API documentation (auto-generated by FastAPI)
- π CORS middleware enabled
fastapi-book-project/
βββ api/
β βββ db/
β β βββ __init__.py
β β βββ schemas.py # Data models and in-memory database
β βββ routes/
β β βββ __init__.py
β β βββ books.py # Book route handlers
β βββ router.py # API router configuration
βββ core/
β βββ __init__.py
β βββ config.py # Application settings
βββ tests/
β βββ __init__.py
β βββ test_books.py # API endpoint tests
βββ main.py # Application entry point
βββ requirements.txt # Project dependencies
βββ README.md
- Python 3.12
- FastAPI
- Pydantic
- pytest
- uvicorn
- Clone the repository:
git clone https://github.com/hng12-kehindebello/fastapi-book-project.git
cd fastapi-book-project- Create a virtual environment:
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate- Install dependencies:
pip install -r requirements.txt- Start the server:
uvicorn main:app- Access the API documentation:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
GET /api/v1/books/- Get all booksGET /api/v1/books/{book_id}- Get a specific bookPOST /api/v1/books/- Create a new bookPUT /api/v1/books/{book_id}- Update a bookDELETE /api/v1/books/{book_id}- Delete a book
GET /healthcheck- Check API status
{
"id": 1,
"title": "Book Title",
"author": "Author Name",
"publication_year": 2024,
"genre": "Fantasy"
}Available genres:
- Science Fiction
- Fantasy
- Horror
- Mystery
- Romance
- Thriller
pytestThe API includes proper error handling for:
- Non-existent books
- Invalid book IDs
- Invalid genre types
- Malformed requests
The CI/CD pipeline is configured to:
- Run tests on pull requests to
main - Deploy the app on merging into
main
Create a .github/workflows folder and add the following as test.yml file
Trigger: Runs on pull requests to main
name: test
on:
pull_request:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: '3.'
- name: Install dependencies
run: |
pip install -r requirements.txt
- name: Run tests
run: pytest- Launch an Ubuntu 22.04 EC2 instance
- Allow inbound rules for HTTP (80), HTTPS (443), and SSH (22)
- In the EC2 Dashboard on the AWS Portal, select Instances from the left panel.
- Find the instance you want to connect to and select it.
- Click the Connect button at the top.
- Choose the EC2 Instance Connect tab.
- Click Connect β a terminal will open in your browser. You are now connected to your EC2 instance.
sudo apt update && sudo apt install -y python3-pip nginxgit clone https://github.com/your-username/fastapi-book-project.git
cd fastapi-book-project
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtCreate an Nginx configuration file:
sudo nano /etc/nginx/sites-available/fastapiAdd the following content:
server {
listen 80;
server_name your-ec2-ip ec2-your-public-dns.amazonaws.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}Save and link the config:
sudo ln -s /etc/nginx/sites-available/fastapi /etc/nginx/sites-enabled/
sudo systemctl restart nginxsudo nano /etc/systemd/system/fastapi.serviceAdd:
[Unit]
Description=FastAPI app
After=network.target
[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/fastapi-book-project
ExecStart=/home/ubuntu/fastapi-book-project/venv/bin/uvicorn main:app --host 0.0.0.0 --port 8000
Restart=always
[Install]
WantedBy=multi-user.targetEnable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable fastapi
sudo systemctl start fastapiIn your GitHub repository, configure the following secrets:
EC2_HOST: Public IP or domain of your EC2 instanceEC2_SSH_KEY: Private SSH key for accessing the EC2 instance
In your .github/workflows folder add the following as deploy.yml file
Trigger: Runs on merging to main
name: deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Deploy to EC2
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /home/ubuntu/fastapi-book-project
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
sudo systemctl restart nginx
sudo systemctl restart fastapi.serviceOnce you've merged all your code changes to the main branch, your application should successfully deploy after a short while and you can access it as follows;
Base URL:
http://your-ec2-ip
http://ec2-your-public-dns.amazonaws.com
Test an endpoint:
http://ec2-your-public-dns.amazonaws.com/api/v1/books/1
You have successfully set up and deployed a FastAPI application with CI/CD on AWS EC2 and configured Nginx as a reverse proxy. π