Coverage for / home / runner / work / bijux-cli / bijux-cli / src / bijux_cli / services / contracts.py: 100%
20 statements
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-26 17:59 +0000
« prev ^ index » next coverage.py v7.13.2, created at 2026-01-26 17:59 +0000
1# SPDX-License-Identifier: Apache-2.0
2# Copyright © 2025 Bijan Mousavi
4"""Service-level protocol contracts."""
6from __future__ import annotations
8from collections.abc import Coroutine
9from typing import Any, Protocol, Self, runtime_checkable
11from structlog.typing import FilteringBoundLogger
13from bijux_cli.core.enums import LogLevel
16@runtime_checkable
17class TelemetryProtocol(Protocol):
18 """Fire-and-forget telemetry sink."""
20 def event(
21 self, name: str, payload: dict[str, Any]
22 ) -> None | Coroutine[Any, Any, None]:
23 """Record a telemetry event."""
24 ...
26 def flush(self) -> None:
27 """Flush buffered events."""
28 ...
30 def enable(self) -> None:
31 """Enable telemetry output."""
32 ...
35@runtime_checkable
36class ObservabilityProtocol(Protocol):
37 """Structured logging facade."""
39 @classmethod
40 def setup(cls, *, log_level: LogLevel, telemetry: TelemetryProtocol) -> Self:
41 """Configure and return a logging instance."""
42 ...
44 def get_logger(self) -> FilteringBoundLogger | None:
45 """Return the bound logger instance."""
46 ...
48 def bind(self, **_kv: Any) -> Self:
49 """Bind context keys for future log entries."""
50 ...
52 def log(self, level: str, msg: str, *, extra: dict[str, Any] | None) -> Self:
53 """Emit a structured log entry."""
54 ...
56 def close(self) -> None:
57 """Close the logger and release resources."""
58 ...
60 def set_telemetry(self, telemetry: TelemetryProtocol) -> Self:
61 """Attach a telemetry sink."""
62 ...
65__all__ = [
66 "ObservabilityProtocol",
67 "TelemetryProtocol",
68]