truing up
This commit is contained in:
0
packetserver/http/database.py
Normal file
0
packetserver/http/database.py
Normal file
@@ -1,15 +1,95 @@
|
|||||||
# runners/http_server.py
|
#!/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 uvicorn
|
||||||
|
import ZODB.FileStorage
|
||||||
|
import ZODB.DB
|
||||||
from packetserver.http.server import app
|
from packetserver.http.server import app
|
||||||
from packetserver.database import open_db # adjust to your actual DB opener
|
|
||||||
|
|
||||||
# Ensure DB is open (same as main server)
|
# Global DB and connection for reuse in the FastAPI dependency
|
||||||
open_db() # or however you initialize the global DB connection
|
_db = None
|
||||||
|
_connection = None
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
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.client_storage(host, port)
|
||||||
|
return ZODB.DB(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(
|
uvicorn.run(
|
||||||
"packetserver.http.server:app",
|
"packetserver.http.server:app",
|
||||||
host="0.0.0.0",
|
host=args.host,
|
||||||
port=8080,
|
port=args.port,
|
||||||
reload=True, # convenient during development
|
reload=args.reload,
|
||||||
)
|
)
|
||||||
|
finally:
|
||||||
|
if _connection and not _connection.closed:
|
||||||
|
_connection.close()
|
||||||
|
if _db:
|
||||||
|
_db.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -5,8 +5,8 @@ PacketServer HTTP User Management CLI
|
|||||||
Supports local FileStorage or ZEO databases via --db.
|
Supports local FileStorage or ZEO databases via --db.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
python runners/http_user_manager.py --db /path/to/Data.fs add W1AW secret
|
python packetserver/runners/http_user_manager.py --db /path/to/Data.fs add W1AW secret
|
||||||
python runners/http_user_manager.py --db zeo.host.com:8100 list
|
python packetserver/runners/http_user_manager.py --db zeo.host.com:8100 list
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
@@ -21,7 +21,9 @@ from persistent.mapping import PersistentMapping
|
|||||||
|
|
||||||
# Import our HTTP package internals
|
# Import our HTTP package internals
|
||||||
from packetserver.http.auth import HttpUser, ph # ph = PasswordHasher
|
from packetserver.http.auth import HttpUser, ph # ph = PasswordHasher
|
||||||
from packetserver.http.database import HTTP_USERS_KEY
|
|
||||||
|
# Define the key directly here (no separate database.py module needed)
|
||||||
|
HTTP_USERS_KEY = "httpUsers"
|
||||||
|
|
||||||
|
|
||||||
def open_database(db_arg: str) -> ZODB.DB.DB:
|
def open_database(db_arg: str) -> ZODB.DB.DB:
|
||||||
@@ -46,6 +48,7 @@ def open_database(db_arg: str) -> ZODB.DB.DB:
|
|||||||
def get_or_create_http_users(root):
|
def get_or_create_http_users(root):
|
||||||
if HTTP_USERS_KEY not in root:
|
if HTTP_USERS_KEY not in root:
|
||||||
root[HTTP_USERS_KEY] = PersistentMapping()
|
root[HTTP_USERS_KEY] = PersistentMapping()
|
||||||
|
transaction.commit() # safe during initial creation
|
||||||
return root[HTTP_USERS_KEY]
|
return root[HTTP_USERS_KEY]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user