From 4a52a71956a8d46fcb7294ac71734504bb09bcc2 Mon Sep 17 00:00:00 2001 From: S. Solomon Darnell Date: Fri, 28 Mar 2025 21:52:21 -0500 Subject: two version of R2R are here --- .../litellm/integrations/opik/utils.py | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 .venv/lib/python3.12/site-packages/litellm/integrations/opik/utils.py (limited to '.venv/lib/python3.12/site-packages/litellm/integrations/opik/utils.py') diff --git a/.venv/lib/python3.12/site-packages/litellm/integrations/opik/utils.py b/.venv/lib/python3.12/site-packages/litellm/integrations/opik/utils.py new file mode 100644 index 00000000..7b3b64dc --- /dev/null +++ b/.venv/lib/python3.12/site-packages/litellm/integrations/opik/utils.py @@ -0,0 +1,110 @@ +import configparser +import os +import time +from typing import Dict, Final, List, Optional + +CONFIG_FILE_PATH_DEFAULT: Final[str] = "~/.opik.config" + + +def create_uuid7(): + ns = time.time_ns() + last = [0, 0, 0, 0] + + # Simple uuid7 implementation + sixteen_secs = 16_000_000_000 + t1, rest1 = divmod(ns, sixteen_secs) + t2, rest2 = divmod(rest1 << 16, sixteen_secs) + t3, _ = divmod(rest2 << 12, sixteen_secs) + t3 |= 7 << 12 # Put uuid version in top 4 bits, which are 0 in t3 + + # The next two bytes are an int (t4) with two bits for + # the variant 2 and a 14 bit sequence counter which increments + # if the time is unchanged. + if t1 == last[0] and t2 == last[1] and t3 == last[2]: + # Stop the seq counter wrapping past 0x3FFF. + # This won't happen in practice, but if it does, + # uuids after the 16383rd with that same timestamp + # will not longer be correctly ordered but + # are still unique due to the 6 random bytes. + if last[3] < 0x3FFF: + last[3] += 1 + else: + last[:] = (t1, t2, t3, 0) + t4 = (2 << 14) | last[3] # Put variant 0b10 in top two bits + + # Six random bytes for the lower part of the uuid + rand = os.urandom(6) + return f"{t1:>08x}-{t2:>04x}-{t3:>04x}-{t4:>04x}-{rand.hex()}" + + +def _read_opik_config_file() -> Dict[str, str]: + config_path = os.path.expanduser(CONFIG_FILE_PATH_DEFAULT) + + config = configparser.ConfigParser() + config.read(config_path) + + config_values = { + section: dict(config.items(section)) for section in config.sections() + } + + if "opik" in config_values: + return config_values["opik"] + + return {} + + +def _get_env_variable(key: str) -> Optional[str]: + env_prefix = "opik_" + return os.getenv((env_prefix + key).upper(), None) + + +def get_opik_config_variable( + key: str, user_value: Optional[str] = None, default_value: Optional[str] = None +) -> Optional[str]: + """ + Get the configuration value of a variable, order priority is: + 1. user provided value + 2. environment variable + 3. Opik configuration file + 4. default value + """ + # Return user provided value if it is not None + if user_value is not None: + return user_value + + # Return environment variable if it is not None + env_value = _get_env_variable(key) + if env_value is not None: + return env_value + + # Return value from Opik configuration file if it is not None + config_values = _read_opik_config_file() + + if key in config_values: + return config_values[key] + + # Return default value if it is not None + return default_value + + +def create_usage_object(usage): + usage_dict = {} + + if usage.completion_tokens is not None: + usage_dict["completion_tokens"] = usage.completion_tokens + if usage.prompt_tokens is not None: + usage_dict["prompt_tokens"] = usage.prompt_tokens + if usage.total_tokens is not None: + usage_dict["total_tokens"] = usage.total_tokens + return usage_dict + + +def _remove_nulls(x): + x_ = {k: v for k, v in x.items() if v is not None} + return x_ + + +def get_traces_and_spans_from_payload(payload: List): + traces = [_remove_nulls(x) for x in payload if "type" not in x] + spans = [_remove_nulls(x) for x in payload if "type" in x] + return traces, spans -- cgit v1.2.3