55 lines
1.6 KiB
Python
55 lines
1.6 KiB
Python
from __future__ import annotations
|
|
|
|
import typing
|
|
from collections.abc import Sequence
|
|
from dataclasses import dataclass, field
|
|
from datetime import datetime
|
|
|
|
from openfeature.exception import GeneralError
|
|
|
|
__all__ = ["EvaluationContext", "get_evaluation_context", "set_evaluation_context"]
|
|
|
|
# https://openfeature.dev/specification/sections/evaluation-context#requirement-312
|
|
EvaluationContextAttributes = typing.Mapping[
|
|
str,
|
|
typing.Union[
|
|
bool,
|
|
int,
|
|
float,
|
|
str,
|
|
datetime,
|
|
Sequence["EvaluationContextAttributes"],
|
|
typing.Mapping[str, "EvaluationContextAttributes"],
|
|
],
|
|
]
|
|
|
|
|
|
@dataclass
|
|
class EvaluationContext:
|
|
targeting_key: typing.Optional[str] = None
|
|
attributes: EvaluationContextAttributes = field(default_factory=dict)
|
|
|
|
def merge(self, ctx2: EvaluationContext) -> EvaluationContext:
|
|
if not (self and ctx2):
|
|
return self or ctx2
|
|
|
|
attributes = {**self.attributes, **ctx2.attributes}
|
|
targeting_key = ctx2.targeting_key or self.targeting_key
|
|
|
|
return EvaluationContext(targeting_key=targeting_key, attributes=attributes)
|
|
|
|
|
|
def get_evaluation_context() -> EvaluationContext:
|
|
return _evaluation_context
|
|
|
|
|
|
def set_evaluation_context(evaluation_context: EvaluationContext) -> None:
|
|
global _evaluation_context
|
|
if evaluation_context is None:
|
|
raise GeneralError(error_message="No api level evaluation context")
|
|
_evaluation_context = evaluation_context
|
|
|
|
|
|
# need to be at the bottom, because of the definition order
|
|
_evaluation_context = EvaluationContext()
|