95 lines
2.8 KiB
Python
95 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
PacketServer HTTP Server Runner
|
||
|
||
Standalone runner with --db support (local FileStorage or ZEO).
|
||
|
||
Examples:
|
||
python packetserver/runners/http_server.py --db /path/to/Data.fs --port 8080
|
||
python packetserver/runners/http_server.py --db zeo.host.com:8100
|
||
"""
|
||
|
||
import argparse
|
||
import sys
|
||
|
||
import uvicorn
|
||
import ZODB.FileStorage
|
||
import ZODB.DB
|
||
from packetserver.http.server import app
|
||
|
||
# Global DB and connection for reuse in the FastAPI dependency
|
||
_db = None
|
||
_connection = None
|
||
|
||
|
||
def open_database(db_arg: str) -> ZODB.DB.DB:
|
||
"""
|
||
Open a ZODB database from either a local FileStorage path or ZEO address.
|
||
Reuses the same logic as http_user_manager.py.
|
||
"""
|
||
if ":" in db_arg and db_arg.count(":") == 1 and "." in db_arg.split(":")[0]:
|
||
import ZEO
|
||
host, port_str = db_arg.split(":")
|
||
try:
|
||
port = int(port_str)
|
||
except ValueError:
|
||
raise ValueError(f"Invalid port in ZEO address: {db_arg}")
|
||
storage = ZEO.DB((host, port))
|
||
return storage
|
||
else:
|
||
# Local FileStorage path
|
||
storage = ZODB.FileStorage.FileStorage(db_arg)
|
||
return ZODB.DB(storage)
|
||
|
||
|
||
def get_db_connection():
|
||
"""Helper used in http/server.py dependency (get_current_http_user)"""
|
||
global _connection
|
||
if _connection is None or _connection.closed:
|
||
if _db is None:
|
||
raise RuntimeError("Database not opened – run the runner properly")
|
||
_connection = _db.open()
|
||
return _connection
|
||
|
||
|
||
# Monkey-patch the dependency helper so server.py can use it without changes
|
||
from packetserver.http import server
|
||
server.get_db_connection = get_db_connection # replaces any previous definition
|
||
|
||
|
||
def main():
|
||
parser = argparse.ArgumentParser(description="Run the PacketServer HTTP API server")
|
||
parser.add_argument("--db", required=True, help="DB path (local /path/to/Data.fs) or ZEO (host:port)")
|
||
parser.add_argument("--host", default="0.0.0.0", help="Bind host (default: 0.0.0.0)")
|
||
parser.add_argument("--port", type=int, default=8080, help="Port to listen on (default: 8080)")
|
||
parser.add_argument("--reload", action="store_true", help="Enable auto-reload during development")
|
||
|
||
args = parser.parse_args()
|
||
|
||
global _db
|
||
try:
|
||
_db = open_database(args.db)
|
||
print(f"Opened database: {args.db}")
|
||
except Exception as e:
|
||
print(f"Failed to open database {args.db}: {e}")
|
||
sys.exit(1)
|
||
|
||
# Open initial connection (will be reused/closed on shutdown)
|
||
get_db_connection()
|
||
|
||
try:
|
||
uvicorn.run(
|
||
"packetserver.http.server:app",
|
||
host=args.host,
|
||
port=args.port,
|
||
reload=args.reload,
|
||
)
|
||
finally:
|
||
if _connection and not _connection.closed:
|
||
_connection.close()
|
||
if _db:
|
||
_db.close()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main() |