Coverage for src / lexigram / contracts / auth / policy.py: 100%
9 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-19 05:41 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-19 05:41 +0800
1"""Policy-store protocol for the ABAC policy engine.
3Defines :class:`PolicyStoreProtocol`, the contract for loading, persisting, and
4querying ABAC policies. Multiple back-ends (in-memory, YAML file,
5database, remote service) can satisfy this protocol through structural
6subtyping, making the :class:`PolicyEngine` independently testable.
7"""
9from __future__ import annotations
11from typing import Any, Protocol, runtime_checkable
13__all__ = ["PolicyStoreProtocol"]
16@runtime_checkable
17class PolicyStoreProtocol(Protocol):
18 """Storage protocol for ABAC authorization policies.
20 Implementations are responsible for persisting and retrieving
21 :class:`~lexigram.auth.policies.types.Policy` objects. The
22 concrete ``Policy`` type is referenced as ``Any`` here so that the
23 contracts package remains dependency-free.
25 Example::
27 class YAMLPolicyStore:
28 def __init__(self, path: Path) -> None:
29 self._path = path
31 async def load_policies(self) -> list[Any]:
32 with open(self._path) as f:
33 raw = yaml.safe_load(f)
34 return [Policy(**p) for p in raw["policies"]]
36 async def save_policy(self, policy: Any) -> None:
37 ... # Append/update in YAML file
38 """
40 async def load_policies(self) -> list[Any]:
41 """Load all policies from the store.
43 Returns:
44 List of policy objects ordered by their natural storage order.
45 """
46 ...
48 async def save_policy(self, policy: Any) -> None:
49 """Persist a single policy.
51 Args:
52 policy: The policy object to save. Implementations should
53 generate the ``id`` field if it is absent.
54 """
55 ...
57 async def delete_policy(self, policy_id: str) -> bool:
58 """Remove a policy by its identifier.
60 Args:
61 policy_id: Unique policy identifier.
63 Returns:
64 True if the policy was found and removed, False otherwise.
65 """
66 ...
68 async def get_policy(self, policy_id: str) -> Any | None:
69 """Retrieve a single policy by ID.
71 Args:
72 policy_id: Unique policy identifier.
74 Returns:
75 The policy if found, None otherwise.
76 """
77 ...