The iTube-api is the core backend API service for the iTube video platform. Built with FastAPI, it handles user authentication (via AWS Cognito), video metadata management, presigned URL generation for S3 uploads, and provides IAM-authenticated endpoints for internal microservices. In short: the central brain of the video platform.
- User authentication: AWS Cognito integration with cookie-based sessions
- Video upload orchestration: Generate presigned S3 URLs for client-side uploads
- Video metadata management: Store and retrieve video information (title, description, visibility, processing status)
- Internal service APIs: IAM-authenticated endpoints for transcoder service communication
- Video discovery: Public APIs for listing and retrieving processed videos
- Database management: PostgreSQL for persistent storage with SQLAlchemy ORM
- Caching layer: Redis integration for video metadata caching
- Logging & observability: Structured logging with request tracking
┌──────────┐ HTTP/REST ┌─────────────┐
│ Client │ ◄─────────────────► │ iTube-api │
│ (Web/App)│ Cookie Auth │ FastAPI │
└──────────┘ └──────┬──────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ AWS │ │PostgreSQL│ │ Redis │
│ Cognito │ │ Database│ │ Cache │
└──────────┘ └──────────┘ └──────────┘
│ │
│ │
▼ ▼
┌──────────┐ ┌──────────┐
│ S3 │ │ SQS │
│ Buckets │ │ Queue │
└──────────┘ └──────────┘
▲
│ AWS SigV4 (IAM Auth)
│
┌─────┴──────┐
│ Transcoder │
│ Service │
└────────────┘
- POST
/api/v1/auth/register- User registration - POST
/api/v1/auth/login- User login (returns cookie) - POST
/api/v1/auth/logout- User logout - GET
/api/v1/auth/me- Get current user info
- POST
/api/v1/upload/videos/upload-url- Get presigned URL for video upload - POST
/api/v1/upload/videos/thumbnail/upload-url- Get presigned URL for thumbnail upload - POST
/api/v1/upload/videos/metadata- Save video metadata after upload - GET
/api/v1/upload/videos/- List all public completed videos - GET
/api/v1/upload/videos/{video_id}- Get specific video details
- GET
/api/v1/upload/videos/by-key/{s3_key}- Lookup video ID by S3 key (for transcoder) - PATCH
/api/v1/upload/videos/{video_id}/status- Update processing status (for transcoder)
- Python 3.11+ (for local development)
- PostgreSQL 16 (database)
- Redis 7 (caching layer)
- AWS Account with:
- AWS Cognito user pool configured
- S3 buckets for raw videos, processed videos, and thumbnails
- IAM credentials with S3 access
- Docker (optional, for containerized development)
Create a .env file (copy from .env.example if available) or set these environment variables:
POSTGRES_DATABASE_URL— PostgreSQL connection string (e.g.,postgresql://user:pass@localhost:5432/itube)POSTGRES_USER— Database usernamePOSTGRES_PASSWORD— Database passwordPOSTGRES_DB— Database name
COGNITO_CLIENT_ID— AWS Cognito app client IDCOGNITO_CLIENT_SECRET— AWS Cognito app client secret
REGION_NAME— AWS region (e.g.,us-east-1)AWS_ACCESS_KEY_ID— AWS access keyAWS_SECRET_ACCESS_KEY— AWS secret key
S3_RAW_VIDEOS_BUCKET— Bucket for raw uploaded videosS3_PROCESSED_VIDEOS_BUCKET— Bucket for transcoded videosS3_VIDEO_THUMBNAILS_BUCKET— Bucket for video thumbnails
REDIS_HOST— Redis server hostname (default:localhost)REDIS_PORT— Redis server port (default:6379)
Seriously — don't commit .env to version control. Treat it like your browser history: deeply personal and best kept private. Add .env to .gitignore if it's not already there.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtOption A: Docker Compose (Recommended)
# From iTube-api/ directory
docker compose up -d db redis
# Wait a few seconds for services to initialize
sleep 5This starts PostgreSQL on port 5433 and Redis on port 6379.
Option B: Local Installation
Install PostgreSQL and Redis locally, then create the database:
createdb itube
redis-servercp .env.example .env
# Edit .env with your AWS credentials and Cognito configurationExample .env:
POSTGRES_DATABASE_URL=postgresql://postgres:postgres@localhost:5433/itube
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=itube
COGNITO_CLIENT_ID=your_cognito_client_id
COGNITO_CLIENT_SECRET=your_cognito_client_secret
REGION_NAME=us-east-1
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
S3_RAW_VIDEOS_BUCKET=itube-raw-videos
S3_PROCESSED_VIDEOS_BUCKET=itube-processed-videos
S3_VIDEO_THUMBNAILS_BUCKET=itube-thumbnails
REDIS_HOST=localhost
REDIS_PORT=6379The application automatically creates tables on startup via init_db() in app/core/database.py. For production, consider using Alembic for migrations.
# Export environment variables
export $(grep -v '^#' .env | xargs)
# Run with uvicorn (development server with auto-reload)
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000The API will be available at: http://localhost:8000
- API Docs: http://localhost:8000/docs (Swagger UI)
- Alternative Docs: http://localhost:8000/redoc (ReDoc)
The repository includes a Dockerfile and docker-compose.yml for full-stack local development.
# From iTube-api/ directory
docker compose build
docker compose upThis starts:
- API server on port 8000
- PostgreSQL on port 5433
- Redis on port 6379
docker build -t itube-api .
docker run --env-file .env -p 8000:8000 itube-apiiTube-api/
├── app/
│ ├── main.py # FastAPI application entrypoint
│ ├── auth/ # Authentication module
│ │ ├── routes.py # Auth endpoints (register, login, logout)
│ │ ├── service.py # Auth business logic
│ │ ├── repository.py # User database operations
│ │ ├── models.py # User SQLAlchemy models
│ │ └── schemas.py # Pydantic schemas for auth
│ ├── video/ # Video management module
│ │ ├── routes.py # Video endpoints (upload, metadata, status)
│ │ ├── service.py # Video business logic
│ │ ├── repository.py # Video database operations
│ │ ├── models.py # Video SQLAlchemy models
│ │ └── schemas.py # Pydantic schemas for videos
│ └── core/ # Core utilities and configuration
│ ├── config.py # Environment configuration (Pydantic Settings)
│ ├── database.py # SQLAlchemy database setup
│ ├── redis.py # Redis client configuration
│ ├── cognito.py # AWS Cognito client setup
│ ├── security.py # Password hashing utilities
│ ├── logging_config.py # Structured logging setup
│ ├── exceptions.py # Custom exception classes
│ ├── error_handlers.py # FastAPI exception handlers
│ └── middleware/
│ ├── auth_user.py # Authentication dependencies
│ └── access_log.py # Request logging middleware
├── requirements.txt # Python dependencies
├── Dockerfile # Container image definition
├── docker-compose.yml # Local development stack
└── README.md # This file
The API supports two authentication methods depending on the endpoint:
For client-facing endpoints (user registration, video uploads, listing videos):
- Method: AWS Cognito with HTTP-only cookies
- Flow:
- User logs in via
/api/v1/auth/login - API validates credentials with AWS Cognito
- Access token stored in secure HTTP-only cookie
- Subsequent requests include cookie automatically
- User logs in via
- Protected by:
get_current_user()dependency - Endpoints:
/api/v1/auth/*,/api/v1/upload/videos/*(except internal endpoints)
For internal microservice communication (transcoder → API):
- Method: AWS Signature Version 4 (SigV4)
- Flow:
- Transcoder signs requests using ECS task role credentials
- API Gateway verifies signature (recommended) or API validates headers
- Request forwarded to API with verified credentials
- Protected by:
verify_iam_auth()dependency - Endpoints:
/api/v1/upload/videos/by-key/*,/api/v1/upload/videos/{id}/status - Production setup: See
API_GATEWAY_SETUP.mdin the project root
Currently, the application uses SQLAlchemy's Base.metadata.create_all() for automatic table creation on startup. For production deployments, consider implementing proper database migrations with Alembic:
# Install Alembic
pip install alembic
# Initialize Alembic
alembic init alembic
# Generate migration
alembic revision --autogenerate -m "Initial migration"
# Apply migration
alembic upgrade head- Logging: Configured centrally in
app/core/logging_config.py. Uses structured logging with JSON format for production readiness. - Error handlers: Global exception handlers in
app/core/error_handlers.pycatch and format errors consistently. - Access logs: Custom middleware (
AccessLogMiddleware) logs all HTTP requests with timing information. - Validation errors: Pydantic schemas provide automatic request/response validation with detailed error messages.
Understanding how videos flow through the system:
-
Client requests upload URL:
POST /api/v1/upload/videos/upload-url- API generates unique S3 key:
videos/{user_id}/{uuid} - Returns presigned S3 URL valid for direct upload
- API generates unique S3 key:
-
Client uploads to S3: Direct browser → S3 upload (no API involved)
- Uses presigned URL
- Faster, doesn't burden API server
-
Client submits metadata:
POST /api/v1/upload/videos/metadata- Title, description, S3 key, visibility
- Creates database record with status
IN_PROGRESS - S3 event triggers SQS → Consumer → Transcoder
-
Transcoder processes video:
- Downloads from S3
- Transcodes to multiple formats/resolutions
- Uploads processed files to processed bucket
- Calls API:
GET /videos/by-key/{s3_key}(lookup video ID) - Calls API:
PATCH /videos/{video_id}/status?status=COMPLETED
-
Video available: Status changes to
COMPLETED, visible in listings
- Database: Use managed PostgreSQL (AWS RDS, GCP Cloud SQL) with connection pooling
- Redis: Use managed Redis (AWS ElastiCache, GCP Memorystore) for high availability
- API Gateway: Deploy behind AWS API Gateway for IAM auth, rate limiting, and DDoS protection (see
API_GATEWAY_SETUP.md) - Secrets management: Use AWS Secrets Manager or Parameter Store instead of environment variables
- Monitoring: Enable CloudWatch metrics, distributed tracing, and alerting
- CORS: Update
allow_originsinapp/main.pyto restrict to your domain (currently set to*for development) - Database migrations: Implement Alembic for safe schema changes
# Build production image
docker build -t itube-api:latest .
# Tag for your registry (ECR example)
docker tag itube-api:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/itube-api:latest
# Push to registry
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/itube-api:latestHealth checks: The API runs on port 8000. Use /docs or create a dedicated /health endpoint for load balancer health checks.
Symptom: could not connect to server or connection refused
Solutions:
- Verify PostgreSQL is running:
docker compose psorpg_isready - Check
POSTGRES_DATABASE_URLin.envmatches your database configuration - Ensure database exists:
psql -U postgres -c "CREATE DATABASE itube;" - Check firewall rules if using remote database
Symptom: UnauthorizedError or InvalidParameterException
Solutions:
- Verify
COGNITO_CLIENT_IDandCOGNITO_CLIENT_SECRETare correct - Check Cognito user pool is in the same region as
REGION_NAME - Ensure Cognito app client has correct auth flow enabled (USER_PASSWORD_AUTH)
- Verify user is confirmed in Cognito (check email confirmation)
Symptom: ConnectionRefusedError or cache misses
Solutions:
- Verify Redis is running:
docker compose psorredis-cli ping - Check
REDIS_HOSTandREDIS_PORTin.env - Redis is optional for basic functionality (only affects caching)
- Errors are logged but don't crash the application
Symptom: AccessDenied or NoSuchBucket
Solutions:
- Verify
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYhave S3 permissions - Ensure buckets exist:
aws s3 ls | grep itube - Check bucket names in
.envmatch actual bucket names - Verify IAM policy allows
s3:PutObjectands3:GetObjecton your buckets
Symptom: ModuleNotFoundError
Solutions:
# Reinstall dependencies
pip install --upgrade -r requirements.txt
# If using virtual environment, ensure it's activated
source .venv/bin/activateSymptom: Address already in use when starting the server
Solutions:
# Find process using port 8000
lsof -ti:8000
# Kill the process
kill -9 $(lsof -ti:8000)
# Or use a different port
uvicorn app.main:app --port 8001FastAPI automatically generates interactive API documentation:
-
Swagger UI: http://localhost:8000/docs
- Try endpoints directly in the browser
- See request/response schemas
- Generate curl commands
-
ReDoc: http://localhost:8000/redoc
- Alternative documentation format
- Better for reading/printing
# Health check (via docs page)
curl http://localhost:8000/docs
# Register a user (replace with your values)
curl -X POST http://localhost:8000/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"name": "Test User",
"email": "test@example.com",
"password": "SecurePass123!"
}'
# Login
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "SecurePass123!"
}' \
-c cookies.txt
# Get presigned upload URL (using saved cookies)
curl -X POST http://localhost:8000/api/v1/upload/videos/upload-url \
-H "Content-Type: application/json" \
-b cookies.txt- Testing: Add unit tests (pytest), integration tests, and API tests
- Database migrations: Implement Alembic for version-controlled schema changes
- Rate limiting: Add request rate limiting per user/IP
- Video analytics: Track view counts, likes, comments
- Search: Add full-text search for video discovery (Elasticsearch/OpenSearch)
- Webhooks: Notify clients when video processing completes
- Admin panel: Create admin endpoints for moderation and management
- GraphQL: Consider GraphQL API for more flexible client queries
- Connection pooling: SQLAlchemy uses connection pooling by default (5-20 connections)
- Redis caching: Video metadata cached for 1 hour, reduces database load
- Async operations: Consider making S3/database operations fully async for better concurrency
- CDN: Serve processed videos through CloudFront for faster delivery
- Database indexing: Ensure indexes on
video_s3_key,user_id,visibility,processing_status
See the top-level LICENSE file.
If you're stuck on AWS Cognito setup (we've all been there), check out this helpful guide.
For S3 presigned URL issues, try searching: AWS S3 presigned URL troubleshooting.
Still stuck? AWS docs and Stack Overflow are your friends. The FastAPI documentation is also excellent: https://fastapi.tiangolo.com/
Happy coding! 🚀