from typing import Any, cast import splitio.client.factory as splitio_factory # type: ignore[import-untyped] IDENTITY_ID_ATTRIBUTE = "identity_id" FEATURE_ON = "on" # Supported features AUDIENCE_ENABLE_STRIPO_PLUGIN_V2 = "audience_enable_stripo_plugin_v2" class Features: def __init__( self, api_key: str, block_until_ready_timeout: int = 60, config: dict[str, Any] | None = None, ) -> None: config = config or {} self.block_until_ready_timeout = block_until_ready_timeout self._factory: splitio_factory.SplitFactory | None = ( splitio_factory.get_factory(api_key, config=config) # type: ignore[no-untyped-call] ) self._client: splitio_factory.Client | None = None @property def factory(self) -> splitio_factory.SplitFactory: if self._factory is None: raise RuntimeError("SplitioFactory not started.") return self._factory @property def client(self) -> splitio_factory.Client: if self._client is None: raise RuntimeError("SplitioClient not started.") return self._client def get_treatment( self, key: str, feature_flag_name: str, attributes: dict[str, Any] | None = None, ) -> str: treatment = cast( str, self.client.get_treatment( # type: ignore[no-untyped-call] key=key, feature_flag_name=feature_flag_name, attributes=attributes, ), ) return treatment def is_on_for_identity(self, feature_flag_name: str, *, identity_id: str) -> bool: if self._client is None: return False treatment = self.get_treatment( key=IDENTITY_ID_ATTRIBUTE, feature_flag_name=feature_flag_name, attributes={IDENTITY_ID_ATTRIBUTE: identity_id}, ) return treatment == FEATURE_ON def start(self) -> None: self.factory.block_until_ready(self.block_until_ready_timeout) # type: ignore[no-untyped-call] self._client = self.factory.client() # type: ignore[no-untyped-call] def close(self) -> None: self._client = None