initial commit
This commit is contained in:
163
docs/getting-started/configuration.md
Normal file
163
docs/getting-started/configuration.md
Normal file
@ -0,0 +1,163 @@
|
||||
# Configuration
|
||||
|
||||
This guide covers the essential configuration steps to get your FastAPI application running quickly.
|
||||
|
||||
## Quick Setup
|
||||
|
||||
The fastest way to get started is to copy the example environment file and modify just a few values:
|
||||
|
||||
```bash
|
||||
cp src/.env.example src/.env
|
||||
```
|
||||
|
||||
## Essential Configuration
|
||||
|
||||
Open `src/.env` and set these required values:
|
||||
|
||||
### Application Settings
|
||||
|
||||
```env
|
||||
# App Settings
|
||||
APP_NAME="Your app name here"
|
||||
APP_DESCRIPTION="Your app description here"
|
||||
APP_VERSION="0.1"
|
||||
CONTACT_NAME="Your name"
|
||||
CONTACT_EMAIL="Your email"
|
||||
LICENSE_NAME="The license you picked"
|
||||
```
|
||||
|
||||
### Database Connection
|
||||
|
||||
```env
|
||||
# Database
|
||||
POSTGRES_USER="your_postgres_user"
|
||||
POSTGRES_PASSWORD="your_password"
|
||||
POSTGRES_SERVER="localhost" # Use "db" for Docker Compose
|
||||
POSTGRES_PORT=5432 # Use 5432 for Docker Compose
|
||||
POSTGRES_DB="your_database_name"
|
||||
```
|
||||
|
||||
### PGAdmin (Optional)
|
||||
|
||||
For database administration:
|
||||
|
||||
```env
|
||||
# PGAdmin
|
||||
PGADMIN_DEFAULT_EMAIL="your_email_address"
|
||||
PGADMIN_DEFAULT_PASSWORD="your_password"
|
||||
PGADMIN_LISTEN_PORT=80
|
||||
```
|
||||
|
||||
**To connect to database in PGAdmin:**
|
||||
1. Login with `PGADMIN_DEFAULT_EMAIL` and `PGADMIN_DEFAULT_PASSWORD`
|
||||
2. Click "Add Server"
|
||||
3. Use these connection settings:
|
||||
- **Hostname/address**: `db` (if using containers) or `localhost`
|
||||
- **Port**: Value from `POSTGRES_PORT`
|
||||
- **Database**: `postgres` (leave as default)
|
||||
- **Username**: Value from `POSTGRES_USER`
|
||||
- **Password**: Value from `POSTGRES_PASSWORD`
|
||||
|
||||
### Security
|
||||
|
||||
Generate a secret key and set it:
|
||||
|
||||
```bash
|
||||
# Generate a secure secret key
|
||||
openssl rand -hex 32
|
||||
```
|
||||
|
||||
```env
|
||||
# Cryptography
|
||||
SECRET_KEY="your-generated-secret-key-here" # Result of openssl rand -hex 32
|
||||
ALGORITHM="HS256" # Default: HS256
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30 # Default: 30
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=7 # Default: 7
|
||||
```
|
||||
|
||||
### First Admin User
|
||||
|
||||
```env
|
||||
# Admin User
|
||||
ADMIN_NAME="your_name"
|
||||
ADMIN_EMAIL="your_email"
|
||||
ADMIN_USERNAME="your_username"
|
||||
ADMIN_PASSWORD="your_password"
|
||||
```
|
||||
|
||||
### Redis Configuration
|
||||
|
||||
```env
|
||||
# Redis Cache
|
||||
REDIS_CACHE_HOST="localhost" # Use "redis" for Docker Compose
|
||||
REDIS_CACHE_PORT=6379
|
||||
|
||||
# Client-side Cache
|
||||
CLIENT_CACHE_MAX_AGE=30 # Default: 30 seconds
|
||||
|
||||
# Redis Job Queue
|
||||
REDIS_QUEUE_HOST="localhost" # Use "redis" for Docker Compose
|
||||
REDIS_QUEUE_PORT=6379
|
||||
|
||||
# Redis Rate Limiting
|
||||
REDIS_RATE_LIMIT_HOST="localhost" # Use "redis" for Docker Compose
|
||||
REDIS_RATE_LIMIT_PORT=6379
|
||||
```
|
||||
|
||||
!!! warning "Redis in Production"
|
||||
You may use the same Redis instance for caching and queues while developing, but use separate containers in production.
|
||||
|
||||
### Rate Limiting Defaults
|
||||
|
||||
```env
|
||||
# Default Rate Limits
|
||||
DEFAULT_RATE_LIMIT_LIMIT=10 # Default: 10 requests
|
||||
DEFAULT_RATE_LIMIT_PERIOD=3600 # Default: 3600 seconds (1 hour)
|
||||
```
|
||||
|
||||
### First Tier
|
||||
|
||||
```env
|
||||
# Default Tier
|
||||
TIER_NAME="free"
|
||||
```
|
||||
|
||||
## Environment Types
|
||||
|
||||
Set your environment type:
|
||||
|
||||
```env
|
||||
ENVIRONMENT="local" # local, staging, or production
|
||||
```
|
||||
|
||||
- **local**: API docs available at `/docs`, `/redoc`, and `/openapi.json`
|
||||
- **staging**: API docs available to superusers only
|
||||
- **production**: API docs completely disabled
|
||||
|
||||
## Docker Compose Settings
|
||||
|
||||
If using Docker Compose, use these values instead:
|
||||
|
||||
```env
|
||||
# Docker Compose values
|
||||
POSTGRES_SERVER="db"
|
||||
REDIS_CACHE_HOST="redis"
|
||||
REDIS_QUEUE_HOST="redis"
|
||||
REDIS_RATE_LIMIT_HOST="redis"
|
||||
```
|
||||
|
||||
## Optional Services
|
||||
|
||||
The boilerplate includes Redis for caching, job queues, and rate limiting. If running locally without Docker, either:
|
||||
|
||||
1. **Install Redis** and keep the default settings
|
||||
2. **Disable Redis services** (see [User Guide - Configuration](../user-guide/configuration/index.md) for details)
|
||||
|
||||
## That's It!
|
||||
|
||||
With these basic settings configured, you can start the application:
|
||||
|
||||
- **Docker Compose**: `docker compose up`
|
||||
- **Manual**: `uv run uvicorn src.app.main:app --reload`
|
||||
|
||||
For detailed configuration options, advanced settings, and production deployment, see the [User Guide - Configuration](../user-guide/configuration/index.md).
|
||||
594
docs/getting-started/first-run.md
Normal file
594
docs/getting-started/first-run.md
Normal file
@ -0,0 +1,594 @@
|
||||
# First Run Guide
|
||||
|
||||
Congratulations on setting up the FastAPI Boilerplate! This guide will walk you through testing your installation, understanding the basics, and making your first customizations.
|
||||
|
||||
## Verification Checklist
|
||||
|
||||
Before diving deeper, let's verify everything is working correctly.
|
||||
|
||||
### 1. Check All Services
|
||||
|
||||
Ensure all services are running:
|
||||
|
||||
```bash
|
||||
# For Docker Compose users
|
||||
docker compose ps
|
||||
|
||||
# Expected output:
|
||||
# NAME COMMAND SERVICE STATUS
|
||||
# fastapi-boilerplate-web-1 "uvicorn app.main:app…" web running
|
||||
# fastapi-boilerplate-db-1 "docker-entrypoint.s…" db running
|
||||
# fastapi-boilerplate-redis-1 "docker-entrypoint.s…" redis running
|
||||
# fastapi-boilerplate-worker-1 "arq src.app.core.wo…" worker running
|
||||
```
|
||||
|
||||
### 2. Test API Endpoints
|
||||
|
||||
Visit these URLs to confirm your API is working:
|
||||
|
||||
**API Documentation:**
|
||||
- **Swagger UI**: [http://localhost:8000/docs](http://localhost:8000/docs)
|
||||
- **ReDoc**: [http://localhost:8000/redoc](http://localhost:8000/redoc)
|
||||
|
||||
**Health Check:**
|
||||
```bash
|
||||
curl http://localhost:8000/api/v1/health
|
||||
```
|
||||
|
||||
Expected response:
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"timestamp": "2024-01-01T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Database Connection
|
||||
|
||||
Check if the database tables were created:
|
||||
|
||||
```bash
|
||||
# For Docker Compose
|
||||
docker compose exec db psql -U postgres -d myapp -c "\dt"
|
||||
|
||||
# You should see tables like:
|
||||
# public | users | table | postgres
|
||||
# public | posts | table | postgres
|
||||
# public | tiers | table | postgres
|
||||
# public | rate_limits | table | postgres
|
||||
```
|
||||
|
||||
### 4. Redis Connection
|
||||
|
||||
Test Redis connectivity:
|
||||
|
||||
```bash
|
||||
# For Docker Compose
|
||||
docker compose exec redis redis-cli ping
|
||||
|
||||
# Expected response: PONG
|
||||
```
|
||||
|
||||
## Initial Setup
|
||||
|
||||
Before testing features, you need to create the first superuser and tier.
|
||||
|
||||
### Creating the First Superuser
|
||||
|
||||
!!! warning "Prerequisites"
|
||||
Make sure the database and tables are created before running create_superuser. The database should be running and the API should have started at least once.
|
||||
|
||||
#### Using Docker Compose
|
||||
|
||||
If using Docker Compose, uncomment this section in your `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
#-------- uncomment to create first superuser --------
|
||||
create_superuser:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
env_file:
|
||||
- ./src/.env
|
||||
depends_on:
|
||||
- db
|
||||
command: python -m src.scripts.create_first_superuser
|
||||
volumes:
|
||||
- ./src:/code/src
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
# Start services and run create_superuser automatically
|
||||
docker compose up -d
|
||||
|
||||
# Or run it manually
|
||||
docker compose run --rm create_superuser
|
||||
|
||||
# Stop the create_superuser service when done
|
||||
docker compose stop create_superuser
|
||||
```
|
||||
|
||||
#### From Scratch
|
||||
|
||||
If running manually, use:
|
||||
|
||||
```bash
|
||||
# Make sure you're in the root folder
|
||||
uv run python -m src.scripts.create_first_superuser
|
||||
```
|
||||
|
||||
### Creating the First Tier
|
||||
|
||||
!!! warning "Prerequisites"
|
||||
Make sure the database and tables are created before running create_tier.
|
||||
|
||||
#### Using Docker Compose
|
||||
|
||||
Uncomment the `create_tier` service in `docker-compose.yml` and run:
|
||||
|
||||
```bash
|
||||
docker compose run --rm create_tier
|
||||
```
|
||||
|
||||
#### From Scratch
|
||||
|
||||
```bash
|
||||
# Make sure you're in the root folder
|
||||
uv run python -m src.scripts.create_first_tier
|
||||
```
|
||||
|
||||
## Testing Core Features
|
||||
|
||||
Let's test the main features of your API.
|
||||
|
||||
### Authentication Flow
|
||||
|
||||
#### 1. Login with Admin User
|
||||
|
||||
Use the admin credentials you set in your `.env` file:
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/login" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=admin&password=your_admin_password"
|
||||
```
|
||||
|
||||
You should receive a response like:
|
||||
```json
|
||||
{
|
||||
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
|
||||
"token_type": "bearer",
|
||||
"refresh_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Create a New User
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/users" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "John Doe",
|
||||
"username": "johndoe",
|
||||
"email": "john@example.com",
|
||||
"password": "securepassword123"
|
||||
}'
|
||||
```
|
||||
|
||||
#### 3. Test Protected Endpoint
|
||||
|
||||
Use the access token from step 1:
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/users/me" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
|
||||
```
|
||||
|
||||
### CRUD Operations
|
||||
|
||||
#### 1. Create a Post
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/posts" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
|
||||
-d '{
|
||||
"title": "My First Post",
|
||||
"content": "This is the content of my first post!"
|
||||
}'
|
||||
```
|
||||
|
||||
#### 2. Get All Posts
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/posts" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
|
||||
```
|
||||
|
||||
#### 3. Get Posts with Pagination
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/posts?page=1&items_per_page=5" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
|
||||
```
|
||||
|
||||
### Background Tasks
|
||||
|
||||
Test the job queue system:
|
||||
|
||||
#### 1. Submit a Background Task
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/tasks/task?message=hello" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
|
||||
```
|
||||
|
||||
Response:
|
||||
```json
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Check Task Status
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8000/api/v1/tasks/task/550e8400-e29b-41d4-a716-446655440000" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
|
||||
```
|
||||
|
||||
### Caching
|
||||
|
||||
Test the caching system:
|
||||
|
||||
#### 1. Make a Cached Request
|
||||
|
||||
```bash
|
||||
# First request (cache miss)
|
||||
curl -X GET "http://localhost:8000/api/v1/users/johndoe" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
|
||||
-w "Time: %{time_total}s\n"
|
||||
|
||||
# Second request (cache hit - should be faster)
|
||||
curl -X GET "http://localhost:8000/api/v1/users/johndoe" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
|
||||
-w "Time: %{time_total}s\n"
|
||||
```
|
||||
|
||||
## Your First Customization
|
||||
|
||||
Let's create a simple custom endpoint to see how easy it is to extend the boilerplate.
|
||||
|
||||
### 1. Create a Simple Model
|
||||
|
||||
Create `src/app/models/item.py`:
|
||||
|
||||
```python
|
||||
from sqlalchemy import String
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from app.core.db.database import Base
|
||||
|
||||
|
||||
class Item(Base):
|
||||
__tablename__ = "items"
|
||||
|
||||
id: Mapped[int] = mapped_column("id", autoincrement=True, nullable=False, unique=True, primary_key=True, init=False)
|
||||
name: Mapped[str] = mapped_column(String(100))
|
||||
description: Mapped[str] = mapped_column(String(500), default="")
|
||||
```
|
||||
|
||||
### 2. Create Pydantic Schemas
|
||||
|
||||
Create `src/app/schemas/item.py`:
|
||||
|
||||
```python
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class ItemBase(BaseModel):
|
||||
name: str = Field(..., min_length=1, max_length=100)
|
||||
description: str = Field("", max_length=500)
|
||||
|
||||
|
||||
class ItemCreate(ItemBase):
|
||||
pass
|
||||
|
||||
|
||||
class ItemCreateInternal(ItemCreate):
|
||||
pass
|
||||
|
||||
|
||||
class ItemRead(ItemBase):
|
||||
id: int
|
||||
|
||||
|
||||
class ItemUpdate(BaseModel):
|
||||
name: str | None = None
|
||||
description: str | None = None
|
||||
|
||||
|
||||
class ItemUpdateInternal(ItemUpdate):
|
||||
pass
|
||||
|
||||
|
||||
class ItemDelete(BaseModel):
|
||||
is_deleted: bool = True
|
||||
```
|
||||
|
||||
### 3. Create CRUD Operations
|
||||
|
||||
Create `src/app/crud/crud_items.py`:
|
||||
|
||||
```python
|
||||
from fastcrud import FastCRUD
|
||||
|
||||
from app.models.item import Item
|
||||
from app.schemas.item import ItemCreateInternal, ItemUpdate, ItemUpdateInternal, ItemDelete
|
||||
|
||||
CRUDItem = FastCRUD[Item, ItemCreateInternal, ItemUpdate, ItemUpdateInternal, ItemDelete]
|
||||
crud_items = CRUDItem(Item)
|
||||
```
|
||||
|
||||
### 4. Create API Endpoints
|
||||
|
||||
Create `src/app/api/v1/items.py`:
|
||||
|
||||
```python
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.api.dependencies import get_current_user
|
||||
from app.core.db.database import async_get_db
|
||||
from app.crud.crud_items import crud_items
|
||||
from app.schemas.item import ItemCreate, ItemRead, ItemUpdate
|
||||
from app.schemas.user import UserRead
|
||||
|
||||
router = APIRouter(tags=["items"])
|
||||
|
||||
|
||||
@router.post("/", response_model=ItemRead, status_code=201)
|
||||
async def create_item(
|
||||
item: ItemCreate,
|
||||
db: Annotated[AsyncSession, Depends(async_get_db)],
|
||||
current_user: Annotated[UserRead, Depends(get_current_user)]
|
||||
):
|
||||
"""Create a new item."""
|
||||
db_item = await crud_items.create(db=db, object=item)
|
||||
return db_item
|
||||
|
||||
|
||||
@router.get("/{item_id}", response_model=ItemRead)
|
||||
async def get_item(
|
||||
item_id: int,
|
||||
db: Annotated[AsyncSession, Depends(async_get_db)]
|
||||
):
|
||||
"""Get an item by ID."""
|
||||
db_item = await crud_items.get(db=db, id=item_id)
|
||||
if not db_item:
|
||||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
return db_item
|
||||
|
||||
|
||||
@router.get("/", response_model=list[ItemRead])
|
||||
async def get_items(
|
||||
db: Annotated[AsyncSession, Depends(async_get_db)],
|
||||
skip: int = 0,
|
||||
limit: int = 100
|
||||
):
|
||||
"""Get all items."""
|
||||
items = await crud_items.get_multi(db=db, offset=skip, limit=limit)
|
||||
return items["data"]
|
||||
|
||||
|
||||
@router.patch("/{item_id}", response_model=ItemRead)
|
||||
async def update_item(
|
||||
item_id: int,
|
||||
item_update: ItemUpdate,
|
||||
db: Annotated[AsyncSession, Depends(async_get_db)],
|
||||
current_user: Annotated[UserRead, Depends(get_current_user)]
|
||||
):
|
||||
"""Update an item."""
|
||||
db_item = await crud_items.get(db=db, id=item_id)
|
||||
if not db_item:
|
||||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
|
||||
updated_item = await crud_items.update(db=db, object=item_update, id=item_id)
|
||||
return updated_item
|
||||
|
||||
|
||||
@router.delete("/{item_id}")
|
||||
async def delete_item(
|
||||
item_id: int,
|
||||
db: Annotated[AsyncSession, Depends(async_get_db)],
|
||||
current_user: Annotated[UserRead, Depends(get_current_user)]
|
||||
):
|
||||
"""Delete an item."""
|
||||
db_item = await crud_items.get(db=db, id=item_id)
|
||||
if not db_item:
|
||||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
|
||||
await crud_items.delete(db=db, id=item_id)
|
||||
return {"message": "Item deleted successfully"}
|
||||
```
|
||||
|
||||
### 5. Register the Router
|
||||
|
||||
Add your new router to `src/app/api/v1/__init__.py`:
|
||||
|
||||
```python
|
||||
from fastapi import APIRouter
|
||||
|
||||
from app.api.v1.login import router as login_router
|
||||
from app.api.v1.logout import router as logout_router
|
||||
from app.api.v1.posts import router as posts_router
|
||||
from app.api.v1.rate_limits import router as rate_limits_router
|
||||
from app.api.v1.tasks import router as tasks_router
|
||||
from app.api.v1.tiers import router as tiers_router
|
||||
from app.api.v1.users import router as users_router
|
||||
from app.api.v1.items import router as items_router # Add this line
|
||||
|
||||
router = APIRouter(prefix="/v1")
|
||||
router.include_router(login_router, prefix="/login")
|
||||
router.include_router(logout_router, prefix="/logout")
|
||||
router.include_router(users_router, prefix="/users")
|
||||
router.include_router(posts_router, prefix="/posts")
|
||||
router.include_router(tasks_router, prefix="/tasks")
|
||||
router.include_router(tiers_router, prefix="/tiers")
|
||||
router.include_router(rate_limits_router, prefix="/rate_limits")
|
||||
router.include_router(items_router, prefix="/items") # Add this line
|
||||
```
|
||||
|
||||
### 6. Create and Run Migration
|
||||
|
||||
Import your new model in `src/app/models/__init__.py`:
|
||||
|
||||
```python
|
||||
from .user import User
|
||||
from .post import Post
|
||||
from .tier import Tier
|
||||
from .rate_limit import RateLimit
|
||||
from .item import Item # Add this line
|
||||
```
|
||||
|
||||
Create and run the migration:
|
||||
|
||||
```bash
|
||||
# For Docker Compose
|
||||
docker compose exec web alembic revision --autogenerate -m "Add items table"
|
||||
docker compose exec web alembic upgrade head
|
||||
|
||||
# For manual installation
|
||||
cd src
|
||||
uv run alembic revision --autogenerate -m "Add items table"
|
||||
uv run alembic upgrade head
|
||||
```
|
||||
|
||||
### 7. Test Your New Endpoint
|
||||
|
||||
Restart your application and test the new endpoints:
|
||||
|
||||
```bash
|
||||
# Create an item
|
||||
curl -X POST "http://localhost:8000/api/v1/items/" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
|
||||
-d '{
|
||||
"name": "My First Item",
|
||||
"description": "This is a test item"
|
||||
}'
|
||||
|
||||
# Get all items
|
||||
curl -X GET "http://localhost:8000/api/v1/items/" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"
|
||||
```
|
||||
|
||||
## Debugging Common Issues
|
||||
|
||||
### Logs and Monitoring
|
||||
|
||||
#### Check Application Logs
|
||||
|
||||
```bash
|
||||
# For Docker Compose
|
||||
docker compose logs web
|
||||
|
||||
# For manual installation
|
||||
tail -f src/app/logs/app.log
|
||||
```
|
||||
|
||||
#### Check Database Logs
|
||||
|
||||
```bash
|
||||
# For Docker Compose
|
||||
docker compose logs db
|
||||
```
|
||||
|
||||
#### Check Worker Logs
|
||||
|
||||
```bash
|
||||
# For Docker Compose
|
||||
docker compose logs worker
|
||||
```
|
||||
|
||||
### Performance Testing
|
||||
|
||||
#### Test API Response Times
|
||||
|
||||
```bash
|
||||
# Test endpoint performance
|
||||
curl -w "Time: %{time_total}s\n" \
|
||||
-H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
|
||||
http://localhost:8000/api/v1/users/me
|
||||
```
|
||||
|
||||
#### Test Database Performance
|
||||
|
||||
```bash
|
||||
# Check active connections
|
||||
docker compose exec db psql -U postgres -d myapp -c "SELECT count(*) FROM pg_stat_activity;"
|
||||
```
|
||||
|
||||
## Monitoring Dashboard
|
||||
|
||||
### Redis Monitor
|
||||
|
||||
```bash
|
||||
# Monitor Redis operations
|
||||
docker compose exec redis redis-cli monitor
|
||||
```
|
||||
|
||||
### Database Activity
|
||||
|
||||
```bash
|
||||
# Check database activity
|
||||
docker compose exec db psql -U postgres -d myapp -c "SELECT * FROM pg_stat_activity;"
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you've verified everything works and created your first custom endpoint, you're ready to dive deeper:
|
||||
|
||||
### Essential Learning
|
||||
|
||||
1. **[Project Structure](../user-guide/project-structure.md)** - Understand how the code is organized
|
||||
2. **[Database Guide](../user-guide/database/index.md)** - Learn about models, schemas, and CRUD operations
|
||||
3. **[Authentication](../user-guide/authentication/index.md)** - Deep dive into JWT and user management
|
||||
|
||||
### Advanced Features
|
||||
|
||||
1. **[Caching](../user-guide/caching/index.md)** - Speed up your API with Redis caching
|
||||
2. **[Background Tasks](../user-guide/background-tasks/index.md)** - Process long-running tasks asynchronously
|
||||
3. **[Rate Limiting](../user-guide/rate-limiting/index.md)** - Protect your API from abuse
|
||||
|
||||
### Development Workflow
|
||||
|
||||
1. **[Development Guide](../user-guide/development.md)** - Best practices for extending the boilerplate
|
||||
2. **[Testing](../user-guide/testing.md)** - Write tests for your new features
|
||||
3. **[Production](../user-guide/production.md)** - Deploy your API to production
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you encounter any issues:
|
||||
|
||||
1. **Check the logs** for error messages
|
||||
2. **Verify your configuration** in the `.env` file
|
||||
3. **Review the [GitHub Issues](https://github.com/benavlabs/fastapi-boilerplate/issues)** for common solutions
|
||||
4. **Search [existing issues](https://github.com/benavlabs/fastapi-boilerplate/issues)** on GitHub
|
||||
5. **Create a [new issue](https://github.com/benavlabs/fastapi-boilerplate/issues/new)** with detailed information
|
||||
|
||||
## Congratulations!
|
||||
|
||||
You've successfully:
|
||||
|
||||
- Verified your FastAPI Boilerplate installation
|
||||
- Tested core API functionality
|
||||
- Created your first custom endpoint
|
||||
- Run database migrations
|
||||
- Tested authentication and CRUD operations
|
||||
|
||||
You're now ready to build amazing APIs with FastAPI!
|
||||
181
docs/getting-started/index.md
Normal file
181
docs/getting-started/index.md
Normal file
@ -0,0 +1,181 @@
|
||||
# Getting Started
|
||||
|
||||
Welcome to the FastAPI Boilerplate! This guide will have you up and running with a production-ready API in just a few minutes.
|
||||
|
||||
## Quick Start (5 minutes)
|
||||
|
||||
The fastest way to get started is using Docker Compose. This will set up everything you need including PostgreSQL, Redis, and the API server.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Make sure you have installed:
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/) (20.10+)
|
||||
- [Docker Compose](https://docs.docker.com/compose/install/) (1.29+)
|
||||
|
||||
### 1. Get the Template
|
||||
|
||||
Start by using this template for your new project:
|
||||
|
||||
1. Click **"Use this template"** on the [GitHub repository](https://github.com/benavlabs/fastapi-boilerplate)
|
||||
2. Create a new repository with your project name
|
||||
3. Clone your new repository:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/yourusername/your-project-name
|
||||
cd your-project-name
|
||||
```
|
||||
|
||||
### 2. Environment Setup
|
||||
|
||||
Create your environment configuration:
|
||||
|
||||
```bash
|
||||
# Create the environment file
|
||||
touch src/.env
|
||||
```
|
||||
|
||||
Add the following basic configuration to `src/.env`:
|
||||
|
||||
```env
|
||||
# Application
|
||||
APP_NAME="My FastAPI App"
|
||||
APP_DESCRIPTION="My awesome API"
|
||||
APP_VERSION="0.1.0"
|
||||
|
||||
# Database
|
||||
POSTGRES_USER="postgres"
|
||||
POSTGRES_PASSWORD="changethis"
|
||||
POSTGRES_SERVER="db"
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_DB="myapp"
|
||||
|
||||
# Security
|
||||
SECRET_KEY="your-secret-key-here"
|
||||
ALGORITHM="HS256"
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
REFRESH_TOKEN_EXPIRE_DAYS=7
|
||||
|
||||
# Redis
|
||||
REDIS_CACHE_HOST="redis"
|
||||
REDIS_CACHE_PORT=6379
|
||||
REDIS_QUEUE_HOST="redis"
|
||||
REDIS_QUEUE_PORT=6379
|
||||
|
||||
# Admin User
|
||||
ADMIN_NAME="Admin"
|
||||
ADMIN_EMAIL="admin@example.com"
|
||||
ADMIN_USERNAME="admin"
|
||||
ADMIN_PASSWORD="changethis"
|
||||
|
||||
# Environment
|
||||
ENVIRONMENT="local"
|
||||
```
|
||||
|
||||
!!! warning "Security Note"
|
||||
Generate a secure secret key using: `openssl rand -hex 32`
|
||||
|
||||
### 3. Start the Application
|
||||
|
||||
Launch all services with a single command:
|
||||
|
||||
```bash
|
||||
docker compose up
|
||||
```
|
||||
|
||||
This will start:
|
||||
- **FastAPI server** on port 8000
|
||||
- **PostgreSQL database**
|
||||
- **Redis** for caching and job queues
|
||||
- **Worker** for background tasks
|
||||
|
||||
### 4. Verify Installation
|
||||
|
||||
Once the containers are running, you should see output like:
|
||||
|
||||
```
|
||||
fastapi-boilerplate-web-1 | INFO: Application startup complete.
|
||||
fastapi-boilerplate-db-1 | database system is ready to accept connections
|
||||
fastapi-boilerplate-worker-1 | redis_version=7.x.x mem_usage=1MB clients_connected=1
|
||||
```
|
||||
|
||||
Visit these URLs to confirm everything is working:
|
||||
|
||||
- **API Documentation**: [http://localhost:8000/docs](http://localhost:8000/docs)
|
||||
- **Alternative Docs**: [http://localhost:8000/redoc](http://localhost:8000/redoc)
|
||||
- **Health Check**: [http://localhost:8000/api/v1/health](http://localhost:8000/api/v1/health)
|
||||
|
||||
## You're Ready!
|
||||
|
||||
Congratulations! You now have a fully functional FastAPI application with:
|
||||
|
||||
- REST API with automatic documentation
|
||||
- PostgreSQL database with migrations
|
||||
- Redis caching and job queues
|
||||
- JWT authentication system
|
||||
- Background task processing
|
||||
- Rate limiting
|
||||
- Admin user created
|
||||
|
||||
## Test Your API
|
||||
|
||||
Try these quick tests to see your API in action:
|
||||
|
||||
### 1. Health Check
|
||||
```bash
|
||||
curl http://localhost:8000/api/v1/health
|
||||
```
|
||||
|
||||
### 2. Create a User
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/users" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"name": "John Doe",
|
||||
"username": "johndoe",
|
||||
"email": "john@example.com",
|
||||
"password": "securepassword"
|
||||
}'
|
||||
```
|
||||
|
||||
### 3. Login
|
||||
```bash
|
||||
curl -X POST "http://localhost:8000/api/v1/login" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "username=johndoe&password=securepassword"
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you have the basics running, explore these guides to learn more:
|
||||
|
||||
### Essential Reading
|
||||
- **[Configuration Guide](configuration.md)** - Understand all configuration options
|
||||
- **[Project Structure](../user-guide/project-structure.md)** - Learn how the code is organized
|
||||
- **[Authentication](../user-guide/authentication/index.md)** - Set up user management
|
||||
|
||||
### Popular Features
|
||||
- **[Database Operations](../user-guide/database/index.md)** - Working with models and CRUD
|
||||
- **[Caching](../user-guide/caching/index.md)** - Speed up your API with Redis caching
|
||||
- **[Background Tasks](../user-guide/background-tasks/index.md)** - Process jobs asynchronously
|
||||
- **[Rate Limiting](../user-guide/rate-limiting/index.md)** - Protect your API from abuse
|
||||
|
||||
### Development & Deployment
|
||||
- **[Development Guide](../user-guide/development.md)** - Extend and customize the boilerplate
|
||||
- **[Testing](../user-guide/testing.md)** - Write tests for your API
|
||||
- **[Production Deployment](../user-guide/production.md)** - Deploy to production
|
||||
|
||||
## Alternative Setup Methods
|
||||
|
||||
Not using Docker? No problem!
|
||||
|
||||
- **[Manual Installation](installation.md)** - Install dependencies manually
|
||||
|
||||
## Need Help?
|
||||
|
||||
- Join our **[Discord Community](../community.md)** - Get help from other developers
|
||||
- Report issues on **[GitHub](https://github.com/benavlabs/fastapi-boilerplate/issues)**
|
||||
|
||||
---
|
||||
|
||||
**Ready to dive deeper?** Continue with the [detailed installation guide](installation.md) or explore the [user guide](../user-guide/index.md).
|
||||
366
docs/getting-started/installation.md
Normal file
366
docs/getting-started/installation.md
Normal file
@ -0,0 +1,366 @@
|
||||
# Installation Guide
|
||||
|
||||
This guide covers different ways to install and set up the FastAPI Boilerplate depending on your needs and environment.
|
||||
|
||||
## System Requirements
|
||||
|
||||
Before you begin, ensure your system meets these requirements:
|
||||
|
||||
- **Python**: 3.11 or higher
|
||||
- **Operating System**: Linux, macOS, or Windows (with WSL2 recommended)
|
||||
- **Memory**: Minimum 4GB RAM (8GB recommended)
|
||||
- **Disk Space**: At least 2GB free space
|
||||
|
||||
## Method 1: Docker Compose (Recommended)
|
||||
|
||||
Docker Compose is the easiest way to get started. It handles all dependencies and services automatically.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Install these tools on your system:
|
||||
|
||||
- [Docker](https://docs.docker.com/get-docker/) (version 20.10+)
|
||||
- [Docker Compose](https://docs.docker.com/compose/install/) (version 1.29+)
|
||||
|
||||
### Installation Steps
|
||||
|
||||
1. **Get the template**:
|
||||
```bash
|
||||
git clone https://github.com/benavlabs/fastapi-boilerplate
|
||||
cd fastapi-boilerplate
|
||||
```
|
||||
|
||||
2. **Set up environment**:
|
||||
```bash
|
||||
cp src/.env.example src/.env
|
||||
# Edit src/.env with your configuration
|
||||
```
|
||||
|
||||
3. **Start services**:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
4. **Verify installation**:
|
||||
```bash
|
||||
curl http://localhost:8000/docs
|
||||
```
|
||||
|
||||
### What Gets Installed
|
||||
|
||||
Docker Compose sets up these services:
|
||||
|
||||
- **Web server** (FastAPI + Uvicorn) on port 8000
|
||||
- **PostgreSQL** database on port 5432 (internal)
|
||||
- **Redis** server on port 6379 (internal)
|
||||
- **ARQ Worker** for background tasks
|
||||
- **NGINX** (optional, for production)
|
||||
|
||||
## Method 2: Manual Installation
|
||||
|
||||
For more control or development purposes, you can install everything manually.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **Install Python 3.11+**:
|
||||
```bash
|
||||
# On Ubuntu/Debian
|
||||
sudo apt update
|
||||
sudo apt install python3.11 python3.11-pip
|
||||
|
||||
# On macOS (with Homebrew)
|
||||
brew install python@3.11
|
||||
|
||||
# On Windows
|
||||
# Download from python.org
|
||||
```
|
||||
|
||||
2. **Install uv** (Python package manager):
|
||||
```bash
|
||||
pip install uv
|
||||
```
|
||||
|
||||
3. **Install PostgreSQL**:
|
||||
```bash
|
||||
# On Ubuntu/Debian
|
||||
sudo apt install postgresql postgresql-contrib
|
||||
|
||||
# On macOS
|
||||
brew install postgresql
|
||||
|
||||
# On Windows
|
||||
# Download from postgresql.org
|
||||
```
|
||||
|
||||
4. **Install Redis**:
|
||||
```bash
|
||||
# On Ubuntu/Debian
|
||||
sudo apt install redis-server
|
||||
|
||||
# On macOS
|
||||
brew install redis
|
||||
|
||||
# On Windows
|
||||
# Download from redis.io
|
||||
```
|
||||
|
||||
### Installation Steps
|
||||
|
||||
1. **Clone the repository**:
|
||||
```bash
|
||||
git clone https://github.com/benavlabs/fastapi-boilerplate
|
||||
cd fastapi-boilerplate
|
||||
```
|
||||
|
||||
2. **Install Python dependencies**:
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
3. **Set up environment variables**:
|
||||
```bash
|
||||
cp src/.env.example src/.env
|
||||
# Edit src/.env with your local database/Redis settings
|
||||
```
|
||||
|
||||
4. **Set up PostgreSQL**:
|
||||
```bash
|
||||
# Create database and user
|
||||
sudo -u postgres psql
|
||||
CREATE DATABASE myapp;
|
||||
CREATE USER myuser WITH PASSWORD 'mypassword';
|
||||
GRANT ALL PRIVILEGES ON DATABASE myapp TO myuser;
|
||||
\q
|
||||
```
|
||||
|
||||
5. **Run database migrations**:
|
||||
```bash
|
||||
cd src
|
||||
uv run alembic upgrade head
|
||||
```
|
||||
|
||||
6. **Create admin user**:
|
||||
```bash
|
||||
uv run python -m src.scripts.create_first_superuser
|
||||
```
|
||||
|
||||
7. **Start the application**:
|
||||
```bash
|
||||
uv run uvicorn src.app.main:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
8. **Start the worker** (in another terminal):
|
||||
```bash
|
||||
uv run arq src.app.core.worker.settings.WorkerSettings
|
||||
```
|
||||
|
||||
## Method 3: Development Setup
|
||||
|
||||
For contributors and advanced users who want to modify the boilerplate.
|
||||
|
||||
### Additional Prerequisites
|
||||
|
||||
- **Git** for version control
|
||||
- **Pre-commit** for code quality
|
||||
|
||||
### Installation Steps
|
||||
|
||||
1. **Fork and clone**:
|
||||
```bash
|
||||
# Fork the repository on GitHub first
|
||||
git clone https://github.com/yourusername/fastapi-boilerplate
|
||||
cd fastapi-boilerplate
|
||||
```
|
||||
|
||||
2. **Install development dependencies**:
|
||||
```bash
|
||||
uv sync --group dev
|
||||
```
|
||||
|
||||
3. **Set up pre-commit hooks**:
|
||||
```bash
|
||||
uv run pre-commit install
|
||||
```
|
||||
|
||||
4. **Set up development environment**:
|
||||
```bash
|
||||
cp src/.env.example src/.env
|
||||
# Configure for development
|
||||
```
|
||||
|
||||
5. **Run tests to verify setup**:
|
||||
```bash
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
## Docker Services Breakdown
|
||||
|
||||
Understanding what each Docker service does:
|
||||
|
||||
### Web Service
|
||||
```yaml
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
- "8000:8000"
|
||||
depends_on:
|
||||
- db
|
||||
- redis
|
||||
```
|
||||
- Runs the FastAPI application
|
||||
- Handles HTTP requests
|
||||
- Auto-reloads on code changes (development)
|
||||
|
||||
### Database Service
|
||||
```yaml
|
||||
db:
|
||||
image: postgres:13
|
||||
environment:
|
||||
POSTGRES_DB: myapp
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: changethis
|
||||
```
|
||||
- PostgreSQL database server
|
||||
- Persistent data storage
|
||||
- Automatic initialization
|
||||
|
||||
### Redis Service
|
||||
```yaml
|
||||
redis:
|
||||
image: redis:alpine
|
||||
command: redis-server --appendonly yes
|
||||
```
|
||||
- In-memory data store
|
||||
- Used for caching and job queues
|
||||
- Persistent storage with AOF
|
||||
|
||||
### Worker Service
|
||||
```yaml
|
||||
worker:
|
||||
build: .
|
||||
command: arq src.app.core.worker.settings.WorkerSettings
|
||||
depends_on:
|
||||
- redis
|
||||
```
|
||||
- Background task processor
|
||||
- Handles async jobs
|
||||
- Scales independently
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
The application uses environment variables for configuration. Key variables:
|
||||
|
||||
```env
|
||||
# Database
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=changethis
|
||||
POSTGRES_SERVER=localhost # or "db" for Docker
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_DB=myapp
|
||||
|
||||
# Redis
|
||||
REDIS_CACHE_HOST=localhost # or "redis" for Docker
|
||||
REDIS_CACHE_PORT=6379
|
||||
|
||||
# Security
|
||||
SECRET_KEY=your-secret-key-here
|
||||
ALGORITHM=HS256
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES=30
|
||||
```
|
||||
|
||||
### Database Connection
|
||||
|
||||
For manual installation, update your database settings:
|
||||
|
||||
```env
|
||||
# Local PostgreSQL
|
||||
POSTGRES_SERVER=localhost
|
||||
POSTGRES_PORT=5432
|
||||
|
||||
# Docker PostgreSQL
|
||||
POSTGRES_SERVER=db
|
||||
POSTGRES_PORT=5432
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
After installation, verify everything works:
|
||||
|
||||
1. **API Documentation**: http://localhost:8000/docs
|
||||
2. **Health Check**: http://localhost:8000/api/v1/health
|
||||
3. **Database Connection**: Check logs for successful connection
|
||||
4. **Redis Connection**: Test caching functionality
|
||||
5. **Background Tasks**: Submit a test job
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Port Already in Use**:
|
||||
```bash
|
||||
# Check what's using port 8000
|
||||
lsof -i :8000
|
||||
|
||||
# Kill the process
|
||||
kill -9 <PID>
|
||||
```
|
||||
|
||||
**Database Connection Error**:
|
||||
```bash
|
||||
# Check PostgreSQL status
|
||||
sudo systemctl status postgresql
|
||||
|
||||
# Restart PostgreSQL
|
||||
sudo systemctl restart postgresql
|
||||
```
|
||||
|
||||
**Redis Connection Error**:
|
||||
```bash
|
||||
# Check Redis status
|
||||
redis-cli ping
|
||||
|
||||
# Start Redis
|
||||
redis-server
|
||||
```
|
||||
|
||||
**Permission Errors**:
|
||||
```bash
|
||||
# Fix Docker permissions
|
||||
sudo usermod -aG docker $USER
|
||||
# Log out and back in
|
||||
```
|
||||
|
||||
### Docker Issues
|
||||
|
||||
**Clean Reset**:
|
||||
```bash
|
||||
# Stop all containers
|
||||
docker compose down
|
||||
|
||||
# Remove volumes (⚠️ deletes data)
|
||||
docker compose down -v
|
||||
|
||||
# Rebuild images
|
||||
docker compose build --no-cache
|
||||
|
||||
# Start fresh
|
||||
docker compose up
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
After successful installation:
|
||||
|
||||
1. **[Configuration Guide](configuration.md)** - Set up your environment
|
||||
2. **[First Run](first-run.md)** - Test your installation
|
||||
3. **[Project Structure](../user-guide/project-structure.md)** - Understand the codebase
|
||||
|
||||
## Need Help?
|
||||
|
||||
If you encounter issues:
|
||||
|
||||
- Check the [GitHub Issues](https://github.com/benavlabs/fastapi-boilerplate/issues) for common problems
|
||||
- Search [existing issues](https://github.com/benavlabs/fastapi-boilerplate/issues)
|
||||
- Create a [new issue](https://github.com/benavlabs/fastapi-boilerplate/issues/new) with details
|
||||
Reference in New Issue
Block a user