A robust API Gateway connecting Web2 clients to the Morpheus-Lumerin AI Marketplace using FastAPI, PostgreSQL, and secure key management practices.
This project migrates the existing Morpheus API Gateway functionality from Node.js/Express to Python/FastAPI, incorporating robust authentication, persistent storage, secure key management, and best practices for API development and deployment using Docker.
The gateway provides OpenAI-compatible endpoints that connect to the Morpheus blockchain, allowing users to access AI models in a familiar way while leveraging blockchain technology behind the scenes.
- Web Framework: FastAPI
- Data Validation: Pydantic
- Database ORM: SQLAlchemy with Alembic for migrations
- Database: PostgreSQL
- Caching: In-memory with DirectModelService
- Asynchronous HTTP Client:
httpx
(for communicating with the proxy-router) - JWT Handling:
python-jose
- Password Hashing:
passlib[bcrypt]
- Cryptography:
cryptography
for private key encryption - KMS Integration: AWS KMS for secure key management
- Containerization: Docker, Docker Compose
morpheus_api_python/
βββ alembic/ # Database migrations
βββ alembic.ini
βββ src/
β βββ api/ # FastAPI routers/endpoints
β β βββ v1/
β β β βββ auth.py # User registration, login, API keys, private key mgmt
β β β βββ models.py # OpenAI compatible models endpoint
β β β βββ chat.py # OpenAI compatible chat completions
β β β βββ chat_history.py # Chat history management
β β β βββ session.py # Session management
β β β βββ automation.py # Automation settings
β β βββ __init__.py
β βββ core/ # Core logic, configuration, security
β β βββ config.py # Pydantic settings
β β βββ security.py # JWT generation/validation, password hashing, API key handling
β β βββ key_vault.py # Private key encryption/decryption, KMS interaction
β β βββ direct_model_service.py # Direct model fetching with in-memory cache
β β βββ model_routing.py # Model name to blockchain ID routing
β β βββ local_testing.py # Local testing mode and authentication bypass
β β βββ __init__.py
β βββ crud/ # Database interaction functions
β β βββ user.py
β β βββ api_key.py
β β βββ private_key.py
β β βββ chat.py # Chat and message CRUD operations
β β βββ session.py # Session CRUD operations
β β βββ __init__.py
β βββ db/ # Database session management, base model
β β βββ database.py
β β βββ models.py # SQLAlchemy models (includes Chat, Message)
β β βββ __init__.py
β βββ schemas/ # Pydantic schemas for request/response validation
β β βββ user.py
β β βββ token.py
β β βββ api_key.py
β β βββ private_key.py
β β βββ openai.py # Schemas for OpenAI compatibility
β β βββ __init__.py
β βββ services/ # Business logic layer
β β βββ cognito_service.py # Cognito integration
β β βββ session_service.py # Session management logic
β β βββ proxy_router.py # Proxy router communication
β β βββ __init__.py
β βββ dependencies.py # FastAPI dependency injection functions
β βββ main.py # FastAPI application instance and root setup
βββ ai-docs/ # Documentation and guides
β βββ DOCKER_TESTING.md # Local testing guide
β βββ SELF_CONTAINED_LOCAL_TESTING.md # Detailed local setup
β βββ ... # Other documentation files
βββ scripts/ # Development and deployment scripts
β βββ test_local.sh # Self-contained local testing
β βββ start_local_dev.sh # Container startup with auto-migration
β βββ ... # Other utility scripts
βββ tests/ # Test files
β βββ api/ # API integration tests
β βββ unit/ # Unit tests
βββ .env.example # Production environment template
βββ env.local.example # Local testing environment template
βββ .gitignore # Git ignore file
βββ Dockerfile # Docker build configuration
βββ docker-compose.local.yml # Local development container setup
βββ pyproject.toml # Python project dependencies
βββ README.md # This file
No external dependencies needed! For rapid development and testing:
# One-time setup
cp env.local.example .env.local
# Start local development environment
./scripts/test_local.sh
What this gives you:
- β No Authentication Required - All endpoints work without tokens/keys
- β Fresh Database - PostgreSQL with auto-migrations on every start
- β Hot Reload - Code changes apply instantly
- β Complete API Testing - Test all endpoints via Swagger UI
- β Ephemeral Environment - Clean state every restart
Access your local environment:
- API: http://localhost:8000
- Swagger UI: http://localhost:8000/docs (all endpoints work without auth!)
- Health Check: http://localhost:8000/health
π For detailed testing instructions, see Docker Testing Guide
- Python 3.11+
- Docker and Docker Compose
- PostgreSQL (if running locally without Docker)
- AWS Account with KMS access (for production)
-
Clone the repository:
git clone https://github.com/yourusername/morpheus-api-python.git cd morpheus-api-python
-
Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install poetry poetry install
-
Configure environment variables:
cp .env.example .env
Edit the
.env
file with your specific settings
Configure the following key environment variables:
# Database
POSTGRES_USER=morpheus_user
POSTGRES_PASSWORD=secure_password_here
POSTGRES_DB=morpheus_db
DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}
# Model Service (uses in-memory caching)
ACTIVE_MODELS_URL=https://active.dev.mor.org/active_models.json
# JWT
JWT_SECRET_KEY=generate_this_with_openssl_rand_-hex_32
ACCESS_TOKEN_EXPIRE_MINUTES=30
REFRESH_TOKEN_EXPIRE_DAYS=7
# AWS KMS (for production)
KMS_PROVIDER=aws
KMS_MASTER_KEY_ID=your_kms_key_id_or_arn
AWS_REGION=us-east-1
# AWS_ACCESS_KEY_ID=your_access_key_id # If not using IAM roles
# AWS_SECRET_ACCESS_KEY=your_secret_access_key # If not using IAM roles
# Development mode local encryption (not for production)
MASTER_ENCRYPTION_KEY=generate_this_with_openssl_rand_-hex_32
# Proxy Router
PROXY_ROUTER_URL=http://localhost:8545 # URL of the Morpheus-Lumerin Node proxy-router
Using Local Testing Environment (Recommended):
- Database setup is automatic when using
./scripts/test_local.sh
- PostgreSQL starts in Docker with auto-migrations
- No manual database setup required!
-
Start PostgreSQL:
docker run --name morpheus-postgres -e POSTGRES_USER=morpheus_user -e POSTGRES_PASSWORD=morpheus_password -e POSTGRES_DB=morpheus_db -p 5432:5432 -d postgres:15-alpine
-
Run migrations:
alembic upgrade head
Local Development:
- Migrations run automatically on container startup
- Always uses the latest schema
- Fresh database on every restart
Production/Manual:
Generate a new migration after model changes:
alembic revision --autogenerate -m "Description of changes"
Apply migrations:
alembic upgrade head
Roll back migrations:
alembic downgrade -1 # Roll back one migration
The API uses an in-memory caching system for model data fetched from CloudFront. No external caching service is required.
- Create a KMS key in the AWS console or using AWS CLI
- Note the key ARN or ID
- Configure IAM permissions for your service principal
- Update environment variables with key details
One command starts everything:
./scripts/test_local.sh
Features:
- β PostgreSQL database with auto-migrations
- β API with hot reload
- β Authentication bypass for easy testing
- β All endpoints accessible via Swagger UI
Monitor your environment:
# View logs
docker compose -f docker-compose.local.yml logs -f api-local
# Check status
docker compose -f docker-compose.local.yml ps
# Stop environment
docker compose -f docker-compose.local.yml down
-
Build and start containers:
docker-compose up -d
-
Check container status:
docker-compose ps
-
View logs:
docker-compose logs -f api
-
Start PostgreSQL (see Database Setup above)
-
Run the FastAPI application:
uvicorn src.main:app --reload --host 0.0.0.0 --port 8000
Using Local Environment (No Authentication Required):
# Start environment
./scripts/test_local.sh
# Access Swagger UI - all endpoints work without authentication!
# http://localhost:8000/docs
Test any endpoint directly:
- No Bearer tokens needed
- No API keys required
- Click "Try it out" and execute immediately
- Test user automatically created:
[email protected]
FastAPI automatically generates interactive API documentation:
- Swagger UI: http://localhost:8000/docs
- ReDoc: http://localhost:8000/redoc
π For comprehensive testing instructions, see Docker Testing Guide
POST /api/v1/auth/register
- Create a new userPOST /api/v1/auth/login
- Log in and get JWT tokensPOST /api/v1/auth/refresh
- Refresh access token
POST /api/v1/auth/keys
- Create a new API keyGET /api/v1/auth/keys
- List your API keysDELETE /api/v1/auth/keys/{key_id}
- Delete an API key
POST /api/v1/auth/private-key
- Store your blockchain private keyGET /api/v1/auth/private-key/status
- Check if you have a stored private keyDELETE /api/v1/auth/private-key
- Delete your stored private key
GET /api/v1/models
- List available modelsGET /api/v1/models/{model_id}
- Get model detailsPOST /api/v1/chat/completions
- Create a chat completion
# Start local environment
./scripts/test_local.sh
# Test chat completion directly (no auth needed!)
curl -X POST http://localhost:8000/api/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-3.5-turbo",
"messages": [
{"role": "user", "content": "Hello, how are you?"}
]
}'
# Test chat history
curl -X POST http://localhost:8000/api/v1/chat-history/chats \
-H "Content-Type: application/json" \
-d '{"title": "Test Chat"}'
# List available models
curl http://localhost:8000/api/v1/models
-
Register a user:
curl -X POST http://localhost:8000/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"name": "Test User", "email": "[email protected]", "password": "securepassword"}'
-
Login to get tokens:
curl -X POST http://localhost:8000/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email": "[email protected]", "password": "securepassword"}'
-
Create an API key (using JWT from login):
curl -X POST http://localhost:8000/api/v1/auth/keys \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "My API Key"}'
-
Store a private key:
curl -X POST http://localhost:8000/api/v1/auth/private-key \ -H "Authorization: Bearer YOUR_JWT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"private_key": "YOUR_BLOCKCHAIN_PRIVATE_KEY"}'
-
Create a chat completion using the API key:
curl -X POST http://localhost:8000/api/v1/chat/completions \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-3.5-turbo", "messages": [ {"role": "user", "content": "Hello, how are you?"} ] }'
GET /health
- Check API and model service healthGET /
- Basic API information
This implementation is based on the FastAPI Implementation Plan and has the following open questions:
- Proxy-Router API Specifics: The exact API contract of the
morpheus-lumerin-node
proxy-router
needs clarification. - Model Mapping Source: The source of mapping between OpenAI model names and blockchain model IDs needs to be determined.
- Token Spending Approval: The mechanism for the
/auth/approve-spending
endpoint needs specification. - Private Key Scope: Confirm if a single private key per user is sufficient.
- Rate Limiting: Determine rate-limiting requirements and implement if needed.
- Security Requirements: Confirm if there are any specific compliance or advanced security requirements.
The current implementation uses placeholder/mock data for model information and chat completions until the proxy-router integration is finalized.
# Start local environment (one-time per session)
./scripts/test_local.sh
# Make code changes (hot reload active - changes apply instantly!)
# Test in Swagger UI: http://localhost:8000/docs
# Stop environment when done
# Ctrl+C or: docker compose -f docker-compose.local.yml down
- β Hot Reload - Code changes apply instantly
- β No Authentication - Test all endpoints immediately
- β Fresh Database - Clean state every restart
- β Auto-Migration - Database schema always current
- β Comprehensive Testing - All endpoints accessible via Swagger UI
# Test chat functionality
curl -X POST http://localhost:8000/api/v1/chat-history/chats \
-H "Content-Type: application/json" \
-d '{"title": "Development Test"}'
# Test model service
curl http://localhost:8000/api/v1/models
# Test health checks
curl http://localhost:8000/health
- Format code with
ruff format
- Run linting with
ruff check
- Run type checking with
mypy
- Run tests with
pytest