0.8.0
0.8.0 Summary
🚀Features
- NGINX deployment🎉
- Better Custom Exceptions
- Core Folder Restructured
📝Docs
0. 🚀Core Folder Restructured
Old core folder structure:
├── core # Core utilities and configurations for the application.
│ │ ├── __init__.py
│ │ ├── cache.py # Utilities related to caching.
│ │ ├── config.py # Application configuration settings.
│ │ ├── database.py # Database connectivity and session management.
│ │ ├── exceptions.py # Contains core custom exceptions for the application.
│ │ ├── logger.py # Logging utilities.
│ │ ├── models.py # Base models for the application.
│ │ ├── queue.py # Utilities related to task queues.
│ │ ├── rate_limit.py # Rate limiting utilities and configurations.
│ │ ├── security.py # Security utilities like password hashing and token generation.
│ │ └── setup.py # File defining settings and FastAPI application instance definition.
New structure:
├── core # Core utilities and configurations for the application.
│ ├── __init__.py
│ ├── config.py # Configuration settings for the application.
│ ├── logger.py # Configuration for application logging.
│ ├── schemas.py # Pydantic schemas for data validation.
│ ├── security.py # Security utilities, such as password hashing.
│ ├── setup.py # Setup file for the FastAPI app instance.
│ │
│ ├── db # Core Database related modules.
│ │ ├── __init__.py
│ │ ├── crud_token_blacklist.py # CRUD operations for token blacklist.
│ │ ├── database.py # Database connectivity and session management.
│ │ ├── models.py # Core Database models.
│ │ └── token_blacklist.py # Model for token blacklist functionality.
│ │
│ ├── exceptions # Custom exception classes.
│ │ ├── __init__.py
│ │ └── ...
│ │
│ └── utils # Utility functions and helpers.
│ ├── __init__.py
│ ├── cache.py # Cache-related utilities.
│ ├── queue.py # Utilities for task queue management.
│ └── rate_limit.py # Rate limiting utilities.
A few relevant notes:
- Token_blacklist model, schemas and crud were were moved to the core folder.
- Mixins are now defined as both pydantic schemas and sqlalchemy models
1. ⚡️Better Custom Exceptions
Exception handling was restructured.
Old exceptions structure:
├── app # Main application directory.
├── ...
│
├── api # Folder containing API-related logic.
│ ├── ...
│ ├── exceptions.py # Custom exceptions for the API.
│
├── core # Core utilities and configurations for the application.
│ ├── ...
│ │
│ ├── exceptions # Custom exception classes.
│ │ ├── __init__.py
│ │ └── exceptions.py # Definitions of custom exceptions.
New structure:
├── app # Main application directory.
├── ...
│
├── core # Core utilities and configurations for the application.
│ ├── ...
│ │
│ ├── exceptions # Custom exception classes.
│ │ ├── __init__.py
│ │ ├── cache_exceptions.py # Exceptions related to cache operations.
│ │ └── http_exceptions.py # HTTP-related exceptions.
Now to use http exceptions you may just import from app/core/exceptions/http_exceptions
and optionally add a detail:
from app.core.exceptions.http_exceptions import NotFoundException
# If you want to specify the detail, just add the message
if not user:
raise NotFoundException("User not found")
# Or you may just use the default message
if not post:
raise NotFoundException()
The predefined possibilities in http_exceptions are the following:
CustomException
: 500 internal errorBadRequestException
: 400 bad requestNotFoundException
: 404 not foundForbiddenException
: 403 forbiddenUnauthorizedException
: 401 unauthorizedUnprocessableEntityException
: 422 unprocessable entityDuplicateValueException
: 422 unprocessable entityRateLimitException
: 429 too many requests
2. 🎉NGINX deployment
NGINX is a high-performance web server, known for its stability, rich feature set, simple configuration, and low resource consumption. NGINX acts as a reverse proxy, that is, it receives client requests, forwards them to the FastAPI server (running via Uvicorn or Gunicorn), and then passes the responses back to the clients.
To run with NGINX, you start by uncommenting the following part in your docker-compose.yml
:
# docker-compose.yml
...
# #-------- uncomment to run with nginx --------
# nginx:
# image: nginx:latest
# ports:
# - "80:80"
# volumes:
# - ./default.conf:/etc/nginx/conf.d/default.conf
# depends_on:
# - web
...
Which should be changed to:
# docker-compose.yml
...
#-------- uncomment to run with nginx --------
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./default.conf:/etc/nginx/conf.d/default.conf
depends_on:
- web
...
Then comment the following part:
# docker-compose.yml
services:
web:
...
# -------- Both of the following should be commented to run with nginx --------
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
# command: gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
Which becomes:
# docker-compose.yml
services:
web:
...
# -------- Both of the following should be commented to run with nginx --------
# command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
# command: gunicorn app.main:app -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000
Then pick the way you want to run (uvicorn or gunicorn managing uvicorn workers) in Dockerfile
.
The one you want should be uncommented, comment the other one.
# Dockerfile
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
# CMD ["gunicorn", "app.main:app", "-w", "4", "-k", "uvicorn.workers.UvicornWorker". "-b", "0.0.0.0:8000"]
1. One Server
If you want to run with one server only, your setup should be ready. Just make sure the only part that is not a comment in deafult.conf
is:
# default.conf
# ---------------- Running With One Server ----------------
server {
listen 80;
location / {
proxy_pass http://web: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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
2. Multiple Servers
NGINX can distribute incoming network traffic across multiple servers, improving the efficiency and capacity utilization of your application.
To run with multiple servers, just comment the Running With One Server
part in default.conf
and Uncomment the other one:
# default.conf
# ---------------- Running With One Server ----------------
...
# ---------------- To Run with Multiple Servers, Uncomment below ----------------
upstream fastapi_app {
server fastapi1:8000; # Replace with actual server names or IP addresses
server fastapi2:8000;
# Add more servers as needed
}
server {
listen 80;
location / {
proxy_pass http://fastapi_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Warning
Note that we are using fastapi1:8000
and fastapi2:8000
as examples, you should replace it with the actual name of your service and the port it's running on.
What's Changed
- Core Folder Restructured by @igorbenav in #54
- Better exceptions by @igorbenav in #55
- Nginx configuration by @igorbenav in #56
Full Changelog: v0.7.0...v0.8.0