indoxrouter 0.1.9__tar.gz → 0.1.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: indoxrouter
3
- Version: 0.1.9
3
+ Version: 0.1.12
4
4
  Summary: A unified client for various AI providers
5
5
  Home-page: https://github.com/indoxrouter/indoxrouter
6
6
  Author: indoxRouter Team
@@ -78,14 +78,33 @@ client = Client(
78
78
 
79
79
  ### Authentication
80
80
 
81
- IndoxRouter uses cookie-based authentication, which securely transmits your API key in cookies rather than headers. This is handled automatically by the client.
81
+ IndoxRouter uses cookie-based authentication with JWT tokens. The client handles this automatically by:
82
+
83
+ 1. Taking your API key and exchanging it for JWT tokens using the server's authentication endpoints
84
+ 2. Storing the JWT tokens in cookies
85
+ 3. Using the cookies for subsequent requests
86
+ 4. Automatically refreshing tokens when they expire
82
87
 
83
88
  ```python
84
89
  # Authentication is handled automatically when creating the client
85
90
  client = Client(api_key="your_api_key")
86
91
  ```
87
92
 
88
- > **Note**: The `use_cookies` parameter is kept for backward compatibility but should always be set to `True` as the server no longer supports header-based authentication.
93
+ ### Testing Your API Key
94
+
95
+ The package includes a test script to verify your API key and connection:
96
+
97
+ ```bash
98
+ # Run the test script with your API key
99
+ python -m indoxrouter.test_api_key --api-key YOUR_API_KEY
100
+
101
+ # Or set the environment variable and run
102
+ export INDOX_ROUTER_API_KEY=YOUR_API_KEY
103
+ python -m indoxrouter.test_api_key
104
+
105
+ # To see detailed debugging information
106
+ python -m indoxrouter.test_api_key --debug
107
+ ```
89
108
 
90
109
  ### Chat Completions
91
110
 
@@ -40,14 +40,33 @@ client = Client(
40
40
 
41
41
  ### Authentication
42
42
 
43
- IndoxRouter uses cookie-based authentication, which securely transmits your API key in cookies rather than headers. This is handled automatically by the client.
43
+ IndoxRouter uses cookie-based authentication with JWT tokens. The client handles this automatically by:
44
+
45
+ 1. Taking your API key and exchanging it for JWT tokens using the server's authentication endpoints
46
+ 2. Storing the JWT tokens in cookies
47
+ 3. Using the cookies for subsequent requests
48
+ 4. Automatically refreshing tokens when they expire
44
49
 
45
50
  ```python
46
51
  # Authentication is handled automatically when creating the client
47
52
  client = Client(api_key="your_api_key")
48
53
  ```
49
54
 
50
- > **Note**: The `use_cookies` parameter is kept for backward compatibility but should always be set to `True` as the server no longer supports header-based authentication.
55
+ ### Testing Your API Key
56
+
57
+ The package includes a test script to verify your API key and connection:
58
+
59
+ ```bash
60
+ # Run the test script with your API key
61
+ python -m indoxrouter.test_api_key --api-key YOUR_API_KEY
62
+
63
+ # Or set the environment variable and run
64
+ export INDOX_ROUTER_API_KEY=YOUR_API_KEY
65
+ python -m indoxrouter.test_api_key
66
+
67
+ # To see detailed debugging information
68
+ python -m indoxrouter.test_api_key --debug
69
+ ```
51
70
 
52
71
  ### Chat Completions
53
72
 
@@ -1362,7 +1362,7 @@
1362
1362
  ],
1363
1363
  "metadata": {
1364
1364
  "kernelspec": {
1365
- "display_name": "Python 3",
1365
+ "display_name": "base",
1366
1366
  "language": "python",
1367
1367
  "name": "python3"
1368
1368
  },
@@ -6,8 +6,7 @@ interface to multiple AI providers and models. The client handles authentication
6
6
  error handling, and provides a standardized response format across different AI services.
7
7
 
8
8
  IMPORTANT: The IndoxRouter server now supports only cookie-based authentication. This client
9
- will use cookie-based authentication by default. The 'use_cookies' parameter is kept for
10
- backward compatibility but should always be set to True for newer server versions.
9
+ automatically handles authentication by exchanging your API key for a JWT token through the login endpoint.
11
10
 
12
11
  The Client class offers methods for:
13
12
  - Authentication and session management
@@ -97,7 +96,6 @@ class Client:
97
96
  Args:
98
97
  api_key: API key for authentication. If not provided, the client will look for the
99
98
  INDOX_ROUTER_API_KEY environment variable.
100
- base_url: Custom base URL for the API. If not provided, the default base URL will be used.
101
99
  timeout: Request timeout in seconds.
102
100
  """
103
101
 
@@ -113,23 +111,82 @@ class Client:
113
111
  self.use_cookies = use_cookies
114
112
  self.session = requests.Session()
115
113
 
116
- # Set up authentication method based on preference
117
- if use_cookies:
118
- # Set cookie for authentication - using access_token as that's what the server expects
119
- self.session.cookies.set(
120
- "access_token", self.api_key, domain=self._get_domain(), path="/"
121
- )
122
- else:
123
- # Warning: Authorization header is no longer supported by the server
124
- logger.warning(
125
- "WARNING: The IndoxRouter server no longer supports Authorization header authentication. "
126
- "Using cookie-based authentication instead."
127
- )
128
- # Still set the cookie despite the use_cookies=False setting
129
- self.session.cookies.set(
130
- "access_token", self.api_key, domain=self._get_domain(), path="/"
114
+ # Authenticate and get JWT tokens
115
+ self._authenticate()
116
+
117
+ def _authenticate(self):
118
+ """
119
+ Authenticate with the server and get JWT tokens.
120
+ This uses the /auth/token endpoint to get JWT tokens using the API key.
121
+ """
122
+ try:
123
+ # First try with the dedicated API key endpoint
124
+ logger.debug("Authenticating with dedicated API key endpoint")
125
+ response = self.session.post(
126
+ f"{self.base_url}/api/v1/auth/api-key",
127
+ headers={"X-API-Key": self.api_key},
128
+ timeout=self.timeout,
131
129
  )
132
130
 
131
+ if response.status_code != 200:
132
+ # If dedicated endpoint fails, try using the API key as a username
133
+ logger.debug("API key endpoint failed, trying with API key as username")
134
+ response = self.session.post(
135
+ f"{self.base_url}/api/v1/auth/token",
136
+ data={
137
+ "username": self.api_key,
138
+ "password": self.api_key, # Try using API key as both username and password
139
+ },
140
+ timeout=self.timeout,
141
+ )
142
+
143
+ if response.status_code != 200:
144
+ # Try one more method - the token endpoint with different format
145
+ logger.debug("Trying with API key as token parameter")
146
+ response = self.session.post(
147
+ f"{self.base_url}/api/v1/auth/token",
148
+ data={
149
+ "username": "pip_client",
150
+ "password": self.api_key,
151
+ },
152
+ timeout=self.timeout,
153
+ )
154
+
155
+ if response.status_code != 200:
156
+ error_data = {}
157
+ try:
158
+ error_data = response.json()
159
+ except:
160
+ error_data = {"detail": response.text}
161
+
162
+ raise AuthenticationError(
163
+ f"Authentication failed: {error_data.get('detail', 'Unknown error')}"
164
+ )
165
+
166
+ # Check if we have a token in the response body
167
+ try:
168
+ response_data = response.json()
169
+ if "access_token" in response_data:
170
+ # Store token in the session object for later use
171
+ self.access_token = response_data["access_token"]
172
+ logger.debug("Retrieved access token from response body")
173
+ except:
174
+ # If we couldn't parse JSON, that's fine - we'll rely on cookies
175
+ logger.debug("No token found in response body, will rely on cookies")
176
+
177
+ # At this point, the cookies should be set in the session
178
+ logger.debug("Authentication successful")
179
+
180
+ # Check if we have the cookies we need
181
+ if "access_token" not in self.session.cookies:
182
+ logger.warning(
183
+ "Authentication succeeded but no access_token cookie was set"
184
+ )
185
+
186
+ except requests.RequestException as e:
187
+ logger.error(f"Authentication request failed: {str(e)}")
188
+ raise NetworkError(f"Network error during authentication: {str(e)}")
189
+
133
190
  def _get_domain(self):
134
191
  """
135
192
  Extract domain from the base URL for cookie setting.
@@ -188,6 +245,10 @@ class Client:
188
245
  url = f"{self.base_url}/{endpoint}"
189
246
  headers = {"Content-Type": "application/json"}
190
247
 
248
+ # Add Authorization header if we have an access token
249
+ if hasattr(self, "access_token") and self.access_token:
250
+ headers["Authorization"] = f"Bearer {self.access_token}"
251
+
191
252
  # logger.debug(f"Making {method} request to {url}")
192
253
  # if data:
193
254
  # logger.debug(f"Request data: {json.dumps(data, indent=2)}")
@@ -213,6 +274,28 @@ class Client:
213
274
  if stream:
214
275
  return response
215
276
 
277
+ # Check if we need to reauthenticate (401 Unauthorized)
278
+ if response.status_code == 401:
279
+ logger.debug("Received 401, attempting to reauthenticate")
280
+ self._authenticate()
281
+
282
+ # Update Authorization header with new token if available
283
+ if hasattr(self, "access_token") and self.access_token:
284
+ headers["Authorization"] = f"Bearer {self.access_token}"
285
+
286
+ # Retry the request after reauthentication
287
+ response = self.session.request(
288
+ method,
289
+ url,
290
+ headers=headers,
291
+ json=data,
292
+ timeout=self.timeout,
293
+ stream=stream,
294
+ )
295
+
296
+ if stream:
297
+ return response
298
+
216
299
  response.raise_for_status()
217
300
  return response.json()
218
301
  except requests.HTTPError as e:
@@ -7,6 +7,7 @@ DEFAULT_API_VERSION = "v1"
7
7
  DEFAULT_BASE_URL = "https://api.indox.org" # Production server URL with HTTPS
8
8
  # DEFAULT_BASE_URL = "http://localhost:8000" # Local development server
9
9
  DEFAULT_TIMEOUT = 60
10
+ USE_COOKIES = True # Always use cookie-based authentication
10
11
 
11
12
  # Default models
12
13
  DEFAULT_MODEL = "openai/gpt-4o-mini"
@@ -29,6 +30,3 @@ ERROR_PROVIDER_NOT_FOUND = "Provider not found"
29
30
  ERROR_MODEL_NOT_FOUND = "Model not found"
30
31
  ERROR_INVALID_PARAMETERS = "Invalid parameters provided"
31
32
  ERROR_INSUFFICIENT_CREDITS = "Insufficient credits"
32
-
33
-
34
- USE_COOKIES = True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: indoxrouter
3
- Version: 0.1.9
3
+ Version: 0.1.12
4
4
  Summary: A unified client for various AI providers
5
5
  Home-page: https://github.com/indoxrouter/indoxrouter
6
6
  Author: indoxRouter Team
@@ -78,14 +78,33 @@ client = Client(
78
78
 
79
79
  ### Authentication
80
80
 
81
- IndoxRouter uses cookie-based authentication, which securely transmits your API key in cookies rather than headers. This is handled automatically by the client.
81
+ IndoxRouter uses cookie-based authentication with JWT tokens. The client handles this automatically by:
82
+
83
+ 1. Taking your API key and exchanging it for JWT tokens using the server's authentication endpoints
84
+ 2. Storing the JWT tokens in cookies
85
+ 3. Using the cookies for subsequent requests
86
+ 4. Automatically refreshing tokens when they expire
82
87
 
83
88
  ```python
84
89
  # Authentication is handled automatically when creating the client
85
90
  client = Client(api_key="your_api_key")
86
91
  ```
87
92
 
88
- > **Note**: The `use_cookies` parameter is kept for backward compatibility but should always be set to `True` as the server no longer supports header-based authentication.
93
+ ### Testing Your API Key
94
+
95
+ The package includes a test script to verify your API key and connection:
96
+
97
+ ```bash
98
+ # Run the test script with your API key
99
+ python -m indoxrouter.test_api_key --api-key YOUR_API_KEY
100
+
101
+ # Or set the environment variable and run
102
+ export INDOX_ROUTER_API_KEY=YOUR_API_KEY
103
+ python -m indoxrouter.test_api_key
104
+
105
+ # To see detailed debugging information
106
+ python -m indoxrouter.test_api_key --debug
107
+ ```
89
108
 
90
109
  ### Chat Completions
91
110
 
@@ -9,7 +9,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
9
9
 
10
10
  setup(
11
11
  name="indoxrouter",
12
- version="0.1.9",
12
+ version="0.1.12",
13
13
  author="indoxRouter Team",
14
14
  author_email="ashkan.eskandari.dev@gmail.com",
15
15
  description="A unified client for various AI providers",
File without changes
File without changes