Deployment Guide for APIFromAnythingο
This guide provides instructions for deploying APIs built with APIFromAnything in various environments, including Docker, Kubernetes, and serverless platforms.
Table of Contentsο
Docker Deployment {#docker-deployment}ο
Docker provides a consistent and isolated environment for running your API. Hereβs how to containerize an API built with APIFromAnything:
1. Create a Dockerfileο
Create a Dockerfile in your project root:
FROM python:3.9-slim
WORKDIR /app
# Copy requirements file
COPY requirements.txt .
# Install dependencies
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . .
# Expose the port your API will run on
EXPOSE 8000
# Command to run the API
CMD ["python", "app.py"]
2. Create a requirements.txt fileο
Make sure your requirements.txt includes APIFromAnything and any other dependencies:
apifrom>=0.1.0
3. Build the Docker imageο
docker build -t my-api .
4. Run the Docker containerο
docker run -p 8000:8000 my-api
5. Docker Compose (Optional)ο
For more complex setups with multiple services, create a docker-compose.yml file:
version: '3'
services:
api:
build: .
ports:
- "8000:8000"
environment:
- ENV=production
restart: always
prometheus:
image: prom/prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
depends_on:
- api
Run with:
docker-compose up
Kubernetes Deployment {#kubernetes-deployment}ο
Kubernetes provides a robust platform for deploying, scaling, and managing containerized applications.
1. Create a Kubernetes Deploymentο
Create a file named deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-api
labels:
app: my-api
spec:
replicas: 3
selector:
matchLabels:
app: my-api
template:
metadata:
labels:
app: my-api
spec:
containers:
- name: my-api
image: my-api:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8000
resources:
limits:
cpu: "500m"
memory: "512Mi"
requests:
cpu: "100m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
2. Create a Kubernetes Serviceο
Create a file named service.yaml:
apiVersion: v1
kind: Service
metadata:
name: my-api-service
spec:
selector:
app: my-api
ports:
- port: 80
targetPort: 8000
type: LoadBalancer
3. Apply the Kubernetes configurationsο
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
4. Horizontal Pod Autoscaling (Optional)ο
Create a file named hpa.yaml:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-api
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
Apply the HPA configuration:
kubectl apply -f hpa.yaml
Serverless Deployment {#serverless-deployment}ο
APIFromAnything can be deployed to serverless platforms, allowing you to run your API without managing servers.
AWS Lambda {#aws-lambda}ο
1. Create a Lambda handlerο
Create a file named lambda_handler.py:
from apifrom.core.app import API
from apifrom.decorators.api import api
from apifrom.adapters.aws_lambda import LambdaAdapter
# Create an API application
app = API(title="My Serverless API")
# Define API endpoints
@api(app)
def hello(name: str = "World") -> dict:
"""Say hello to someone."""
return {"message": f"Hello, {name}!"}
# Create a Lambda adapter
lambda_adapter = LambdaAdapter(app)
# Lambda handler function
def handler(event, context):
"""AWS Lambda handler function."""
return lambda_adapter.handle(event, context)
2. Package your applicationο
Create a deployment package by installing dependencies in a local directory and zipping everything:
pip install apifrom -t ./package
cp lambda_handler.py ./package/
cd package
zip -r ../deployment.zip .
3. Deploy to AWS Lambdaο
Using the AWS CLI:
aws lambda create-function \
--function-name my-api \
--runtime python3.9 \
--handler lambda_handler.handler \
--zip-file fileb://deployment.zip \
--role arn:aws:iam::123456789012:role/lambda-execution-role
4. Configure API Gatewayο
Create a new REST API in API Gateway
Create a resource and method that integrates with your Lambda function
Deploy the API to a stage
Google Cloud Functions {#google-cloud-functions}ο
1. Create a Cloud Function handlerο
Create a file named main.py:
from apifrom.core.app import API
from apifrom.decorators.api import api
from apifrom.adapters.gcp_functions import CloudFunctionAdapter
# Create an API application
app = API(title="My Serverless API")
# Define API endpoints
@api(app)
def hello(name: str = "World") -> dict:
"""Say hello to someone."""
return {"message": f"Hello, {name}!"}
# Create a Cloud Function adapter
cf_adapter = CloudFunctionAdapter(app)
# Cloud Function handler
def handler(request):
"""Google Cloud Function handler."""
return cf_adapter.handle(request)
2. Create a requirements.txt fileο
apifrom>=0.1.0
3. Deploy to Google Cloud Functionsο
Using the gcloud CLI:
gcloud functions deploy my-api \
--runtime python39 \
--trigger-http \
--entry-point handler
Azure Functions {#azure-functions}ο
1. Create an Azure Function projectο
Initialize an Azure Functions project:
func init my-api-project --python
cd my-api-project
func new --name my-api --template "HTTP trigger"
2. Modify the function codeο
Edit my-api/__init__.py:
import azure.functions as func
from apifrom.core.app import API
from apifrom.decorators.api import api
from apifrom.adapters.azure_functions import AzureFunctionAdapter
# Create an API application
app = API(title="My Serverless API")
# Define API endpoints
@api(app)
def hello(name: str = "World") -> dict:
"""Say hello to someone."""
return {"message": f"Hello, {name}!"}
# Create an Azure Function adapter
azure_adapter = AzureFunctionAdapter(app)
# Azure Function handler
def main(req: func.HttpRequest) -> func.HttpResponse:
"""Azure Function handler."""
return azure_adapter.handle(req)
3. Update requirements.txtο
azure-functions
apifrom>=0.1.0
4. Deploy to Azure Functionsο
func azure functionapp publish my-api-app
Performance Considerations {#performance-considerations}ο
When deploying APIFromAnything in production, consider the following performance optimizations:
1. Asynchronous Processingο
Use asynchronous endpoints for I/O-bound operations:
@api(app)
async def fetch_data() -> dict:
"""Fetch data asynchronously."""
# Asynchronous I/O operations
result = await some_async_operation()
return {"data": result}
2. Cachingο
Implement caching for frequently accessed endpoints:
from apifrom.middleware.cache import cache
@api(app)
@cache(ttl=300) # Cache for 5 minutes
def expensive_operation() -> dict:
"""Perform an expensive operation."""
# Expensive computation or database query
return {"result": result}
3. Connection Poolingο
For database connections, use connection pooling:
# Example with SQLAlchemy
from sqlalchemy import create_engine
from sqlalchemy.pool import QueuePool
engine = create_engine(
"postgresql://user:password@localhost/dbname",
poolclass=QueuePool,
pool_size=5,
max_overflow=10
)
4. Load Testingο
Before deploying to production, perform load testing to identify bottlenecks:
# Using Apache Benchmark
ab -n 1000 -c 100 http://localhost:8000/api/endpoint
Monitoring in Production {#monitoring-in-production}ο
APIFromAnything provides built-in monitoring capabilities that can be integrated with various monitoring systems.
1. Prometheus Integrationο
from apifrom.monitoring import MetricsCollector, PrometheusExporter
# Create a metrics collector
metrics = MetricsCollector()
# Create a Prometheus exporter
prometheus_exporter = PrometheusExporter(collector=metrics)
# Define a metrics endpoint
@api(app)
def metrics() -> str:
"""Return Prometheus metrics."""
return prometheus_exporter.export()
Configure Prometheus to scrape this endpoint:
# prometheus.yml
scrape_configs:
- job_name: 'my-api'
scrape_interval: 15s
static_configs:
- targets: ['my-api:8000']
2. Loggingο
Configure comprehensive logging:
import logging
from apifrom.monitoring import LogExporter
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
filename='/var/log/my-api.log'
)
# Create a log exporter
log_exporter = LogExporter(collector=metrics)
# Export metrics periodically
log_exporter.export_periodic(interval_seconds=60)
3. Alertingο
Set up alerts for critical metrics:
# Prometheus alerting rules
groups:
- name: my-api-alerts
rules:
- alert: HighErrorRate
expr: rate(api_errors_total[5m]) / rate(api_requests_total[5m]) > 0.1
for: 5m
labels:
severity: critical
annotations:
summary: "High error rate detected"
description: "Error rate is above 10% for the last 5 minutes"
4. Distributed Tracingο
Implement distributed tracing for complex systems:
from apifrom.monitoring.tracing import init_tracer, trace
# Initialize a tracer
tracer = init_tracer("my-api")
@api(app)
@trace(tracer)
def traced_endpoint() -> dict:
"""An endpoint with distributed tracing."""
# Your endpoint logic
return {"result": "success"}
Production Deployment Checklistο
Before deploying your APIFromAnything application to production, ensure youβve completed the following checklist to guarantee a smooth, secure, and performant deployment:
Security Checklistο
Enable HTTPS: Always use HTTPS in production
app.run(host="0.0.0.0", port=443, ssl_certfile="cert.pem", ssl_keyfile="key.pem")
Set up CORS properly: Restrict CORS to only the domains that need access
from apifrom.middleware import CORSMiddleware app.add_middleware( CORSMiddleware( allow_origins=["https://yourdomain.com"], allow_methods=["GET", "POST", "PUT", "DELETE"], allow_headers=["Content-Type", "Authorization"], allow_credentials=True ) )
Add CSRF protection: Protect against Cross-Site Request Forgery
from apifrom.middleware import CSRFMiddleware app.add_middleware(CSRFMiddleware())
Configure security headers: Add security headers to protect against common attacks
from apifrom.middleware import SecurityHeadersMiddleware app.add_middleware(SecurityHeadersMiddleware())
Set up rate limiting: Protect against abuse and DoS attacks
from apifrom.middleware import RateLimitMiddleware app.add_middleware( RateLimitMiddleware( limit=100, # 100 requests per minute window=60, by_ip=True ) )
Implement authentication: Secure your API with proper authentication
from apifrom.security import jwt_required @api(route="/protected", method="GET") @jwt_required(secret="your-secret-key") def protected_endpoint(request): user_id = request.state.jwt_payload.get("sub") return {"message": f"Hello, user {user_id}!"}
Validate input data: Ensure all input data is properly validated
from pydantic import BaseModel, Field class User(BaseModel): name: str = Field(..., min_length=2, max_length=50) email: str = Field(..., regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$") age: int = Field(..., ge=18, le=120) @api(route="/users", method="POST") def create_user(user: User): # User data is automatically validated return {"id": 123, **user.dict()}
Use environment variables for secrets: Never hardcode secrets in your code
import os from apifrom.security import jwt_required JWT_SECRET = os.environ.get("JWT_SECRET") @api(route="/protected", method="GET") @jwt_required(secret=JWT_SECRET) def protected_endpoint(request): return {"message": "Protected endpoint"}
Performance Checklistο
Enable caching: Cache responses to improve performance
from apifrom.middleware import CacheMiddleware app.add_middleware( CacheMiddleware( ttl=60, # Cache for 60 seconds max_size=1000 # Maximum number of cached responses ) )
Use connection pooling: Reuse connections to databases and external services
from apifrom.performance import ConnectionPool import aiohttp http_pool = ConnectionPool( factory=lambda: aiohttp.ClientSession(), min_size=5, max_size=20 )
Enable compression: Compress responses to reduce bandwidth usage
from apifrom.middleware import CompressionMiddleware app.add_middleware(CompressionMiddleware())
Implement pagination: Paginate large result sets
@api(route="/users", method="GET") def get_users(page: int = 1, limit: int = 10): offset = (page - 1) * limit users = db.get_users(offset=offset, limit=limit) total = db.count_users() return { "users": users, "page": page, "limit": limit, "total": total, "pages": (total + limit - 1) // limit }
Use asynchronous programming: Use async/await for I/O-bound operations
@api(route="/users", method="GET") async def get_users(): async with db_pool.acquire() as connection: rows = await connection.fetch("SELECT * FROM users") return [dict(row) for row in rows]
Optimize database queries: Use indexes and optimize queries
@api(route="/users", method="GET") async def get_users(search: str = None): query = "SELECT id, name, email FROM users" params = [] if search: query += " WHERE name ILIKE $1 OR email ILIKE $1" params.append(f"%{search}%") query += " ORDER BY id LIMIT 100" async with db_pool.acquire() as connection: rows = await connection.fetch(query, *params) return [dict(row) for row in rows]
Monitoring Checklistο
Set up logging: Configure proper logging for your application
import logging from apifrom.plugins import LoggingPlugin logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", handlers=[ logging.FileHandler("app.log"), logging.StreamHandler() ] ) app.plugin_manager.register(LoggingPlugin())
Add metrics collection: Collect metrics to monitor your API
from apifrom.monitoring import MetricsMiddleware app.add_middleware(MetricsMiddleware()) @api(route="/metrics", method="GET") def metrics(): return app.metrics.export_prometheus()
Set up health checks: Add health check endpoints
@api(route="/health", method="GET") def health_check(): # Check database connection db_status = check_database_connection() # Check external services external_services_status = check_external_services() status = "healthy" if db_status and external_services_status else "unhealthy" return { "status": status, "database": db_status, "external_services": external_services_status, "timestamp": datetime.datetime.now().isoformat() }
Configure error tracking: Set up error tracking to be notified of errors
from apifrom.middleware import ErrorHandlingMiddleware def log_error(request, exc, traceback): # Send error to error tracking service error_tracking_service.capture_exception(exc) app.add_middleware( ErrorHandlingMiddleware( debug=False, log_exceptions=True, on_error=log_error ) )
Deployment Environment Checklistο
Use environment-specific configuration: Configure your application differently for different environments
import os # Get environment ENV = os.environ.get("ENV", "development") # Create API with environment-specific configuration app = API( title="My API", version="1.0.0", debug=ENV == "development" ) # Add middleware based on environment if ENV == "production": app.add_middleware(SecurityHeadersMiddleware()) app.add_middleware(RateLimitMiddleware(limit=100, window=60))
Set up a process manager: Use a process manager to keep your application running
# Using PM2 pm2 start app.py --name "my-api" --interpreter python # Using Supervisor # Create a supervisor configuration file
Configure a reverse proxy: Use a reverse proxy like Nginx or Apache
# Nginx configuration example server { listen 80; server_name api.example.com; location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
Set up SSL/TLS: Configure SSL/TLS for HTTPS
# Nginx configuration with SSL server { listen 443 ssl; server_name api.example.com; ssl_certificate /path/to/certificate.crt; ssl_certificate_key /path/to/private.key; location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
Configure CORS headers in the reverse proxy: Add CORS headers in the reverse proxy
# Nginx configuration with CORS server { listen 443 ssl; server_name api.example.com; # SSL configuration location / { proxy_pass http://localhost:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # CORS headers add_header 'Access-Control-Allow-Origin' 'https://example.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } } }
Final Checklistο
Run tests: Ensure all tests pass before deployment
python -m pytest
Check for security vulnerabilities: Scan your dependencies for vulnerabilities
pip-audit
Verify documentation: Ensure your API documentation is up-to-date
# Make sure your OpenAPI documentation is accessible app = API( title="My API", version="1.0.0", docs_url="/docs", openapi_url="/openapi.json" )
Create a rollback plan: Have a plan for rolling back if something goes wrong
# Example: Keep the previous version of your application cp -r /path/to/app /path/to/app.backup
Set up monitoring alerts: Configure alerts for critical issues
# Example: Set up alerts for high error rates from apifrom.monitoring import AlertManager alert_manager = AlertManager() alert_manager.add_alert( name="high_error_rate", condition=lambda metrics: metrics.error_rate > 0.05, action=lambda: send_alert("High error rate detected!") )
Document deployment process: Document the deployment process for future reference
# Deployment Process 1. Run tests: `python -m pytest` 2. Build the application: `python setup.py sdist bdist_wheel` 3. Deploy to production: `scp dist/myapp-1.0.0.tar.gz user@server:/path/to/app` 4. Install on the server: `pip install myapp-1.0.0.tar.gz` 5. Restart the application: `systemctl restart myapp`
By following this checklist, youβll ensure that your APIFromAnything application is ready for production deployment with proper security, performance, and monitoring configurations.
By following this deployment guide, you can deploy your APIFromAnything applications to various environments with confidence, ensuring they are performant, scalable, and properly monitored.