ai-scheduling-platform / dev_server.py
arcshukla's picture
refactoring and review comments
3a89a62
Raw
History Blame Contribute Delete
1.76 kB
"""
Local dev server — Windows-safe SelectorEventLoop runner.
Use this instead of `uvicorn main:app` on Windows. It guarantees SelectorEventLoop,
which psycopg_async requires (ProactorEventLoop, the Windows default, fails with psycopg3).
reload=False is intentional — reload spawns subprocesses that lose the loop.
Reads host and port from APP_BASE_URL in .env (e.g. http://192.168.1.36:7880).
Reads log level from LOG_LEVEL in .env.
Usage:
uv run python dev_server.py
Note: main.py is the FastAPI app entry point — used by uvicorn directly and by HF Spaces.
This script is only needed for local Windows development.
"""
import asyncio
import os
import selectors
import sys
from urllib.parse import urlparse
from dotenv import load_dotenv
load_dotenv()
import uvicorn
def _host_port_from_base_url(url: str) -> tuple[str, int]:
parsed = urlparse(url)
host = parsed.hostname or "127.0.0.1"
port = parsed.port or 8000
return host, port
HOST, PORT = _host_port_from_base_url(os.getenv("APP_BASE_URL", "http://127.0.0.1:8000"))
LOG_LEVEL = os.getenv("LOG_LEVEL", "info").lower()
async def _serve():
config = uvicorn.Config("main:app", host=HOST, port=PORT, log_level=LOG_LEVEL)
server = uvicorn.Server(config)
await server.serve()
if __name__ == "__main__":
try:
if sys.platform == "win32":
# loop_factory requires Python 3.12+ — we're on 3.13, safe.
asyncio.run(
_serve(),
loop_factory=lambda: asyncio.SelectorEventLoop(selectors.SelectSelector()),
)
else:
asyncio.run(_serve())
except KeyboardInterrupt:
pass # Ctrl+C — server already shut down cleanly via uvicorn's signal handler