Files
alpinebits_python/src/alpine_bits_python/run_api.py
2025-11-18 16:10:57 +01:00

116 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""Startup script for the Alpine Bits Python Server API.
This script:
1. Runs database migrations using Alembic
2. Starts the FastAPI application with uvicorn
Database migrations are run BEFORE starting the server to ensure the schema
is up to date. This approach works well with multiple workers since migrations
complete before any worker starts processing requests.
"""
import argparse
import sys
import uvicorn
from alpine_bits_python.run_migrations import run_migrations
def parse_args() -> argparse.Namespace:
"""Parse command line arguments for uvicorn configuration."""
parser = argparse.ArgumentParser(
description="Run Alpine Bits Python Server with database migrations"
)
parser.add_argument(
"--host",
type=str,
default="0.0.0.0",
help="Host to bind to (default: 0.0.0.0)",
)
parser.add_argument(
"--port",
type=int,
default=8080,
help="Port to bind to (default: 8080)",
)
parser.add_argument(
"--workers",
type=int,
default=1,
help="Number of worker processes (default: 1)",
)
parser.add_argument(
"--reload",
action="store_true",
default=False,
help="Enable auto-reload for development (default: False)",
)
parser.add_argument(
"--log-level",
type=str,
default="info",
choices=["critical", "error", "warning", "info", "debug", "trace"],
help="Log level (default: info)",
)
parser.add_argument(
"--access-log",
action="store_true",
default=False,
help="Enable access log (default: False)",
)
parser.add_argument(
"--forwarded-allow-ips",
type=str,
default="127.0.0.1",
help=(
"Comma-separated list of IPs to trust for proxy headers "
"(default: 127.0.0.1)"
),
)
parser.add_argument(
"--proxy-headers",
action="store_true",
default=False,
help="Enable proxy headers (X-Forwarded-* headers) (default: False)",
)
parser.add_argument(
"--no-server-header",
action="store_true",
default=False,
help="Disable Server header in responses (default: False)",
)
return parser.parse_args()
if __name__ == "__main__":
# Parse command line arguments
args = parse_args()
# Run database migrations before starting the server
# This ensures the schema is up to date before any workers start
print("Running database migrations...")
try:
run_migrations()
print("Database migrations completed successfully")
except Exception as e:
print(f"Failed to run migrations: {e}", file=sys.stderr)
sys.exit(1)
# Start the API server
print("Starting API server...")
uvicorn.run(
"alpine_bits_python.api:app",
host=args.host,
port=args.port,
workers=args.workers,
reload=args.reload,
log_level=args.log_level,
access_log=args.access_log,
forwarded_allow_ips=args.forwarded_allow_ips,
proxy_headers=args.proxy_headers,
server_header=not args.no_server_header,
)