"""Deployable stdlib service entrypoint for phase-memory.""" from __future__ import annotations import argparse from dataclasses import dataclass from typing import Sequence from wsgiref.simple_server import make_server from .service import RuntimeConfig from .service_binding import ServiceBinding, service_binding_from_config SERVICE_APP_SCHEMA = "phase_memory.service.app.v1" @dataclass(frozen=True) class ServiceAppConfig: host: str = "127.0.0.1" port: int = 8080 local_store_path: str = ".phase-memory-local" def runtime_config(self) -> RuntimeConfig: return RuntimeConfig(local_store_path=self.local_store_path) def to_dict(self) -> dict: return { "host": self.host, "port": self.port, "local_store_path": self.local_store_path, } def build_service_binding(config: ServiceAppConfig | None = None) -> ServiceBinding: config = config or ServiceAppConfig() return service_binding_from_config(config.runtime_config()) def service_app_metadata(config: ServiceAppConfig | None = None) -> dict: config = config or ServiceAppConfig() binding = build_service_binding(config) readiness = binding.readiness() return { "schema_version": SERVICE_APP_SCHEMA, "config": config.to_dict(), "readiness": readiness, "routes": { "health": "/health", "readiness": "/ready", "contracts": "/contracts", "operations": "/operations/{operation}", }, } def create_wsgi_app(config: ServiceAppConfig | None = None): return build_service_binding(config).as_wsgi_app() def serve(config: ServiceAppConfig | None = None) -> None: config = config or ServiceAppConfig() app = create_wsgi_app(config) with make_server(config.host, config.port, app) as server: server.serve_forever() def main(argv: Sequence[str] | None = None) -> int: parser = argparse.ArgumentParser(description="Run the phase-memory service binding.") parser.add_argument("--host", default="127.0.0.1") parser.add_argument("--port", type=int, default=8080) parser.add_argument("--store", default=".phase-memory-local") parser.add_argument("--check", action="store_true", help="Build the app and return readiness status without listening.") args = parser.parse_args(list(argv) if argv is not None else None) config = ServiceAppConfig(host=args.host, port=args.port, local_store_path=args.store) if args.check: return 0 if service_app_metadata(config)["readiness"]["ok"] else 1 serve(config) return 0