55"""
66
77import asyncio
8+ import json
89import os
910
11+ import httpx
1012import yaml
11- from openai import AsyncOpenAI # Use the OpenAI library
1213
14+ MODEL = "deepseek/deepseek-r1:free"
15+ STREAM = True
16+ MAX_TOKENS = 600
17+ INCLUDE_REASONING = True
1318
1419def load_config ():
1520 """
@@ -36,28 +41,15 @@ def load_config():
3641if os .environ .get ("ACCESS_KEY" ):
3742 ACCESS_KEY = os .environ .get ("ACCESS_KEY" )
3843
39- MODEL = "deepseek/deepseek-r1:free"
40- # MODEL = "google/gemini-2.0-pro-exp-02-05:free"
41-
4244
4345async def test_openrouter_streaming ():
4446 """
4547 Test the OpenRouter proxy with streaming mode.
4648 """
47- print (f"Testing OpenRouter Proxy at { PROXY_URL } with model { MODEL } in streaming mode..." )
48-
49- # Initialize OpenAI client with proxy URL
50- client = AsyncOpenAI (
51- base_url = PROXY_URL + "/api/v1" , # Append /api/v1 for OpenAI compatibility
52- api_key = ACCESS_KEY if ACCESS_KEY else "dummy" # Use a dummy key if no access key
53- )
54-
55- headers = {
56- # Optional. Site URL for rankings on openrouter.ai.
57- "HTTP-Referer" : config .get ("test" , {}).get ("http_referer" , "http://localhost" ),
58- # Optional. Site title for rankings on openrouter.ai.
59- "X-Title" : config .get ("test" , {}).get ("x_title" , "Local Test" ),
60- }
49+ print (f"Testing OpenRouter Proxy at { PROXY_URL } with model { MODEL } " )
50+
51+ url = f"{ PROXY_URL } /api/v1/chat/completions"
52+ headers = {"Authorization" : f"Bearer { ACCESS_KEY or 'dummy' } " }
6153 if not ACCESS_KEY :
6254 print ("No valid access key found. Request may fail if server requires authentication." )
6355 else :
@@ -70,62 +62,61 @@ async def test_openrouter_streaming():
7062 "messages" : [
7163 {"role" : "user" , "content" : "Write a short poem about AI and humanity working together" }
7264 ],
73- "stream" : True , # Enable streaming
74- "max_tokens" : 600
65+ "stream" : STREAM ,
66+ "max_tokens" : MAX_TOKENS ,
67+ "include_reasoning" : INCLUDE_REASONING ,
7568 }
7669
70+ client = httpx .AsyncClient (timeout = httpx .Timeout (15.0 , read = 600.0 ))
71+ req = client .build_request ("POST" , url , headers = headers , json = request_data )
72+
73+ print (f"\n Starting to receive data streaming: { STREAM } ...\n " )
74+ print ("-" * 50 )
75+
76+ resp = await client .send (req , stream = STREAM )
7777 try :
78- # Use OpenAI's async streaming
79- stream = await client .chat .completions .create (
80- ** request_data ,
81- extra_headers = headers ,
82- extra_body = {"include_reasoning" : True }
83- )
84-
85- print ("\n Starting to receive stream...\n " )
86- print ("-" * 50 )
87- start_reasoning = False
88- end_reasoning = False
89-
90- if request_data ["stream" ]:
91- async for chunk in stream :
92- if chunk .choices :
93- content = chunk .choices [0 ].delta .content
94- if content :
95- if start_reasoning and not end_reasoning :
96- end_reasoning = True
97- print ("</reasoning>\n " )
98- print (content , end = '' , flush = True )
99-
100- # Check for reasoning, if supported by the model
101- if not end_reasoning and hasattr (chunk .choices [0 ].delta , 'reasoning' ):
102- reasoning = chunk .choices [0 ].delta .reasoning
103- if reasoning :
104- if not start_reasoning :
105- print ("<reasoning>" )
106- start_reasoning = True
107- print (reasoning , end = '' , flush = True )
108- else :
109- if stream .choices :
110- if hasattr (stream .choices [0 ].message , 'reasoning' ):
111- reasoning = stream .choices [0 ].message .reasoning
112- if reasoning :
113- print ("<reasoning>" )
114- print (reasoning , end = '' , flush = True )
78+ resp .raise_for_status ()
79+ if STREAM :
80+ reasoning_phase = False
81+ async for line in resp .aiter_lines ():
82+ if not line .startswith ("data: " ):
83+ continue
84+ if (line := line [6 :]) == "[DONE]" :
85+ break
86+ data = json .loads (line )
87+ if "error" in data :
88+ raise ValueError (str (data ))
89+ choice = data ["choices" ][0 ]["delta" ]
90+ if content := choice .get ("content" ):
91+ if reasoning_phase :
92+ reasoning_phase = False
11593 print ("</reasoning>\n " )
116- content = stream .choices [0 ].message .content
117- if content :
11894 print (content , end = '' , flush = True )
119-
120- print ("\n " + "-" * 50 )
121- if request_data ["stream" ]:
122- print ("\n Stream completed!" )
95+ elif reasoning := choice .get ("reasoning" ):
96+ if not reasoning_phase :
97+ reasoning_phase = True
98+ print ("<reasoning>" )
99+ print (reasoning , end = '' , flush = True )
123100 else :
124- print ("\n Non-streaming response completed!" )
125-
101+ data = resp .json ()
102+ if "error" in data :
103+ raise ValueError (str (data ))
104+ choice = data ["choices" ][0 ]["message" ]
105+ if reasoning := choice .get ("reasoning" ):
106+ print (f"<reasoning>\n { reasoning } </reasoning>\n " )
107+ if content := choice .get ("content" ):
108+ print (content , end = '' )
126109 except Exception as e :
127110 print (f"Error occurred during test: { str (e )} " )
111+ finally :
112+ if STREAM :
113+ await resp .aclose ()
114+ print ("\n " + "-" * 50 )
115+ if STREAM :
116+ print ("\n Stream completed!" )
117+ else :
118+ print ("\n Non-streaming response completed!" )
128119
129120
130121if __name__ == "__main__" :
131- asyncio .run (test_openrouter_streaming ())
122+ asyncio .run (test_openrouter_streaming ())
0 commit comments