diff --git a/permit/api/base.py b/permit/api/base.py index f7fb517..faaabc9 100644 --- a/permit/api/base.py +++ b/permit/api/base.py @@ -163,8 +163,12 @@ def __init__(self, config: PermitConfig): def _build_http_client(self, endpoint_url: str = "", *, use_pdp: bool = False, **kwargs): optional_headers = {} - if self.config.proxy_facts_via_pdp and self.config.facts_sync_timeout: - optional_headers["X-Wait-Timeout"] = str(self.config.facts_sync_timeout) + if self.config.proxy_facts_via_pdp: + if self.config.facts_sync_timeout: + optional_headers["X-Wait-Timeout"] = str(self.config.facts_sync_timeout) + if self.config.facts_sync_timeout_policy: + optional_headers["X-Timeout-Policy"] = str(self.config.facts_sync_timeout_policy) + client_config = ClientConfig( base_url=self.config.pdp if use_pdp else self.config.api_url, headers={ diff --git a/permit/config.py b/permit/config.py index cc65923..f1d4fe7 100644 --- a/permit/config.py +++ b/permit/config.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import Literal, Optional from .api.context import ApiContext from .utils.pydantic_version import PYDANTIC_VERSION @@ -68,6 +68,10 @@ class PermitConfig(BaseModel): description="The amount of time in seconds to wait for facts to be available " "in the PDP cache before returning the response.", ) + facts_sync_timeout_policy: Optional[Literal["ignore", "fail"]] = Field( + default=None, + description="The policy to apply when the facts sync timeout is reached.", + ) class Config: arbitrary_types_allowed = True diff --git a/permit/permit.py b/permit/permit.py index b5025c8..56b1b29 100644 --- a/permit/permit.py +++ b/permit/permit.py @@ -1,6 +1,6 @@ import json from contextlib import contextmanager -from typing import Any, Dict, Generator, List, Optional +from typing import Any, Dict, Generator, List, Literal, Optional from loguru import logger from typing_extensions import Self @@ -49,7 +49,9 @@ def config(self): return self._config.copy() @contextmanager - def wait_for_sync(self, timeout: float = 10.0) -> Generator[Self, None, None]: + def wait_for_sync( + self, timeout: float = 10.0, policy: Optional[Literal["ignore", "fail"]] = None + ) -> Generator[Self, None, None]: """ Context manager that returns a client that is configured to wait for facts to be synced before proceeding. @@ -58,6 +60,9 @@ def wait_for_sync(self, timeout: float = 10.0) -> Generator[Self, None, None]: Args: timeout: The amount of time in seconds to wait for facts to be available in the PDP cache before returning the response. + policy: Weather to fail the request when the timeout is reached or ignore. + + Set None to keep the default policy set in the instance config or the default value of PDP. Yields: Permit: A Permit instance that is configured to wait for facts to be synced. @@ -71,6 +76,8 @@ def wait_for_sync(self, timeout: float = 10.0) -> Generator[Self, None, None]: return contextualized_config = self.config # this copies the config contextualized_config.facts_sync_timeout = timeout + if policy is not None: + contextualized_config.facts_sync_timeout_policy = policy yield self.__class__(contextualized_config) @property