orchestrata_ultimate.gateway.cli
Reference › orchestrata_ultimate › gateway › cli
cli is the command-line entry point of the gateway; nothing imports it, since it is started as a process. main loads .env defaults with _load_dotenv only when no explicit environment mapping is passed, configures structured logging from ORCHESTRATA_LOG_LEVEL and ORCHESTRATA_JSON_LOGS, and parses arguments with build_parser. The serve command runs run_serve, which builds a GatewayConfig from config, creates a WebSocketGateway from server, starts it, and blocks until cancelled, then stops the gateway. The version command prints the version, and any other input prints help and exits with status 1. Passing an env mapping keeps tests hermetic. Package narrative: gateway.
At a glance
| Source | src/orchestrata_ultimate/gateway/cli.py |
| Lines of code | 112 |
| Classes | 0 |
| Functions | 4 |
| Imports (internal) | orchestrata_ultimate.core.base.traces, orchestrata_ultimate.core.env_bootstrap, orchestrata_ultimate.core.logging, orchestrata_ultimate.gateway.config, orchestrata_ultimate.gateway.server |
| Imported by | none |
| Tests that import it | tests/gateway/test_cli.py, tests/gateway/test_cli_behavioral.py, tests/gateway/test_cli_coverage_wave.py, tests/gateway/test_cli_extra.py, tests/generated_gateway/test_cli_generated.py |
Class diagram
No classes; see Functions.
Dependency diagram
API
Functions
| Function | Signature | Summary |
|---|---|---|
_load_dotenv |
_load_dotenv() -> None |
Load the RUL-019 two-phase env contract (thin delegation). |
build_parser |
build_parser() -> argparse.ArgumentParser |
Build the CLI argument parser. |
run_serve traces, traces |
async run_serve(env: Mapping[str, str] | None = None) -> None |
Start the gateway server and block. |
main traces, traces |
main(argv: list[str] | None = None, env: Mapping[str, str] | None = None) -> None |
CLI entry point. |
Source
"""Thin CLI wrapper for the WebSocket gateway."""
import argparse
import asyncio
import logging
import os
import sys
from collections.abc import Mapping
from orchestrata_ultimate.core.base.traces import traces
from orchestrata_ultimate.core.env_bootstrap import load_env_contract
from orchestrata_ultimate.gateway.config import GatewayConfig
from orchestrata_ultimate.gateway.server import WebSocketGateway
def _load_dotenv() -> None:
"""Load the RUL-019 two-phase env contract (thin delegation).
This used to be a private ``.env``-only walk-up that never applied the
``env/<profile>.env`` overlay, so a gateway started from a bare shell
resolved the prod-BASE endpoints in ``.env``. Exactly ONE canonical
loader may exist (``scripts/check_env_contract.py`` enforces it); this
name is kept because it is the documented entry hook.
"""
load_env_contract()
logger = logging.getLogger(__name__)
VERSION = "0.7.0"
def build_parser() -> argparse.ArgumentParser:
"""Build the CLI argument parser.
Returns:
Configured ArgumentParser with serve and version
subcommands.
"""
parser = argparse.ArgumentParser(
prog="orchestrata-gateway",
description="SPEC-014 WebSocket Gateway",
)
sub = parser.add_subparsers(dest="command")
sub.add_parser("serve", help="Start the gateway")
sub.add_parser("version", help="Show version")
return parser
@traces(spec="004", reqs=["REQ-004-SUCC-005"])
@traces(
spec="014",
story="US-011",
reqs=["REQ-014-166", "REQ-014-170", "REQ-014-101"],
)
async def run_serve(env: Mapping[str, str] | None = None) -> None:
"""Start the gateway server and block.
Args:
env: Optional explicit environment mapping. When provided, configuration
is resolved from this mapping instead of ``os.environ``.
"""
config = GatewayConfig(environ=env)
gw = WebSocketGateway(config)
await gw.start()
try:
await asyncio.Future()
except asyncio.CancelledError:
logger.info("Gateway serve cancelled")
finally:
await gw.stop()
@traces(spec="004", reqs=["REQ-004-SUCC-006"])
@traces(spec="014", reqs=["REQ-014-102"])
def main(argv: list[str] | None = None, env: Mapping[str, str] | None = None) -> None:
"""CLI entry point.
Args:
argv: Command-line arguments (defaults to sys.argv[1:]).
env: Optional explicit environment mapping. When provided, configuration
and logging are resolved from this mapping instead of ``os.environ``.
"""
# Only load .env defaults into the process environment when no explicit
# environment is supplied. Tests pass a hermetic mapping and must not
# mutate ``os.environ``.
if env is None:
_load_dotenv()
# Activate the structured-logging facility (correlation_id / volk_id /
# per-volk trace fields) at the process entry. Human-readable by default;
# set ORCHESTRATA_JSON_LOGS=1 for one-JSON-object-per-line output.
from orchestrata_ultimate.core.logging import configure_logging
environ = os.environ if env is None else env
configure_logging(
level=environ.get("ORCHESTRATA_LOG_LEVEL", "INFO"),
json_format=environ.get("ORCHESTRATA_JSON_LOGS", "").strip().lower()
in ("1", "true", "yes", "on"),
)
parser = build_parser()
args = parser.parse_args(argv)
if args.command == "serve":
asyncio.run(run_serve(env=env))
elif args.command == "version":
print(f"orchestrata-gateway {VERSION}")
else:
parser.print_help()
sys.exit(1)
if __name__ == "__main__":
main()