mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-12-15 18:55:48 -07:00
Added Additional Scaffolds for API Endpoint Domains
This commit is contained in:
@@ -1,11 +1,4 @@
|
||||
"""API service adapters for the Borealis Engine runtime.
|
||||
|
||||
Stage 3 of the migration introduces blueprint registration that mirrors the
|
||||
behaviour of :mod:`Data.Server.server` by delegating to the existing domain
|
||||
modules under ``Data/Server/Modules``. Each adapter wires the Engine context
|
||||
into the legacy registration helpers so routes continue to function while
|
||||
configuration toggles control which API groups are exposed.
|
||||
"""
|
||||
"""API service adapters for the Borealis Engine runtime."""
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime as _dt
|
||||
@@ -15,10 +8,9 @@ import sqlite3
|
||||
import time
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
import os
|
||||
from typing import Any, Callable, Iterable, Mapping, Optional, Sequence
|
||||
|
||||
from flask import Blueprint, Flask, jsonify, request
|
||||
from flask import Blueprint, Flask, jsonify
|
||||
|
||||
from Modules.auth import jwt_service as jwt_service_module
|
||||
from Modules.auth.dpop import DPoPValidator
|
||||
@@ -29,11 +21,12 @@ from Modules.enrollment.nonce_store import NonceCache
|
||||
from Modules.tokens import routes as token_routes
|
||||
|
||||
from ...server import EngineContext
|
||||
from .authentication import register_auth
|
||||
|
||||
DEFAULT_API_GROUPS: Sequence[str] = ("tokens", "enrollment")
|
||||
DEFAULT_API_GROUPS: Sequence[str] = ("auth", "tokens", "enrollment")
|
||||
|
||||
_SERVER_SCOPE_PATTERN = re.compile(r"\b(?:scope|context|agent_context)=([A-Za-z0-9_-]+)", re.IGNORECASE)
|
||||
_SERVER_AGENT_ID_PATTERN = re.compile(r"\bagent_id=([^\s,]+)", re.IGNORECASE)
|
||||
_SERVER_SCOPE_PATTERN = re.compile(r"\\b(?:scope|context|agent_context)=([A-Za-z0-9_-]+)", re.IGNORECASE)
|
||||
_SERVER_AGENT_ID_PATTERN = re.compile(r"\\bagent_id=([^\\s,]+)", re.IGNORECASE)
|
||||
|
||||
|
||||
def _canonical_server_scope(raw: Optional[str]) -> Optional[str]:
|
||||
@@ -104,7 +97,7 @@ def _make_service_logger(base: Path, logger: logging.Logger) -> Callable[[str, s
|
||||
prefix_parts.append(f"[CONTEXT-{resolved_scope}]")
|
||||
prefix = "".join(prefix_parts)
|
||||
with path.open("a", encoding="utf-8") as handle:
|
||||
handle.write(f"[{timestamp}] {prefix} {msg}\n")
|
||||
handle.write(f"[{timestamp}] {prefix} {msg}\\n")
|
||||
except Exception:
|
||||
logger.debug("Failed to write service log entry", exc_info=True)
|
||||
|
||||
@@ -187,64 +180,11 @@ def _register_enrollment(app: Flask, adapters: LegacyServiceAdapters) -> None:
|
||||
|
||||
|
||||
_GROUP_REGISTRARS: Mapping[str, Callable[[Flask, LegacyServiceAdapters], None]] = {
|
||||
"auth": register_auth,
|
||||
"tokens": _register_tokens,
|
||||
"enrollment": _register_enrollment,
|
||||
}
|
||||
|
||||
LEGACY_APP_CACHE: Optional[Flask] = None
|
||||
|
||||
|
||||
def _load_legacy_app(context: EngineContext) -> Flask:
|
||||
global LEGACY_APP_CACHE
|
||||
if LEGACY_APP_CACHE is not None:
|
||||
return LEGACY_APP_CACHE
|
||||
|
||||
os.environ.setdefault("BOREALIS_DATABASE_PATH", context.database_path)
|
||||
if context.tls_cert_path:
|
||||
os.environ.setdefault("BOREALIS_TLS_CERT", context.tls_cert_path)
|
||||
if context.tls_key_path:
|
||||
os.environ.setdefault("BOREALIS_TLS_KEY", context.tls_key_path)
|
||||
if context.tls_bundle_path:
|
||||
os.environ.setdefault("BOREALIS_TLS_BUNDLE", context.tls_bundle_path)
|
||||
|
||||
try:
|
||||
from Data.Server import server as legacy_server # Local import to avoid heavy import when unused
|
||||
except ImportError as exc:
|
||||
raise RuntimeError("Legacy server module is unavailable; cannot enable fallback proxy.") from exc
|
||||
|
||||
LEGACY_APP_CACHE = legacy_server.app
|
||||
return LEGACY_APP_CACHE
|
||||
|
||||
|
||||
def _register_legacy_proxy(app: Flask, context: EngineContext) -> None:
|
||||
try:
|
||||
legacy_app = _load_legacy_app(context)
|
||||
except RuntimeError as exc:
|
||||
context.logger.warning("Legacy API fallback disabled: %s", exc)
|
||||
return
|
||||
blueprint = Blueprint("legacy_api_bridge", __name__)
|
||||
methods = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]
|
||||
|
||||
@blueprint.route("/api", defaults={"path": ""}, methods=methods)
|
||||
@blueprint.route("/api/<path:path>", methods=methods)
|
||||
def _legacy_passthrough(path: str):
|
||||
legacy_context = legacy_app.request_context(request.environ)
|
||||
legacy_context.push()
|
||||
try:
|
||||
request_path = request.path or f"/api/{path or ''}"
|
||||
context.logger.info(
|
||||
"Engine API routed to legacy handler: %s %s",
|
||||
request.method,
|
||||
request_path,
|
||||
)
|
||||
response = legacy_app.full_dispatch_request()
|
||||
finally:
|
||||
legacy_context.pop()
|
||||
return response
|
||||
|
||||
app.register_blueprint(blueprint)
|
||||
context.logger.info("Engine registered legacy API fallback proxy.")
|
||||
|
||||
|
||||
def _register_core(app: Flask, context: EngineContext) -> None:
|
||||
"""Register core utility endpoints that do not require legacy adapters."""
|
||||
@@ -279,5 +219,3 @@ def register_api(app: Flask, context: EngineContext) -> None:
|
||||
continue
|
||||
registrar(app, adapters)
|
||||
context.logger.info("Engine registered API group '%s'.", group)
|
||||
|
||||
_register_legacy_proxy(app, context)
|
||||
|
||||
Reference in New Issue
Block a user