Source code for demessaging.config.api

"""DASF API utilties for to access the configuration."""

# SPDX-FileCopyrightText: 2019-2024 Helmholtz Centre Potsdam GFZ German Research Centre for Geosciences
# SPDX-FileCopyrightText: 2020-2021 Helmholtz-Zentrum Geesthacht GmbH
# SPDX-FileCopyrightText: 2021-2024 Helmholtz-Zentrum hereon GmbH
#
# SPDX-License-Identifier: Apache-2.0

from __future__ import annotations

import inspect
from typing import Any, Callable, Optional, Type, TypeVar, Union

from demessaging.config.registry import ApiRegistry
from demessaging.utils import merge_config

T = TypeVar("T", bound=Callable[..., Any])


#: registry for the stuff that should be available in the generated client stub
registry = ApiRegistry()


[docs] def configure( js: Optional[str] = None, merge: bool = True, **kwargs ) -> Callable[[T], T]: """Configuration decorator for function or modules. Use this function as a decorator for classes or functions in the backend module like so:: >>> @configure(field_params={"a": {"gt": 0}}, returns={"gt": 0}) ... def sqrt(a: float) -> float: ... import math ... ... return math.sqrt(a) The available parameters for this function vary depending on what you are decorating. If you are decorating a class, your parameters must be valid for the :class:`ClassConfig`. If you are decorating a function, your parameters must be valid for a :class:`FunctionConfig`. Parameters ---------- js: Optional[str] A JSON-formatted string that can be used to setup the config. merge: bool If True (default), then the configuration will be merged with the existing configuration for the function (if existing) ``**kwargs`` Any keyword argument that can be used to setup the config. Notes ----- If you are specifying any ``kwargs``, your first argument (`js`) should be ``None``. """ from demessaging.config.backend import ClassConfig, FunctionConfig def decorator(obj: T) -> T: ConfClass: Union[Type[ClassConfig], Type[FunctionConfig]] if inspect.isclass(obj): ConfClass = ClassConfig else: ConfClass = FunctionConfig if js and kwargs: raise ValueError( "You can either specify a JSON string or keyword arguments, " "not both!" ) if js: config = ConfClass.model_validate_json(js) else: config = ConfClass(**kwargs) if merge and hasattr(obj, "__pulsar_config__"): old = obj.__pulsar_config__.model_dump() new = config.model_dump() config = ConfClass(**merge_config(old, new)) obj.__pulsar_config__ = config # type: ignore return obj return decorator