From 2c0280cff36ed131d1350710b5ddff0c40e49995 Mon Sep 17 00:00:00 2001 From: Krrish Dholakia Date: Fri, 13 Oct 2023 15:14:14 -0700 Subject: [PATCH] fix(proxy_cli): add logs and config --- .gitignore | 2 + litellm/__pycache__/__init__.cpython-311.pyc | Bin 13559 -> 13611 bytes litellm/__pycache__/utils.cpython-311.pyc | Bin 160512 -> 160994 bytes litellm/proxy/proxy_cli.py | 74 ++++++++++++++++++- litellm/proxy/proxy_server.py | 9 ++- 5 files changed, 77 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 3bc0cdc13..3009cea1c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ bun.lockb litellm_results.jsonl secrets.toml .gitignore +litellm/proxy/litellm_secrets.toml +litellm/proxy/api_log.json diff --git a/litellm/__pycache__/__init__.cpython-311.pyc b/litellm/__pycache__/__init__.cpython-311.pyc index 3e9cf4ee774b984fe6e7f6ea0531b5b726e8fe3b..9469b8889171690d527950dc35e0268c0621e602 100644 GIT binary patch delta 101 zcmeyKxjKt?IWI340}xoA&`8}dkyny&(L{B(iS2R|tIdGq#{JG3Tns!63?G;o85ti; z=GPRTtgPuEtE=C@H-TkB=nUfp95ZaMh-zLD(7M2&4@4Ik^e2~TDoifdl;6Bs(}x=X DLmwZ) delta 106 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 delta 7531 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 diff --git a/litellm/proxy/proxy_cli.py b/litellm/proxy/proxy_cli.py index b32d83630..f1bb7abee 100644 --- a/litellm/proxy/proxy_cli.py +++ b/litellm/proxy/proxy_cli.py @@ -1,8 +1,16 @@ import click -import subprocess, traceback +import subprocess, traceback, json import os, sys -import random +import random, appdirs +from datetime import datetime from dotenv import load_dotenv +import operator + +config_filename = "litellm.secrets.toml" +pkg_config_filename = "template.secrets.toml" +# Using appdirs to determine user-specific config path +config_dir = appdirs.user_config_dir("litellm") +user_config_path = os.path.join(config_dir, config_filename) load_dotenv() from importlib import resources @@ -15,6 +23,37 @@ def run_ollama_serve(): with open(os.devnull, 'w') as devnull: process = subprocess.Popen(command, stdout=devnull, stderr=devnull) +def open_config(file_path=None): + # Create the .env file if it doesn't exist + if file_path: + # Ensure the user-specific directory exists + os.makedirs(config_dir, exist_ok=True) + # Copying the file using shutil.copy + try: + shutil.copy(file_path, user_config_path) + with open(file_path) as f: + print(f"Source file: {file_path}") + print(f.read()) + + with open(user_config_path) as f: + print(f"Dest file: {user_config_path}") + print(f.read()) + except Exception as e: + print(f"Failed to copy {file_path}: {e}") + else: + if os.path.exists(user_config_path): + if os.path.getsize(user_config_path) == 0: + print(f"{user_config_path} exists but is empty") + print(f"To create a config (save keys, modify model prompt), copy the template located here: https://docs.litellm.ai/docs/proxy_server") + else: + with open(user_config_path) as f: + print(f"Saved Config file: {user_config_path}") + print(f.read()) + else: + print(f"{user_config_path} hasn't been created yet.") + print(f"To create a config (save keys, modify model prompt), copy the template located here: https://docs.litellm.ai/docs/proxy_server") + print(f"LiteLLM: config location - {user_config_path}") + def clone_subfolder(repo_url, subfolder, destination): # Clone the full repo repo_name = repo_url.split('/')[-1] @@ -54,13 +93,19 @@ def is_port_in_use(port): @click.option('--drop_params', is_flag=True, help='Drop any unmapped params') @click.option('--create_proxy', is_flag=True, help='Creates a local OpenAI-compatible server template') @click.option('--add_function_to_prompt', is_flag=True, help='If function passed but unsupported, pass it as prompt') +@click.option('--config', '-c', is_flag=True, help='Configure Litellm') +@click.option('--file', '-f', help='Path to config file') @click.option('--max_budget', default=None, type=float, help='Set max budget for API calls - works for hosted models like OpenAI, TogetherAI, Anthropic, etc.`') @click.option('--telemetry', default=True, type=bool, help='Helps us know if people are using this feature. Turn this off by doing `--telemetry False`') +@click.option('--logs', flag_value=False, type=int, help='Gets the "n" most recent logs. By default gets most recent log.') @click.option('--test', flag_value=True, help='proxy chat completions url to make a test request to') @click.option('--local', is_flag=True, default=False, help='for local debugging') @click.option('--cost', is_flag=True, default=False, help='for viewing cost logs') -def run_server(host, port, api_base, model, deploy, debug, temperature, max_tokens, drop_params, create_proxy, add_function_to_prompt, max_budget, telemetry, test, local, cost): +def run_server(host, port, api_base, model, deploy, debug, temperature, max_tokens, drop_params, create_proxy, add_function_to_prompt, config, file, max_budget, telemetry, logs, test, local, cost): global feature_telemetry + args = locals() + print(f"args: {args}") + print(f"logs: {logs}") if local: from proxy_server import app, initialize, deploy_proxy, print_cost_logs, usage_telemetry debug = True @@ -76,8 +121,29 @@ def run_server(host, port, api_base, model, deploy, debug, temperature, max_toke destination = os.path.join(os.getcwd(), 'litellm-proxy') clone_subfolder(repo_url, subfolder, destination) - return + if config: + if file: + open_config(file_path=file) + else: + open_config() + return + if logs is not None: + if logs == 0: # default to 1 + logs = 1 + with open('api_log.json') as f: + data = json.load(f) + + # convert keys to datetime objects + log_times = {datetime.strptime(k, "%Y%m%d%H%M%S%f"): v for k, v in data.items()} + + # sort by timestamp + sorted_times = sorted(log_times.items(), key=operator.itemgetter(0), reverse=True) + + # get n recent logs + recent_logs = {k.strftime("%Y%m%d%H%M%S%f"): v for k, v in sorted_times[:logs]} + + print(json.dumps(recent_logs, indent=4)) if deploy == True: print(f"\033[32mLiteLLM: Deploying your proxy to api.litellm.ai\033[0m\n") print(f"\033[32mLiteLLM: Deploying proxy for model: {model}\033[0m\n") diff --git a/litellm/proxy/proxy_server.py b/litellm/proxy/proxy_server.py index 3d5718928..931252298 100644 --- a/litellm/proxy/proxy_server.py +++ b/litellm/proxy/proxy_server.py @@ -1,9 +1,9 @@ import sys, os, platform, time, copy import threading import shutil, random, traceback -# sys.path.insert( -# 0, os.path.abspath("../..") -# ) # Adds the parent directory to the system path - for litellm local dev +sys.path.insert( + 0, os.path.abspath("../..") +) # Adds the parent directory to the system path - for litellm local dev try: @@ -77,8 +77,9 @@ user_max_tokens = None user_temperature = None user_telemetry = True user_config = None -config_filename = "secrets.toml" +config_filename = "litellm.secrets.toml" config_dir = os.getcwd() +config_dir = appdirs.user_config_dir("litellm") user_config_path = os.path.join(config_dir, config_filename) log_file = 'api_log.json' #### HELPER FUNCTIONS ####