1- import json
1+ from fastapi import FastAPI , Request , HTTPException
2+ import uvicorn
23import logging
3- import os
4- import re
5- import sys
6- import time
7- import uuid
8- from datetime import datetime
9- from typing import Any , Dict , List , Literal , Optional , Union
10-
4+ import json
5+ from pydantic import BaseModel , Field , field_validator
6+ from typing import List , Dict , Any , Optional , Union , Literal
117import httpx
8+ import os
9+ from fastapi .responses import JSONResponse , StreamingResponse
1210import litellm
13- import uvicorn
11+ import uuid
12+ import time
1413from dotenv import load_dotenv
15- from fastapi import FastAPI , HTTPException , Request
16- from fastapi . responses import JSONResponse , StreamingResponse
17- from pydantic import BaseModel , Field , field_validator
14+ import re
15+ from datetime import datetime
16+ import sys
1817
1918# Load environment variables from .env file
2019load_dotenv ()
2120
2221# Configure logging
2322logging .basicConfig (
2423 level = logging .WARN , # Change to INFO level to show more details
25- format = " %(asctime)s - %(levelname)s - %(message)s" ,
24+ format = ' %(asctime)s - %(levelname)s - %(message)s' ,
2625)
2726logger = logging .getLogger (__name__ )
2827
2928# Configure uvicorn to be quieter
3029import uvicorn
31-
3230# Tell uvicorn's loggers to be quiet
3331logging .getLogger ("uvicorn" ).setLevel (logging .WARNING )
3432logging .getLogger ("uvicorn.access" ).setLevel (logging .WARNING )
@@ -41,48 +39,42 @@ def filter(self, record):
4139 # Block messages containing these strings
4240 blocked_phrases = [
4341 "LiteLLM completion()" ,
44- "HTTP Request:" ,
42+ "HTTP Request:" ,
4543 "selected model name for cost calculation" ,
4644 "utils.py" ,
47- "cost_calculator" ,
45+ "cost_calculator"
4846 ]
49-
50- if hasattr (record , " msg" ) and isinstance (record .msg , str ):
47+
48+ if hasattr (record , ' msg' ) and isinstance (record .msg , str ):
5149 for phrase in blocked_phrases :
5250 if phrase in record .msg :
5351 return False
5452 return True
5553
56-
5754# Apply the filter to the root logger to catch all messages
5855root_logger = logging .getLogger ()
5956root_logger .addFilter (MessageFilter ())
6057
61-
6258# Custom formatter for model mapping logs
6359class ColorizedFormatter (logging .Formatter ):
6460 """Custom formatter to highlight model mappings"""
65-
6661 BLUE = "\033 [94m"
6762 GREEN = "\033 [92m"
6863 YELLOW = "\033 [93m"
6964 RED = "\033 [91m"
7065 RESET = "\033 [0m"
7166 BOLD = "\033 [1m"
72-
67+
7368 def format (self , record ):
7469 if record .levelno == logging .debug and "MODEL MAPPING" in record .msg :
7570 # Apply colors and formatting to model mapping logs
7671 return f"{ self .BOLD } { self .GREEN } { record .msg } { self .RESET } "
7772 return super ().format (record )
7873
79-
8074# Apply custom formatter to console handler
8175for handler in logger .handlers :
8276 if isinstance (handler , logging .StreamHandler ):
83- handler .setFormatter (
84- ColorizedFormatter ("%(asctime)s - %(levelname)s - %(message)s" )
85- )
77+ handler .setFormatter (ColorizedFormatter ('%(asctime)s - %(levelname)s - %(message)s' ))
8678
8779app = FastAPI ()
8880
@@ -122,12 +114,14 @@ def format(self, record):
122114]
123115
124116# List of Gemini models
125- GEMINI_MODELS = ["gemini-2.5-pro-preview-03-25" , "gemini-2.0-flash" ]
117+ GEMINI_MODELS = [
118+ "gemini-2.5-pro-preview-03-25" ,
119+ "gemini-2.0-flash"
120+ ]
126121
127122# List of Azure OpenAI models (deployment names)
128123AZURE_MODELS = [] # These are deployment-specific, so we'll validate at runtime
129124
130-
131125# Helper function to clean schema for Gemini
132126def clean_gemini_schema (schema : Any ) -> Any :
133127 """Recursively removes unsupported fields from a JSON schema for Gemini."""
@@ -140,22 +134,17 @@ def clean_gemini_schema(schema: Any) -> Any:
140134 if schema .get ("type" ) == "string" and "format" in schema :
141135 allowed_formats = {"enum" , "date-time" }
142136 if schema ["format" ] not in allowed_formats :
143- logger .debug (
144- f"Removing unsupported format '{ schema ['format' ]} ' for string type in Gemini schema."
145- )
137+ logger .debug (f"Removing unsupported format '{ schema ['format' ]} ' for string type in Gemini schema." )
146138 schema .pop ("format" )
147139
148140 # Recursively clean nested schemas (properties, items, etc.)
149- for key , value in list (
150- schema .items ()
151- ): # Use list() to allow modification during iteration
141+ for key , value in list (schema .items ()): # Use list() to allow modification during iteration
152142 schema [key ] = clean_gemini_schema (value )
153143 elif isinstance (schema , list ):
154144 # Recursively clean items in a list
155145 return [clean_gemini_schema (item ) for item in schema ]
156146 return schema
157147
158-
159148# Models for Anthropic API requests
160149class ContentBlockText (BaseModel ):
161150 type : Literal ["text" ]
0 commit comments