107 lines
2.8 KiB
Python
107 lines
2.8 KiB
Python
from __future__ import annotations
|
|
|
|
import typing
|
|
from collections.abc import Sequence
|
|
from dataclasses import dataclass, field
|
|
|
|
from openfeature._backports.strenum import StrEnum
|
|
from openfeature.exception import ErrorCode, OpenFeatureError
|
|
|
|
if typing.TYPE_CHECKING: # pragma: no cover
|
|
# resolves a circular dependency in type annotations
|
|
from openfeature.hook import Hook, HookHints
|
|
|
|
|
|
__all__ = [
|
|
"FlagEvaluationDetails",
|
|
"FlagEvaluationOptions",
|
|
"FlagMetadata",
|
|
"FlagResolutionDetails",
|
|
"FlagType",
|
|
"Reason",
|
|
]
|
|
|
|
|
|
class FlagType(StrEnum):
|
|
BOOLEAN = "BOOLEAN"
|
|
STRING = "STRING"
|
|
OBJECT = "OBJECT"
|
|
FLOAT = "FLOAT"
|
|
INTEGER = "INTEGER"
|
|
|
|
|
|
class Reason(StrEnum):
|
|
CACHED = "CACHED"
|
|
DEFAULT = "DEFAULT"
|
|
DISABLED = "DISABLED"
|
|
ERROR = "ERROR"
|
|
SPLIT = "SPLIT"
|
|
STATIC = "STATIC"
|
|
STALE = "STALE"
|
|
TARGETING_MATCH = "TARGETING_MATCH"
|
|
UNKNOWN = "UNKNOWN"
|
|
|
|
|
|
FlagMetadata = typing.Mapping[str, typing.Union[bool, int, float, str]]
|
|
FlagValueType = typing.Union[
|
|
bool,
|
|
int,
|
|
float,
|
|
str,
|
|
Sequence["FlagValueType"],
|
|
typing.Mapping[str, "FlagValueType"],
|
|
]
|
|
|
|
T_co = typing.TypeVar("T_co", covariant=True)
|
|
|
|
|
|
@dataclass
|
|
class FlagEvaluationDetails(typing.Generic[T_co]):
|
|
flag_key: str
|
|
value: T_co
|
|
variant: typing.Optional[str] = None
|
|
flag_metadata: FlagMetadata = field(default_factory=dict)
|
|
reason: typing.Optional[typing.Union[str, Reason]] = None
|
|
error_code: typing.Optional[ErrorCode] = None
|
|
error_message: typing.Optional[str] = None
|
|
|
|
def get_exception(self) -> typing.Optional[OpenFeatureError]:
|
|
if self.error_code:
|
|
return ErrorCode.to_exception(self.error_code, self.error_message or "")
|
|
return None
|
|
|
|
|
|
@dataclass
|
|
class FlagEvaluationOptions:
|
|
hooks: list[Hook] = field(default_factory=list)
|
|
hook_hints: HookHints = field(default_factory=dict)
|
|
|
|
|
|
U_co = typing.TypeVar("U_co", covariant=True)
|
|
|
|
|
|
@dataclass
|
|
class FlagResolutionDetails(typing.Generic[U_co]):
|
|
value: U_co
|
|
error_code: typing.Optional[ErrorCode] = None
|
|
error_message: typing.Optional[str] = None
|
|
reason: typing.Optional[typing.Union[str, Reason]] = None
|
|
variant: typing.Optional[str] = None
|
|
flag_metadata: FlagMetadata = field(default_factory=dict)
|
|
|
|
def raise_for_error(self) -> None:
|
|
if self.error_code:
|
|
raise ErrorCode.to_exception(self.error_code, self.error_message or "")
|
|
return None
|
|
|
|
def to_flag_evaluation_details(self, flag_key: str) -> FlagEvaluationDetails[U_co]:
|
|
return FlagEvaluationDetails(
|
|
flag_key=flag_key,
|
|
value=self.value,
|
|
variant=self.variant,
|
|
flag_metadata=self.flag_metadata,
|
|
reason=self.reason,
|
|
error_code=self.error_code,
|
|
error_message=self.error_message,
|
|
)
|