import logging import os import sys from collections.abc import Callable from typing import Any, cast import env shutdown_hook: list[Callable[[], None]] = [] logging.basicConfig(stream=sys.stderr, level=logging.DEBUG if env.DEV else logging.INFO) logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("httpcore").setLevel(logging.WARNING) LOGGER = logging.getLogger("XPost") class Result[V, E]: _value: V _error: E | None def __init__(self, value: V, err: E) -> None: self._value = value self._error = err def error(self) -> E: if self._error is None: raise ValueError("self._error not set!") return self._error def value(self) -> V: return self._value def is_ok(self) -> bool: return self._error is None @classmethod def err(cls, err: E) -> "Result[V, E]": return cast("Result[V, E]", Result(None, err)) @classmethod def ok(cls, val: V) -> "Result[V, E]": return cast("Result[V, E]", Result(val, None)) def normalize_service_url(url: str) -> str: if not url.startswith("https://") and not url.startswith("http://"): raise ValueError(f"Invalid service url {url}! Must start with http/https!") return url[:-1] if url.endswith("/") else url def _read_env(data: Any) -> None: match data: case dict(): read_env(data) case list(): for v in data: _read_env(v) case _: pass def read_env(data: dict[str, Any]) -> None: keys = list(data.keys()) for key in keys: val = data[key] match val: case str(): if val.startswith("env:"): envval = os.environ.get(val[4:]) if envval is None: del data[key] else: data[key] = envval case _: _read_env(val)