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.
- {indoxrouter-0.1.9/indoxrouter.egg-info → indoxrouter-0.1.12}/PKG-INFO +22 -3
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/README.md +21 -2
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/cookbook/indoxRouter_cookbook.ipynb +1 -1
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter/client.py +101 -18
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter/constants.py +1 -3
- {indoxrouter-0.1.9 → indoxrouter-0.1.12/indoxrouter.egg-info}/PKG-INFO +22 -3
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/setup.py +1 -1
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/MANIFEST.in +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/cookbook/README.md +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter/__init__.py +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter/exceptions.py +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter.egg-info/SOURCES.txt +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter.egg-info/dependency_links.txt +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter.egg-info/requires.txt +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/indoxrouter.egg-info/top_level.txt +0 -0
- {indoxrouter-0.1.9 → indoxrouter-0.1.12}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.2
|
2
2
|
Name: indoxrouter
|
3
|
-
Version: 0.1.
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
|
@@ -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
|
-
|
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
|
-
#
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
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.
|
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
|
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
|
-
|
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.
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|