From 06e05d35094525d164026cae3d75601533cadaf3 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Sat, 5 Aug 2023 10:12:09 -0700 Subject: [PATCH] cleanup --- build/lib/litellm/__init__.py | 47 --- build/lib/litellm/integrations/__init__.py | 1 - build/lib/litellm/integrations/helicone.py | 73 ----- build/lib/litellm/main.py | 315 ------------------- build/lib/litellm/timeout.py | 83 ----- build/lib/litellm/utils.py | 333 --------------------- dist/litellm-0.1.229-py3-none-any.whl | Bin 12406 -> 0 bytes dist/litellm-0.1.229.tar.gz | Bin 11899 -> 0 bytes dist/litellm-0.1.2291-py3-none-any.whl | Bin 12414 -> 0 bytes dist/litellm-0.1.2291.tar.gz | Bin 11894 -> 0 bytes litellm.egg-info/PKG-INFO | 6 - litellm.egg-info/SOURCES.txt | 15 - litellm.egg-info/dependency_links.txt | 1 - litellm.egg-info/requires.txt | 8 - litellm.egg-info/top_level.txt | 1 - 15 files changed, 883 deletions(-) delete mode 100644 build/lib/litellm/__init__.py delete mode 100644 build/lib/litellm/integrations/__init__.py delete mode 100644 build/lib/litellm/integrations/helicone.py delete mode 100644 build/lib/litellm/main.py delete mode 100644 build/lib/litellm/timeout.py delete mode 100644 build/lib/litellm/utils.py delete mode 100644 dist/litellm-0.1.229-py3-none-any.whl delete mode 100644 dist/litellm-0.1.229.tar.gz delete mode 100644 dist/litellm-0.1.2291-py3-none-any.whl delete mode 100644 dist/litellm-0.1.2291.tar.gz delete mode 100644 litellm.egg-info/PKG-INFO delete mode 100644 litellm.egg-info/SOURCES.txt delete mode 100644 litellm.egg-info/dependency_links.txt delete mode 100644 litellm.egg-info/requires.txt delete mode 100644 litellm.egg-info/top_level.txt diff --git a/build/lib/litellm/__init__.py b/build/lib/litellm/__init__.py deleted file mode 100644 index 191a8ed260..0000000000 --- a/build/lib/litellm/__init__.py +++ /dev/null @@ -1,47 +0,0 @@ -success_callback = [] -failure_callback = [] -set_verbose=False -telemetry=True -max_tokens = 256 # OpenAI Defaults -retry = True # control tenacity retries. -####### PROXY PARAMS ################### configurable params if you use proxy models like Helicone -api_base = None -headers = None -####### COMPLETION MODELS ################### -open_ai_chat_completion_models = [ - "gpt-4", - "gpt-4-0613", - "gpt-4-32k", - "gpt-4-32k-0613", - ################# - "gpt-3.5-turbo", - "gpt-3.5-turbo-16k", - "gpt-3.5-turbo-0613", - "gpt-3.5-turbo-16k-0613", - 'gpt-3.5-turbo', - 'gpt-3.5-turbo-16k-0613', - 'gpt-3.5-turbo-16k' -] -open_ai_text_completion_models = [ - 'text-davinci-003' -] - -cohere_models = [ - 'command-nightly', -] - -anthropic_models = [ - "claude-2", - "claude-instant-1" -] - -model_list = open_ai_chat_completion_models + open_ai_text_completion_models + cohere_models + anthropic_models - -####### EMBEDDING MODELS ################### -open_ai_embedding_models = [ - 'text-embedding-ada-002' -] -from .timeout import timeout -from .utils import client, logging, exception_type # Import all the symbols from main.py -from .main import * # Import all the symbols from main.py -from .integrations import * \ No newline at end of file diff --git a/build/lib/litellm/integrations/__init__.py b/build/lib/litellm/integrations/__init__.py deleted file mode 100644 index b9742821a6..0000000000 --- a/build/lib/litellm/integrations/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import * \ No newline at end of file diff --git a/build/lib/litellm/integrations/helicone.py b/build/lib/litellm/integrations/helicone.py deleted file mode 100644 index 6b3d619659..0000000000 --- a/build/lib/litellm/integrations/helicone.py +++ /dev/null @@ -1,73 +0,0 @@ -#### What this does #### -# On success, logs events to Helicone -import dotenv, os -import requests -from anthropic import HUMAN_PROMPT, AI_PROMPT -dotenv.load_dotenv() # Loading env variables using dotenv -import traceback -class HeliconeLogger: - # Class variables or attributes - helicone_model_list = ["gpt", "claude"] - def __init__(self): - # Instance variables - self.provider_url = "https://api.openai.com/v1" - self.key = os.getenv('HELICONE_API_KEY') - - def claude_mapping(self, model, messages, response_obj): - prompt = f"{HUMAN_PROMPT}" - for message in messages: - if "role" in message: - if message["role"] == "user": - prompt += f"{HUMAN_PROMPT}{message['content']}" - else: - prompt += f"{AI_PROMPT}{message['content']}" - else: - prompt += f"{HUMAN_PROMPT}{message['content']}" - prompt += f"{AI_PROMPT}" - claude_provider_request = {"model": model, "prompt": prompt} - - claude_response_obj = {"completion": response_obj['choices'][0]['message']['content'], "model": model, "stop_reason": "stop_sequence"} - - return claude_provider_request, claude_response_obj - - def log_success(self, model, messages, response_obj, start_time, end_time, print_verbose): - # Method definition - try: - print_verbose(f"Helicone Logging - Enters logging function for model {model}") - model = model if any(accepted_model in model for accepted_model in self.helicone_model_list) else "gpt-3.5-turbo" - provider_request = {"model": model, "messages": messages} - - if "claude" in model: - provider_request, response_obj = self.claude_mapping(model=model, messages=messages, response_obj=response_obj) - - providerResponse = { - "json": response_obj, - "headers": {"openai-version": "2020-10-01"}, - "status": 200 - } - - # Code to be executed - url = "https://api.hconeai.com/oai/v1/log" - headers = { - 'Authorization': f'Bearer {self.key}', - 'Content-Type': 'application/json' - } - start_time_seconds = int(start_time.timestamp()) - start_time_milliseconds = int((start_time.timestamp() - start_time_seconds) * 1000) - end_time_seconds = int(end_time.timestamp()) - end_time_milliseconds = int((end_time.timestamp() - end_time_seconds) * 1000) - data = { - "providerRequest": {"url": self.provider_url, "json": provider_request, "meta": {"Helicone-Auth": f"Bearer {self.key}"}}, - "providerResponse": providerResponse, - "timing": {"startTime": {"seconds": start_time_seconds, "milliseconds": start_time_milliseconds}, "endTime": {"seconds": end_time_seconds, "milliseconds": end_time_milliseconds}} # {"seconds": .., "milliseconds": ..} - } - response = requests.post(url, headers=headers, json=data) - if response.status_code == 200: - print_verbose("Helicone Logging - Success!") - else: - print_verbose(f"Helicone Logging - Error Request was not successful. Status Code: {response.status_code}") - print_verbose(f"Helicone Logging - Error {response.text}") - except: - # traceback.print_exc() - print_verbose(f"Helicone Logging Error - {traceback.format_exc()}") - pass \ No newline at end of file diff --git a/build/lib/litellm/main.py b/build/lib/litellm/main.py deleted file mode 100644 index f35af8013a..0000000000 --- a/build/lib/litellm/main.py +++ /dev/null @@ -1,315 +0,0 @@ -import os, openai, cohere, replicate, sys -from typing import Any -from anthropic import Anthropic, HUMAN_PROMPT, AI_PROMPT -import traceback -from functools import partial -import dotenv -import traceback -import litellm -from litellm import client, logging, exception_type, timeout, success_callback, failure_callback -import random -import asyncio -from tenacity import ( - retry, - stop_after_attempt, - wait_random_exponential, -) # for exponential backoff -####### ENVIRONMENT VARIABLES ################### -dotenv.load_dotenv() # Loading env variables using dotenv - -def get_optional_params( - # 12 optional params - functions = [], - function_call = "", - temperature = 1, - top_p = 1, - n = 1, - stream = False, - stop = None, - max_tokens = float('inf'), - presence_penalty = 0, - frequency_penalty = 0, - logit_bias = {}, - user = "", - deployment_id = None -): - optional_params = {} - if functions != []: - optional_params["functions"] = functions - if function_call != "": - optional_params["function_call"] = function_call - if temperature != 1: - optional_params["temperature"] = temperature - if top_p != 1: - optional_params["top_p"] = top_p - if n != 1: - optional_params["n"] = n - if stream: - optional_params["stream"] = stream - if stop != None: - optional_params["stop"] = stop - if max_tokens != float('inf'): - optional_params["max_tokens"] = max_tokens - if presence_penalty != 0: - optional_params["presence_penalty"] = presence_penalty - if frequency_penalty != 0: - optional_params["frequency_penalty"] = frequency_penalty - if logit_bias != {}: - optional_params["logit_bias"] = logit_bias - if user != "": - optional_params["user"] = user - if deployment_id != None: - optional_params["deployment_id"] = user - return optional_params - -####### COMPLETION ENDPOINTS ################ -############################################# -async def acompletion(*args, **kwargs): - loop = asyncio.get_event_loop() - - # Use a partial function to pass your keyword arguments - func = partial(completion, *args, **kwargs) - - # Call the synchronous function using run_in_executor - return await loop.run_in_executor(None, func) - -@client -@retry(wait=wait_random_exponential(min=1, max=60), stop=stop_after_attempt(2), reraise=True, retry_error_callback=lambda retry_state: setattr(retry_state.outcome, 'retry_variable', litellm.retry)) # retry call, turn this off by setting `litellm.retry = False` -@timeout(60) ## set timeouts, in case calls hang (e.g. Azure) - default is 60s, override with `force_timeout` -def completion( - model, messages, # required params - # Optional OpenAI params: see https://platform.openai.com/docs/api-reference/chat/create - functions=[], function_call="", # optional params - temperature=1, top_p=1, n=1, stream=False, stop=None, max_tokens=float('inf'), - presence_penalty=0, frequency_penalty=0, logit_bias={}, user="", deployment_id=None, - # Optional liteLLM function params - *, return_async=False, api_key=None, force_timeout=60, azure=False, logger_fn=None, verbose=False - ): - try: - # check if user passed in any of the OpenAI optional params - optional_params = get_optional_params( - functions=functions, function_call=function_call, - temperature=temperature, top_p=top_p, n=n, stream=stream, stop=stop, max_tokens=max_tokens, - presence_penalty=presence_penalty, frequency_penalty=frequency_penalty, logit_bias=logit_bias, user=user, deployment_id=deployment_id - ) - if azure == True: - # azure configs - openai.api_type = "azure" - openai.api_base = litellm.api_base if litellm.api_base is not None else os.environ.get("AZURE_API_BASE") - openai.api_version = os.environ.get("AZURE_API_VERSION") - openai.api_key = api_key if api_key is not None else os.environ.get("AZURE_API_KEY") - ## LOGGING - logging(model=model, input=messages, azure=azure, logger_fn=logger_fn) - ## COMPLETION CALL - if litellm.headers: - response = openai.ChatCompletion.create( - engine=model, - messages = messages, - headers = litellm.headers, - **optional_params, - ) - else: - response = openai.ChatCompletion.create( - engine=model, - messages = messages, - **optional_params - ) - elif model in litellm.open_ai_chat_completion_models: - openai.api_type = "openai" - openai.api_base = litellm.api_base if litellm.api_base is not None else "https://api.openai.com/v1" - openai.api_version = None - openai.api_key = api_key if api_key is not None else os.environ.get("OPENAI_API_KEY") - ## LOGGING - logging(model=model, input=messages, azure=azure, logger_fn=logger_fn) - ## COMPLETION CALL - if litellm.headers: - response = openai.ChatCompletion.create( - model=model, - messages = messages, - headers = litellm.headers, - **optional_params - ) - else: - response = openai.ChatCompletion.create( - model=model, - messages = messages, - **optional_params - ) - elif model in litellm.open_ai_text_completion_models: - openai.api_type = "openai" - openai.api_base = litellm.api_base if litellm.api_base is not None else "https://api.openai.com/v1" - openai.api_version = None - openai.api_key = api_key if api_key is not None else os.environ.get("OPENAI_API_KEY") - prompt = " ".join([message["content"] for message in messages]) - ## LOGGING - logging(model=model, input=prompt, azure=azure, logger_fn=logger_fn) - ## COMPLETION CALL - if litellm.headers: - response = openai.Completion.create( - model=model, - prompt = prompt, - headers = litellm.headers, - ) - else: - response = openai.Completion.create( - model=model, - prompt = prompt - ) - elif "replicate" in model: - # replicate defaults to os.environ.get("REPLICATE_API_TOKEN") - # checking in case user set it to REPLICATE_API_KEY instead - if not os.environ.get("REPLICATE_API_TOKEN") and os.environ.get("REPLICATE_API_KEY"): - replicate_api_token = os.environ.get("REPLICATE_API_KEY") - os.environ["REPLICATE_API_TOKEN"] = replicate_api_token - elif api_key: - os.environ["REPLICATE_API_TOKEN"] = api_key - prompt = " ".join([message["content"] for message in messages]) - input = {"prompt": prompt} - if max_tokens != float('inf'): - input["max_length"] = max_tokens # for t5 models - input["max_new_tokens"] = max_tokens # for llama2 models - ## LOGGING - logging(model=model, input=input, azure=azure, additional_args={"max_tokens": max_tokens}, logger_fn=logger_fn) - ## COMPLETION CALL - output = replicate.run( - model, - input=input) - response = "" - for item in output: - response += item - new_response = { - "choices": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": response, - "role": "assistant" - } - } - ] - } - response = new_response - elif model in litellm.anthropic_models: - #anthropic defaults to os.environ.get("ANTHROPIC_API_KEY") - if api_key: - os.environ["ANTHROPIC_API_KEY"] = api_key - prompt = f"{HUMAN_PROMPT}" - for message in messages: - if "role" in message: - if message["role"] == "user": - prompt += f"{HUMAN_PROMPT}{message['content']}" - else: - prompt += f"{AI_PROMPT}{message['content']}" - else: - prompt += f"{HUMAN_PROMPT}{message['content']}" - prompt += f"{AI_PROMPT}" - anthropic = Anthropic() - # check if user passed in max_tokens != float('inf') - if max_tokens != float('inf'): - max_tokens_to_sample = max_tokens - else: - max_tokens_to_sample = litellm.max_tokens # default in Anthropic docs https://docs.anthropic.com/claude/reference/client-libraries - ## LOGGING - logging(model=model, input=prompt, azure=azure, additional_args={"max_tokens": max_tokens}, logger_fn=logger_fn) - ## COMPLETION CALL - completion = anthropic.completions.create( - model=model, - prompt=prompt, - max_tokens_to_sample=max_tokens_to_sample - ) - new_response = { - "choices": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": completion.completion, - "role": "assistant" - } - } - ] - } - print_verbose(f"new response: {new_response}") - response = new_response - elif model in litellm.cohere_models: - cohere_key = api_key if api_key is not None else os.environ.get("COHERE_API_KEY") - co = cohere.Client(cohere_key) - prompt = " ".join([message["content"] for message in messages]) - ## LOGGING - logging(model=model, input=prompt, azure=azure, logger_fn=logger_fn) - ## COMPLETION CALL - response = co.generate( - model=model, - prompt = prompt - ) - new_response = { - "choices": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": response[0].text, - "role": "assistant" - } - } - ], - } - response = new_response - else: - logging(model=model, input=messages, azure=azure, logger_fn=logger_fn) - args = locals() - raise ValueError(f"No valid completion model args passed in - {args}") - return response - except Exception as e: - # log the original exception - logging(model=model, input=messages, azure=azure, additional_args={"max_tokens": max_tokens}, logger_fn=logger_fn, exception=e) - ## Map to OpenAI Exception - raise exception_type(model=model, original_exception=e) - -### EMBEDDING ENDPOINTS #################### -@client -@timeout(60) ## set timeouts, in case calls hang (e.g. Azure) - default is 60s, override with `force_timeout` -def embedding(model, input=[], azure=False, force_timeout=60, logger_fn=None): - try: - response = None - if azure == True: - # azure configs - openai.api_type = "azure" - openai.api_base = os.environ.get("AZURE_API_BASE") - openai.api_version = os.environ.get("AZURE_API_VERSION") - openai.api_key = os.environ.get("AZURE_API_KEY") - ## LOGGING - logging(model=model, input=input, azure=azure, logger_fn=logger_fn) - ## EMBEDDING CALL - response = openai.Embedding.create(input=input, engine=model) - print_verbose(f"response_value: {str(response)[:50]}") - elif model in litellm.open_ai_embedding_models: - openai.api_type = "openai" - openai.api_base = "https://api.openai.com/v1" - openai.api_version = None - openai.api_key = os.environ.get("OPENAI_API_KEY") - ## LOGGING - logging(model=model, input=input, azure=azure, logger_fn=logger_fn) - ## EMBEDDING CALL - response = openai.Embedding.create(input=input, model=model) - print_verbose(f"response_value: {str(response)[:50]}") - else: - logging(model=model, input=input, azure=azure, logger_fn=logger_fn) - args = locals() - raise ValueError(f"No valid embedding model args passed in - {args}") - - return response - except Exception as e: - # log the original exception - logging(model=model, input=input, azure=azure, logger_fn=logger_fn, exception=e) - ## Map to OpenAI Exception - raise exception_type(model=model, original_exception=e) -####### HELPER FUNCTIONS ################ -## Set verbose to true -> ```litellm.set_verbose = True``` -def print_verbose(print_statement): - if litellm.set_verbose: - print(f"LiteLLM: {print_statement}") - if random.random() <= 0.3: - print("Get help - https://discord.com/invite/wuPM9dRgDw") - diff --git a/build/lib/litellm/timeout.py b/build/lib/litellm/timeout.py deleted file mode 100644 index 37bbbffc1a..0000000000 --- a/build/lib/litellm/timeout.py +++ /dev/null @@ -1,83 +0,0 @@ -""" -Module containing "timeout" decorator for sync and async callables. -""" - -import asyncio - -from concurrent import futures -from inspect import iscoroutinefunction -from functools import wraps -from threading import Thread -from openai.error import Timeout - - -def timeout( - timeout_duration: float = None, exception_to_raise = Timeout -): - """ - Wraps a function to raise the specified exception if execution time - is greater than the specified timeout. - - Works with both synchronous and asynchronous callables, but with synchronous ones will introduce - some overhead due to the backend use of threads and asyncio. - - :param float timeout_duration: Timeout duration in seconds. If none callable won't time out. - :param OpenAIError exception_to_raise: Exception to raise when the callable times out. - Defaults to TimeoutError. - :return: The decorated function. - :rtype: callable - """ - - def decorator(func): - @wraps(func) - def wrapper(*args, **kwargs): - async def async_func(): - return func(*args, **kwargs) - - thread = _LoopWrapper() - thread.start() - future = asyncio.run_coroutine_threadsafe(async_func(), thread.loop) - local_timeout_duration = timeout_duration - if "force_timeout" in kwargs: - local_timeout_duration = kwargs["force_timeout"] - try: - result = future.result(timeout=local_timeout_duration) - except futures.TimeoutError: - thread.stop_loop() - raise exception_to_raise(f"A timeout error occurred. The function call took longer than {local_timeout_duration} second(s).") - thread.stop_loop() - return result - - @wraps(func) - async def async_wrapper(*args, **kwargs): - local_timeout_duration = timeout_duration - if "force_timeout" in kwargs: - local_timeout_duration = kwargs["force_timeout"] - try: - value = await asyncio.wait_for( - func(*args, **kwargs), timeout=timeout_duration - ) - return value - except asyncio.TimeoutError: - raise exception_to_raise(f"A timeout error occurred. The function call took longer than {local_timeout_duration} second(s).") - - if iscoroutinefunction(func): - return async_wrapper - return wrapper - - return decorator - - -class _LoopWrapper(Thread): - def __init__(self): - super().__init__(daemon=True) - self.loop = asyncio.new_event_loop() - - def run(self) -> None: - self.loop.run_forever() - self.loop.call_soon_threadsafe(self.loop.close) - - def stop_loop(self): - for task in asyncio.all_tasks(self.loop): - task.cancel() - self.loop.call_soon_threadsafe(self.loop.stop) \ No newline at end of file diff --git a/build/lib/litellm/utils.py b/build/lib/litellm/utils.py deleted file mode 100644 index b0050226b8..0000000000 --- a/build/lib/litellm/utils.py +++ /dev/null @@ -1,333 +0,0 @@ -import dotenv, json, traceback, threading -import subprocess, os -import litellm, openai -import random, uuid, requests -import datetime -from openai.error import AuthenticationError, InvalidRequestError, RateLimitError, ServiceUnavailableError, OpenAIError -####### ENVIRONMENT VARIABLES ################### -dotenv.load_dotenv() # Loading env variables using dotenv -sentry_sdk_instance = None -capture_exception = None -add_breadcrumb = None -posthog = None -slack_app = None -alerts_channel = None -heliconeLogger = None -callback_list = [] -user_logger_fn = None -additional_details = {} - -def print_verbose(print_statement): - if litellm.set_verbose: - print(f"LiteLLM: {print_statement}") - if random.random() <= 0.3: - print("Get help - https://discord.com/invite/wuPM9dRgDw") - -####### LOGGING ################### -#Logging function -> log the exact model details + what's being sent | Non-Blocking -def logging(model, input, azure=False, additional_args={}, logger_fn=None, exception=None): - try: - model_call_details = {} - model_call_details["model"] = model - model_call_details["azure"] = azure - # log exception details - if exception: - model_call_details["original_exception"] = exception - - if litellm.telemetry: - safe_crash_reporting(model=model, exception=exception, azure=azure) # log usage-crash details. Do not log any user details. If you want to turn this off, set `litellm.telemetry=False`. - - model_call_details["input"] = input - # log additional call details -> api key, etc. - if azure == True or model in litellm.open_ai_chat_completion_models or model in litellm.open_ai_chat_completion_models or model in litellm.open_ai_embedding_models: - model_call_details["api_type"] = openai.api_type - model_call_details["api_base"] = openai.api_base - model_call_details["api_version"] = openai.api_version - model_call_details["api_key"] = openai.api_key - elif "replicate" in model: - model_call_details["api_key"] = os.environ.get("REPLICATE_API_TOKEN") - elif model in litellm.anthropic_models: - model_call_details["api_key"] = os.environ.get("ANTHROPIC_API_KEY") - elif model in litellm.cohere_models: - model_call_details["api_key"] = os.environ.get("COHERE_API_KEY") - model_call_details["additional_args"] = additional_args - ## User Logging -> if you pass in a custom logging function or want to use sentry breadcrumbs - print_verbose(f"Basic model call details: {model_call_details}") - if logger_fn and callable(logger_fn): - try: - logger_fn(model_call_details) # Expectation: any logger function passed in by the user should accept a dict object - except: - print_verbose(f"[Non-Blocking] Exception occurred while logging {traceback.format_exc()}") - except: - traceback.print_exc() - pass - -####### CLIENT ################### -# make it easy to log if completion/embedding runs succeeded or failed + see what happened | Non-Blocking -def client(original_function): - def function_setup(*args, **kwargs): #just run once to check if user wants to send their data anywhere - PostHog/Sentry/Slack/etc. - try: - global callback_list, add_breadcrumb - if (len(litellm.success_callback) > 0 or len(litellm.failure_callback) > 0) and len(callback_list) == 0: - callback_list = list(set(litellm.success_callback + litellm.failure_callback)) - set_callbacks(callback_list=callback_list,) - if add_breadcrumb: - add_breadcrumb( - category="litellm.llm_call", - message=f"Positional Args: {args}, Keyword Args: {kwargs}", - level="info", - ) - except: # DO NOT BLOCK running the function because of this - print_verbose(f"[Non-Blocking] {traceback.format_exc()}") - pass - - def wrapper(*args, **kwargs): - try: - function_setup(args, kwargs) - ## MODEL CALL - start_time = datetime.datetime.now() - result = original_function(*args, **kwargs) - end_time = datetime.datetime.now() - ## LOG SUCCESS - my_thread = threading.Thread(target=handle_success, args=(args, kwargs, result, start_time, end_time)) # don't interrupt execution of main thread - my_thread.start() - return result - except Exception as e: - traceback_exception = traceback.format_exc() - my_thread = threading.Thread(target=handle_failure, args=(e, traceback_exception, args, kwargs)) # don't interrupt execution of main thread - my_thread.start() - raise e - return wrapper - -####### HELPER FUNCTIONS ################ -def set_callbacks(callback_list): - global sentry_sdk_instance, capture_exception, add_breadcrumb, posthog, slack_app, alerts_channel, heliconeLogger - try: - for callback in callback_list: - if callback == "sentry": - try: - import sentry_sdk - except ImportError: - print_verbose("Package 'sentry_sdk' is missing. Installing it...") - subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'sentry_sdk']) - import sentry_sdk - sentry_sdk_instance = sentry_sdk - sentry_trace_rate = os.environ.get("SENTRY_API_TRACE_RATE") if "SENTRY_API_TRACE_RATE" in os.environ else "1.0" - sentry_sdk_instance.init(dsn=os.environ.get("SENTRY_API_URL"), traces_sample_rate=float(os.environ.get("SENTRY_API_TRACE_RATE"))) - capture_exception = sentry_sdk_instance.capture_exception - add_breadcrumb = sentry_sdk_instance.add_breadcrumb - elif callback == "posthog": - try: - from posthog import Posthog - except ImportError: - print_verbose("Package 'posthog' is missing. Installing it...") - subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'posthog']) - from posthog import Posthog - posthog = Posthog( - project_api_key=os.environ.get("POSTHOG_API_KEY"), - host=os.environ.get("POSTHOG_API_URL")) - elif callback == "slack": - try: - from slack_bolt import App - except ImportError: - print_verbose("Package 'slack_bolt' is missing. Installing it...") - subprocess.check_call([sys.executable, '-m', 'pip', 'install', 'slack_bolt']) - from slack_bolt import App - slack_app = App( - token=os.environ.get("SLACK_API_TOKEN"), - signing_secret=os.environ.get("SLACK_API_SECRET") - ) - alerts_channel = os.environ["SLACK_API_CHANNEL"] - print_verbose(f"Initialized Slack App: {slack_app}") - elif callback == "helicone": - from .integrations.helicone import HeliconeLogger - - heliconeLogger = HeliconeLogger() - except: - pass - - -def handle_failure(exception, traceback_exception, args, kwargs): - global sentry_sdk_instance, capture_exception, add_breadcrumb, posthog, slack_app, alerts_channel - try: - print_verbose(f"handle_failure args: {args}") - print_verbose(f"handle_failure kwargs: {kwargs}") - - success_handler = additional_details.pop("success_handler", None) - failure_handler = additional_details.pop("failure_handler", None) - - additional_details["Event_Name"] = additional_details.pop("failed_event_name", "litellm.failed_query") - print_verbose(f"self.failure_callback: {litellm.failure_callback}") - - print_verbose(f"additional_details: {additional_details}") - for callback in litellm.failure_callback: - try: - if callback == "slack": - slack_msg = "" - if len(kwargs) > 0: - for key in kwargs: - slack_msg += f"{key}: {kwargs[key]}\n" - if len(args) > 0: - for i, arg in enumerate(args): - slack_msg += f"LiteLLM_Args_{str(i)}: {arg}" - for detail in additional_details: - slack_msg += f"{detail}: {additional_details[detail]}\n" - slack_msg += f"Traceback: {traceback_exception}" - slack_app.client.chat_postMessage(channel=alerts_channel, text=slack_msg) - elif callback == "sentry": - capture_exception(exception) - elif callback == "posthog": - print_verbose(f"inside posthog, additional_details: {len(additional_details.keys())}") - ph_obj = {} - if len(kwargs) > 0: - ph_obj = kwargs - if len(args) > 0: - for i, arg in enumerate(args): - ph_obj["litellm_args_" + str(i)] = arg - for detail in additional_details: - ph_obj[detail] = additional_details[detail] - event_name = additional_details["Event_Name"] - print_verbose(f"ph_obj: {ph_obj}") - print_verbose(f"PostHog Event Name: {event_name}") - if "user_id" in additional_details: - posthog.capture(additional_details["user_id"], event_name, ph_obj) - else: # PostHog calls require a unique id to identify a user - https://posthog.com/docs/libraries/python - unique_id = str(uuid.uuid4()) - posthog.capture(unique_id, event_name) - print_verbose(f"successfully logged to PostHog!") - except: - print_verbose(f"Error Occurred while logging failure: {traceback.format_exc()}") - pass - - if failure_handler and callable(failure_handler): - call_details = { - "exception": exception, - "additional_details": additional_details - } - failure_handler(call_details) - pass - except: - pass - -def handle_success(args, kwargs, result, start_time, end_time): - global heliconeLogger - try: - success_handler = additional_details.pop("success_handler", None) - failure_handler = additional_details.pop("failure_handler", None) - additional_details["Event_Name"] = additional_details.pop("successful_event_name", "litellm.succes_query") - for callback in litellm.success_callback: - try: - if callback == "posthog": - ph_obj = {} - for detail in additional_details: - ph_obj[detail] = additional_details[detail] - event_name = additional_details["Event_Name"] - if "user_id" in additional_details: - posthog.capture(additional_details["user_id"], event_name, ph_obj) - else: # PostHog calls require a unique id to identify a user - https://posthog.com/docs/libraries/python - unique_id = str(uuid.uuid4()) - posthog.capture(unique_id, event_name, ph_obj) - pass - elif callback == "slack": - slack_msg = "" - for detail in additional_details: - slack_msg += f"{detail}: {additional_details[detail]}\n" - slack_app.client.chat_postMessage(channel=alerts_channel, text=slack_msg) - elif callback == "helicone": - print_verbose("reaches helicone for logging!") - model = args[0] if len(args) > 0 else kwargs["model"] - messages = args[1] if len(args) > 1 else kwargs["messages"] - heliconeLogger.log_success(model=model, messages=messages, response_obj=result, start_time=start_time, end_time=end_time, print_verbose=print_verbose) - except: - print_verbose(f"Success Callback Error - {traceback.format_exc()}") - pass - - if success_handler and callable(success_handler): - success_handler(args, kwargs) - pass - except: - print_verbose(f"Success Callback Error - {traceback.format_exc()}") - pass - - -def exception_type(model, original_exception): - try: - if isinstance(original_exception, OpenAIError): - # Handle the OpenAIError - raise original_exception - elif model: - error_str = str(original_exception) - if isinstance(original_exception, BaseException): - exception_type = type(original_exception).__name__ - else: - exception_type = "" - if "claude" in model: #one of the anthropics - if "status_code" in original_exception: - print_verbose(f"status_code: {original_exception.status_code}") - if original_exception.status_code == 401: - raise AuthenticationError(f"AnthropicException - {original_exception.message}") - elif original_exception.status_code == 400: - raise InvalidRequestError(f"AnthropicException - {original_exception.message}", f"{model}") - elif original_exception.status_code == 429: - raise RateLimitError(f"AnthropicException - {original_exception.message}") - elif "replicate" in model: - if "Incorrect authentication token" in error_str: - raise AuthenticationError(f"ReplicateException - {error_str}") - elif exception_type == "ModelError": - raise InvalidRequestError(f"ReplicateException - {error_str}", f"{model}") - elif "Request was throttled" in error_str: - raise RateLimitError(f"ReplicateException - {error_str}") - elif exception_type == "ReplicateError": ## ReplicateError implies an error on Replicate server side, not user side - raise ServiceUnavailableError(f"ReplicateException - {error_str}") - elif model == "command-nightly": #Cohere - if "invalid api token" in error_str or "No API key provided." in error_str: - raise AuthenticationError(f"CohereException - {error_str}") - elif "too many tokens" in error_str: - raise InvalidRequestError(f"CohereException - {error_str}", f"{model}") - elif "CohereConnectionError" in exception_type: # cohere seems to fire these errors when we load test it (1k+ messages / min) - raise RateLimitError(f"CohereException - {original_exception.message}") - raise original_exception # base case - return the original exception - else: - raise original_exception - except: - raise original_exception - -def safe_crash_reporting(model=None, exception=None, azure=None): - data = { - "model": model, - "exception": str(exception), - "azure": azure - } - threading.Thread(target=litellm_telemetry, args=(data,), daemon=True).start() - -def litellm_telemetry(data): - # Load or generate the UUID - uuid_file = 'litellm_uuid.txt' - try: - # Try to open the file and load the UUID - with open(uuid_file, 'r') as file: - uuid_value = file.read() - if uuid_value: - uuid_value = uuid_value.strip() - else: - raise FileNotFoundError - except FileNotFoundError: - # Generate a new UUID if the file doesn't exist or is empty - new_uuid = uuid.uuid4() - uuid_value = str(new_uuid) - with open(uuid_file, 'w') as file: - file.write(uuid_value) - - # Prepare the data to send to localhost:3000 - payload = { - 'uuid': uuid_value, - 'data': data - } - print_verbose(f"payload: {payload}") - try: - # Make the POST request to localhost:3000 - response = requests.post('https://litellm.berri.ai/logging', json=payload) - response.raise_for_status() # Raise an exception for HTTP errors - except requests.exceptions.RequestException as e: - # Handle any errors in the request - pass \ No newline at end of file diff --git a/dist/litellm-0.1.229-py3-none-any.whl b/dist/litellm-0.1.229-py3-none-any.whl deleted file mode 100644 index 5d4c7ac2c62de53b64bd9e25ab65aafffb4e515e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12406 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 diff --git a/dist/litellm-0.1.229.tar.gz b/dist/litellm-0.1.229.tar.gz deleted file mode 100644 index a157ac869ef56e27eb9b395a7138b7264e705eda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11899 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 AsQ>@~ diff --git a/dist/litellm-0.1.2291.tar.gz b/dist/litellm-0.1.2291.tar.gz deleted file mode 100644 index 1a286f7bf9cf3ad389f0b476c10909cb40f25e29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11894 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 diff --git a/litellm.egg-info/PKG-INFO b/litellm.egg-info/PKG-INFO deleted file mode 100644 index f01915a438..0000000000 --- a/litellm.egg-info/PKG-INFO +++ /dev/null @@ -1,6 +0,0 @@ -Metadata-Version: 2.1 -Name: litellm -Version: 0.1.2291 -Summary: Library to easily interface with LLM API providers -Author: BerriAI -License-File: LICENSE diff --git a/litellm.egg-info/SOURCES.txt b/litellm.egg-info/SOURCES.txt deleted file mode 100644 index 88f47e84f1..0000000000 --- a/litellm.egg-info/SOURCES.txt +++ /dev/null @@ -1,15 +0,0 @@ -LICENSE -README.md -pyproject.toml -setup.py -litellm/__init__.py -litellm/main.py -litellm/timeout.py -litellm/utils.py -litellm.egg-info/PKG-INFO -litellm.egg-info/SOURCES.txt -litellm.egg-info/dependency_links.txt -litellm.egg-info/requires.txt -litellm.egg-info/top_level.txt -litellm/integrations/__init__.py -litellm/integrations/helicone.py \ No newline at end of file diff --git a/litellm.egg-info/dependency_links.txt b/litellm.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789179..0000000000 --- a/litellm.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/litellm.egg-info/requires.txt b/litellm.egg-info/requires.txt deleted file mode 100644 index b59e88b895..0000000000 --- a/litellm.egg-info/requires.txt +++ /dev/null @@ -1,8 +0,0 @@ -openai -cohere -pytest -anthropic -replicate -python-dotenv -openai[datalib] -tenacity diff --git a/litellm.egg-info/top_level.txt b/litellm.egg-info/top_level.txt deleted file mode 100644 index 8e637fbf56..0000000000 --- a/litellm.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -litellm