1717
1818router = APIRouter ()
1919
20- # Create OpenAI client - use env key if available, otherwise create a dummy one
21- if config .openai_api_key :
22- openai_client = OpenAIClient (
23- config .openai_api_key ,
24- config .openai_base_url ,
25- config .request_timeout ,
26- api_version = config .azure_api_version ,
27- )
28- else :
29- # In passthrough mode, create a client with a dummy key for compatibility
30- # The actual client will be created per-request with user's API key
31- openai_client = OpenAIClient (
32- "sk-dummy" , # This won't be used for actual requests
33- config .openai_base_url ,
34- config .request_timeout ,
35- api_version = config .azure_api_version ,
36- )
37-
38- def get_openai_client (user_api_key : Optional [str ] = None ) -> OpenAIClient :
39- """Get OpenAI client - use env key if available, otherwise create with user-provided key."""
40- if config .openai_api_key :
41- # Proxy mode: use pre-configured client
42- return openai_client
43- elif user_api_key :
44- # Passthrough mode: create client with user-provided key
45- if not config .validate_api_key (user_api_key ):
46- raise HTTPException (
47- status_code = 401 ,
48- detail = "Invalid OpenAI API key format. Please provide a valid API key starting with 'sk-'."
49- )
50- return OpenAIClient (
51- user_api_key ,
52- config .openai_base_url ,
53- config .request_timeout ,
54- api_version = config .azure_api_version ,
55- )
56- else :
57- raise HTTPException (
58- status_code = 401 ,
59- detail = "No OpenAI API key available. Please set OPENAI_API_KEY environment variable or provide your OpenAI API key in Authorization header."
60- )
20+ openai_client = OpenAIClient (
21+ config .openai_api_key ,
22+ config .openai_base_url ,
23+ config .request_timeout ,
24+ api_version = config .azure_api_version ,
25+ )
6126
62- async def validate_api_key_and_extract (x_api_key : Optional [str ] = Header (None ), authorization : Optional [str ] = Header (None )):
63- """Extract API key and handle validation based on configuration ."""
27+ async def validate_api_key (x_api_key : Optional [str ] = Header (None ), authorization : Optional [str ] = Header (None )):
28+ """Validate the client's API key from either x-api-key header or Authorization header ."""
6429 client_api_key = None
6530
6631 # Extract API key from headers
@@ -69,40 +34,27 @@ async def validate_api_key_and_extract(x_api_key: Optional[str] = Header(None),
6934 elif authorization and authorization .startswith ("Bearer " ):
7035 client_api_key = authorization .replace ("Bearer " , "" )
7136
72- # If OPENAI_API_KEY is configured in environment, use proxy validation
73- if config .openai_api_key :
74- # Proxy mode: validate against ANTHROPIC_API_KEY if configured
75- if config .anthropic_api_key :
76- if not client_api_key or not config .validate_client_api_key (client_api_key ):
77- logger .warning (f"Invalid API key provided by client" )
78- raise HTTPException (
79- status_code = 401 ,
80- detail = "Invalid API key. Please provide a valid Anthropic API key."
81- )
82- # Return None since we'll use env OPENAI_API_KEY
83- return None
84- else :
85- # Passthrough mode: no ANTHROPIC validation, use client key as OpenAI key
86- if not client_api_key :
87- raise HTTPException (
88- status_code = 401 ,
89- detail = "No API key provided. Please provide your OpenAI API key in Authorization header."
90- )
91- # Return the client API key to be used as OpenAI key
92- return client_api_key
37+ # Skip validation if ANTHROPIC_API_KEY is not set in the environment
38+ if not config .anthropic_api_key :
39+ return
40+
41+ # Validate the client API key
42+ if not client_api_key or not config .validate_client_api_key (client_api_key ):
43+ logger .warning (f"Invalid API key provided by client" )
44+ raise HTTPException (
45+ status_code = 401 ,
46+ detail = "Invalid API key. Please provide a valid Anthropic API key."
47+ )
9348
9449@router .post ("/v1/messages" )
95- async def create_message (request : ClaudeMessagesRequest , http_request : Request , user_api_key : str = Depends (validate_api_key_and_extract )):
50+ async def create_message (request : ClaudeMessagesRequest , http_request : Request , _ : None = Depends (validate_api_key )):
9651 try :
9752 logger .debug (
9853 f"Processing Claude request: model={ request .model } , stream={ request .stream } "
9954 )
10055
10156 # Generate unique request ID for cancellation tracking
10257 request_id = str (uuid .uuid4 ())
103-
104- # Get OpenAI client (either default or created with user's key)
105- openai_client = get_openai_client (user_api_key )
10658
10759 # Convert Claude request to OpenAI format
10860 openai_request = convert_claude_to_openai (request , model_manager )
@@ -167,7 +119,7 @@ async def create_message(request: ClaudeMessagesRequest, http_request: Request,
167119
168120
169121@router .post ("/v1/messages/count_tokens" )
170- async def count_tokens (request : ClaudeTokenCountRequest , user_api_key : str = Depends (validate_api_key_and_extract )):
122+ async def count_tokens (request : ClaudeTokenCountRequest , _ : None = Depends (validate_api_key )):
171123 try :
172124 # For token counting, we'll use a simple estimation
173125 # In a real implementation, you might want to use tiktoken or similar
@@ -211,7 +163,7 @@ async def health_check():
211163 "status" : "healthy" ,
212164 "timestamp" : datetime .now ().isoformat (),
213165 "openai_api_configured" : bool (config .openai_api_key ),
214- "api_key_valid" : config .validate_api_key () if config . openai_api_key else "per_request" ,
166+ "api_key_valid" : config .validate_api_key (),
215167 "client_api_key_validation" : bool (config .anthropic_api_key ),
216168 }
217169
@@ -220,17 +172,6 @@ async def health_check():
220172async def test_connection ():
221173 """Test API connectivity to OpenAI"""
222174 try :
223- # Use default client if available, otherwise require user API key
224- if not config .openai_api_key :
225- return JSONResponse (
226- status_code = 400 ,
227- content = {
228- "status" : "failed" ,
229- "message" : "No default OpenAI API key configured. Test connection requires OPENAI_API_KEY environment variable." ,
230- "timestamp" : datetime .now ().isoformat (),
231- }
232- )
233-
234175 # Simple test request to verify API connectivity
235176 test_response = await openai_client .create_chat_completion (
236177 {
0 commit comments