indoxrouter 0.1.11__tar.gz → 0.1.15__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.11/indoxrouter.egg-info → indoxrouter-0.1.15}/PKG-INFO +5 -24
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/README.md +1 -1
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/cookbook/README.md +1 -1
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/indoxrouter/client.py +41 -15
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/indoxrouter/constants.py +1 -1
- {indoxrouter-0.1.11 → indoxrouter-0.1.15/indoxrouter.egg-info}/PKG-INFO +5 -24
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/indoxrouter.egg-info/SOURCES.txt +1 -2
- indoxrouter-0.1.15/indoxrouter.egg-info/requires.txt +2 -0
- indoxrouter-0.1.15/pyproject.toml +34 -0
- indoxrouter-0.1.11/indoxrouter/test_api_key.py +0 -98
- indoxrouter-0.1.11/indoxrouter.egg-info/requires.txt +0 -10
- indoxrouter-0.1.11/setup.py +0 -46
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/MANIFEST.in +0 -0
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/cookbook/indoxRouter_cookbook.ipynb +0 -0
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/indoxrouter/__init__.py +0 -0
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/indoxrouter/exceptions.py +0 -0
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/indoxrouter.egg-info/dependency_links.txt +0 -0
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/indoxrouter.egg-info/top_level.txt +0 -0
- {indoxrouter-0.1.11 → indoxrouter-0.1.15}/setup.cfg +0 -0
@@ -1,13 +1,11 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: indoxrouter
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.15
|
4
4
|
Summary: A unified client for various AI providers
|
5
|
-
|
6
|
-
|
7
|
-
Author-email: ashkan.eskandari.dev@gmail.com
|
5
|
+
Author-email: indoxRouter Team <ashkan.eskandari.dev@gmail.com>
|
6
|
+
Project-URL: Homepage, https://github.com/indoxrouter/indoxrouter
|
8
7
|
Classifier: Development Status :: 3 - Alpha
|
9
8
|
Classifier: Intended Audience :: Developers
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
11
9
|
Classifier: Programming Language :: Python :: 3
|
12
10
|
Classifier: Programming Language :: Python :: 3.8
|
13
11
|
Classifier: Programming Language :: Python :: 3.9
|
@@ -18,27 +16,10 @@ Requires-Python: >=3.8
|
|
18
16
|
Description-Content-Type: text/markdown
|
19
17
|
Requires-Dist: requests>=2.25.0
|
20
18
|
Requires-Dist: python-dotenv>=1.0.0
|
21
|
-
Provides-Extra: dev
|
22
|
-
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
23
|
-
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
24
|
-
Requires-Dist: black>=23.0.0; extra == "dev"
|
25
|
-
Requires-Dist: isort>=5.0.0; extra == "dev"
|
26
|
-
Requires-Dist: flake8>=6.0.0; extra == "dev"
|
27
|
-
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
28
|
-
Dynamic: author
|
29
|
-
Dynamic: author-email
|
30
|
-
Dynamic: classifier
|
31
|
-
Dynamic: description
|
32
|
-
Dynamic: description-content-type
|
33
|
-
Dynamic: home-page
|
34
|
-
Dynamic: provides-extra
|
35
|
-
Dynamic: requires-dist
|
36
|
-
Dynamic: requires-python
|
37
|
-
Dynamic: summary
|
38
19
|
|
39
20
|
# IndoxRouter Client
|
40
21
|
|
41
|
-
A unified client for various AI providers, including OpenAI,
|
22
|
+
A unified client for various AI providers, including OpenAI, anthropic, Google, and Mistral.
|
42
23
|
|
43
24
|
## Features
|
44
25
|
|
@@ -41,4 +41,4 @@ python -c "from indoxrouter import Client; client = Client(api_key='your_api_key
|
|
41
41
|
|
42
42
|
## Note on API Keys
|
43
43
|
|
44
|
-
The IndoxRouter API key is used to authenticate with the IndoxRouter server. You don't need to provide individual API keys for each provider (like OpenAI,
|
44
|
+
The IndoxRouter API key is used to authenticate with the IndoxRouter server. You don't need to provide individual API keys for each provider (like OpenAI, anthropic, etc.) as the IndoxRouter server handles that for you.
|
@@ -120,31 +120,38 @@ class Client:
|
|
120
120
|
This uses the /auth/token endpoint to get JWT tokens using the API key.
|
121
121
|
"""
|
122
122
|
try:
|
123
|
-
# First try
|
124
|
-
logger.debug("Authenticating with API key
|
123
|
+
# First try with the dedicated API key endpoint
|
124
|
+
logger.debug("Authenticating with dedicated API key endpoint")
|
125
125
|
response = self.session.post(
|
126
|
-
f"{self.base_url}/api/v1/auth/
|
127
|
-
|
128
|
-
"username": self.api_key,
|
129
|
-
"password": "",
|
130
|
-
},
|
126
|
+
f"{self.base_url}/api/v1/auth/api-key",
|
127
|
+
headers={"X-API-Key": self.api_key},
|
131
128
|
timeout=self.timeout,
|
132
129
|
)
|
133
130
|
|
134
131
|
if response.status_code != 200:
|
135
|
-
#
|
136
|
-
logger.debug(
|
137
|
-
"First auth method failed, trying with API key as password"
|
138
|
-
)
|
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")
|
139
134
|
response = self.session.post(
|
140
|
-
f"{self.base_url}/api/v1/auth/
|
141
|
-
|
142
|
-
"username":
|
143
|
-
"password": self.api_key,
|
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
|
144
139
|
},
|
145
140
|
timeout=self.timeout,
|
146
141
|
)
|
147
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
|
+
|
148
155
|
if response.status_code != 200:
|
149
156
|
error_data = {}
|
150
157
|
try:
|
@@ -156,6 +163,17 @@ class Client:
|
|
156
163
|
f"Authentication failed: {error_data.get('detail', 'Unknown error')}"
|
157
164
|
)
|
158
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
|
+
|
159
177
|
# At this point, the cookies should be set in the session
|
160
178
|
logger.debug("Authentication successful")
|
161
179
|
|
@@ -227,6 +245,10 @@ class Client:
|
|
227
245
|
url = f"{self.base_url}/{endpoint}"
|
228
246
|
headers = {"Content-Type": "application/json"}
|
229
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
|
+
|
230
252
|
# logger.debug(f"Making {method} request to {url}")
|
231
253
|
# if data:
|
232
254
|
# logger.debug(f"Request data: {json.dumps(data, indent=2)}")
|
@@ -257,6 +279,10 @@ class Client:
|
|
257
279
|
logger.debug("Received 401, attempting to reauthenticate")
|
258
280
|
self._authenticate()
|
259
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
|
+
|
260
286
|
# Retry the request after reauthentication
|
261
287
|
response = self.session.request(
|
262
288
|
method,
|
@@ -4,7 +4,7 @@ Constants for the IndoxRouter client.
|
|
4
4
|
|
5
5
|
# API settings
|
6
6
|
DEFAULT_API_VERSION = "v1"
|
7
|
-
DEFAULT_BASE_URL = "https://api.
|
7
|
+
DEFAULT_BASE_URL = "https://api.indoxrouter.com" # Production server URL with HTTPS
|
8
8
|
# DEFAULT_BASE_URL = "http://localhost:8000" # Local development server
|
9
9
|
DEFAULT_TIMEOUT = 60
|
10
10
|
USE_COOKIES = True # Always use cookie-based authentication
|
@@ -1,13 +1,11 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: indoxrouter
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.15
|
4
4
|
Summary: A unified client for various AI providers
|
5
|
-
|
6
|
-
|
7
|
-
Author-email: ashkan.eskandari.dev@gmail.com
|
5
|
+
Author-email: indoxRouter Team <ashkan.eskandari.dev@gmail.com>
|
6
|
+
Project-URL: Homepage, https://github.com/indoxrouter/indoxrouter
|
8
7
|
Classifier: Development Status :: 3 - Alpha
|
9
8
|
Classifier: Intended Audience :: Developers
|
10
|
-
Classifier: License :: OSI Approved :: MIT License
|
11
9
|
Classifier: Programming Language :: Python :: 3
|
12
10
|
Classifier: Programming Language :: Python :: 3.8
|
13
11
|
Classifier: Programming Language :: Python :: 3.9
|
@@ -18,27 +16,10 @@ Requires-Python: >=3.8
|
|
18
16
|
Description-Content-Type: text/markdown
|
19
17
|
Requires-Dist: requests>=2.25.0
|
20
18
|
Requires-Dist: python-dotenv>=1.0.0
|
21
|
-
Provides-Extra: dev
|
22
|
-
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
23
|
-
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
24
|
-
Requires-Dist: black>=23.0.0; extra == "dev"
|
25
|
-
Requires-Dist: isort>=5.0.0; extra == "dev"
|
26
|
-
Requires-Dist: flake8>=6.0.0; extra == "dev"
|
27
|
-
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
28
|
-
Dynamic: author
|
29
|
-
Dynamic: author-email
|
30
|
-
Dynamic: classifier
|
31
|
-
Dynamic: description
|
32
|
-
Dynamic: description-content-type
|
33
|
-
Dynamic: home-page
|
34
|
-
Dynamic: provides-extra
|
35
|
-
Dynamic: requires-dist
|
36
|
-
Dynamic: requires-python
|
37
|
-
Dynamic: summary
|
38
19
|
|
39
20
|
# IndoxRouter Client
|
40
21
|
|
41
|
-
A unified client for various AI providers, including OpenAI,
|
22
|
+
A unified client for various AI providers, including OpenAI, anthropic, Google, and Mistral.
|
42
23
|
|
43
24
|
## Features
|
44
25
|
|
@@ -1,13 +1,12 @@
|
|
1
1
|
MANIFEST.in
|
2
2
|
README.md
|
3
|
-
|
3
|
+
pyproject.toml
|
4
4
|
cookbook/README.md
|
5
5
|
cookbook/indoxRouter_cookbook.ipynb
|
6
6
|
indoxrouter/__init__.py
|
7
7
|
indoxrouter/client.py
|
8
8
|
indoxrouter/constants.py
|
9
9
|
indoxrouter/exceptions.py
|
10
|
-
indoxrouter/test_api_key.py
|
11
10
|
indoxrouter.egg-info/PKG-INFO
|
12
11
|
indoxrouter.egg-info/SOURCES.txt
|
13
12
|
indoxrouter.egg-info/dependency_links.txt
|
@@ -0,0 +1,34 @@
|
|
1
|
+
[build-system]
|
2
|
+
requires = ["setuptools>=42", "wheel"]
|
3
|
+
build-backend = "setuptools.build_meta"
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "indoxrouter"
|
7
|
+
version = "0.1.15"
|
8
|
+
authors = [
|
9
|
+
{name = "indoxRouter Team", email = "ashkan.eskandari.dev@gmail.com"},
|
10
|
+
]
|
11
|
+
description = "A unified client for various AI providers"
|
12
|
+
readme = "README.md"
|
13
|
+
requires-python = ">=3.8"
|
14
|
+
classifiers = [
|
15
|
+
"Development Status :: 3 - Alpha",
|
16
|
+
"Intended Audience :: Developers",
|
17
|
+
"Programming Language :: Python :: 3",
|
18
|
+
"Programming Language :: Python :: 3.8",
|
19
|
+
"Programming Language :: Python :: 3.9",
|
20
|
+
"Programming Language :: Python :: 3.10",
|
21
|
+
"Programming Language :: Python :: 3.11",
|
22
|
+
"Programming Language :: Python :: 3.12",
|
23
|
+
]
|
24
|
+
dependencies = [
|
25
|
+
"requests>=2.25.0",
|
26
|
+
"python-dotenv>=1.0.0",
|
27
|
+
]
|
28
|
+
|
29
|
+
[project.urls]
|
30
|
+
Homepage = "https://github.com/indoxrouter/indoxrouter"
|
31
|
+
|
32
|
+
[tool.setuptools]
|
33
|
+
packages = ["indoxrouter"]
|
34
|
+
|
@@ -1,98 +0,0 @@
|
|
1
|
-
#!/usr/bin/env python
|
2
|
-
"""
|
3
|
-
Test script for the IndoxRouter client.
|
4
|
-
This script tests authentication and basic functionality of the client.
|
5
|
-
"""
|
6
|
-
|
7
|
-
import os
|
8
|
-
import sys
|
9
|
-
import logging
|
10
|
-
from indoxrouter import Client, AuthenticationError, NetworkError
|
11
|
-
|
12
|
-
# Set up logging
|
13
|
-
logging.basicConfig(
|
14
|
-
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
15
|
-
)
|
16
|
-
logger = logging.getLogger("indoxrouter_test")
|
17
|
-
|
18
|
-
|
19
|
-
def test_client(api_key=None, debug=False):
|
20
|
-
"""
|
21
|
-
Test the IndoxRouter client with the provided API key.
|
22
|
-
|
23
|
-
Args:
|
24
|
-
api_key: API key to use for authentication
|
25
|
-
debug: Whether to enable debug logging
|
26
|
-
"""
|
27
|
-
if debug:
|
28
|
-
logging.getLogger("indoxrouter").setLevel(logging.DEBUG)
|
29
|
-
|
30
|
-
logger.info("Testing IndoxRouter client...")
|
31
|
-
|
32
|
-
# If no API key is provided, try to get it from environment variable
|
33
|
-
if not api_key:
|
34
|
-
api_key = os.environ.get("INDOX_ROUTER_API_KEY")
|
35
|
-
if not api_key:
|
36
|
-
logger.error(
|
37
|
-
"No API key provided. Please provide an API key as an argument or set the INDOX_ROUTER_API_KEY environment variable."
|
38
|
-
)
|
39
|
-
sys.exit(1)
|
40
|
-
|
41
|
-
try:
|
42
|
-
# Initialize client
|
43
|
-
logger.info("Initializing client...")
|
44
|
-
client = Client(api_key=api_key)
|
45
|
-
|
46
|
-
# Test connection
|
47
|
-
logger.info("Testing connection...")
|
48
|
-
connection_info = client.test_connection()
|
49
|
-
logger.info(f"Connection test: {connection_info['status']}")
|
50
|
-
|
51
|
-
# Try to get available models
|
52
|
-
logger.info("Fetching available models...")
|
53
|
-
models = client.models()
|
54
|
-
|
55
|
-
# Display some models
|
56
|
-
providers = [p.get("name") for p in models]
|
57
|
-
logger.info(f"Available providers: {', '.join(providers)}")
|
58
|
-
|
59
|
-
# Try a simple chat completion
|
60
|
-
logger.info("Testing chat completion...")
|
61
|
-
response = client.chat(
|
62
|
-
messages=[{"role": "user", "content": "Hello, who are you?"}],
|
63
|
-
model="openai/gpt-3.5-turbo",
|
64
|
-
max_tokens=30,
|
65
|
-
)
|
66
|
-
|
67
|
-
logger.info("Chat completion successful!")
|
68
|
-
logger.info(f"Response: {response['choices'][0]['message']['content']}")
|
69
|
-
|
70
|
-
logger.info("All tests passed! The client is working correctly.")
|
71
|
-
|
72
|
-
except AuthenticationError as e:
|
73
|
-
logger.error(f"Authentication error: {e}")
|
74
|
-
logger.error("Please check that your API key is correct.")
|
75
|
-
sys.exit(1)
|
76
|
-
except NetworkError as e:
|
77
|
-
logger.error(f"Network error: {e}")
|
78
|
-
logger.error(
|
79
|
-
"Please check your internet connection and that the IndoxRouter server is accessible."
|
80
|
-
)
|
81
|
-
sys.exit(1)
|
82
|
-
except Exception as e:
|
83
|
-
logger.error(f"Unexpected error: {e}")
|
84
|
-
sys.exit(1)
|
85
|
-
|
86
|
-
|
87
|
-
if __name__ == "__main__":
|
88
|
-
import argparse
|
89
|
-
|
90
|
-
parser = argparse.ArgumentParser(description="Test the IndoxRouter client")
|
91
|
-
parser.add_argument("--api-key", "-k", help="API key to use for authentication")
|
92
|
-
parser.add_argument(
|
93
|
-
"--debug", "-d", action="store_true", help="Enable debug logging"
|
94
|
-
)
|
95
|
-
|
96
|
-
args = parser.parse_args()
|
97
|
-
|
98
|
-
test_client(api_key=args.api_key, debug=args.debug)
|
indoxrouter-0.1.11/setup.py
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
Setup script for indoxRouter client.
|
3
|
-
"""
|
4
|
-
|
5
|
-
from setuptools import setup, find_packages
|
6
|
-
|
7
|
-
with open("README.md", "r", encoding="utf-8") as fh:
|
8
|
-
long_description = fh.read()
|
9
|
-
|
10
|
-
setup(
|
11
|
-
name="indoxrouter",
|
12
|
-
version="0.1.11",
|
13
|
-
author="indoxRouter Team",
|
14
|
-
author_email="ashkan.eskandari.dev@gmail.com",
|
15
|
-
description="A unified client for various AI providers",
|
16
|
-
long_description=long_description,
|
17
|
-
long_description_content_type="text/markdown",
|
18
|
-
url="https://github.com/indoxrouter/indoxrouter",
|
19
|
-
packages=["indoxrouter"],
|
20
|
-
classifiers=[
|
21
|
-
"Development Status :: 3 - Alpha",
|
22
|
-
"Intended Audience :: Developers",
|
23
|
-
"License :: OSI Approved :: MIT License",
|
24
|
-
"Programming Language :: Python :: 3",
|
25
|
-
"Programming Language :: Python :: 3.8",
|
26
|
-
"Programming Language :: Python :: 3.9",
|
27
|
-
"Programming Language :: Python :: 3.10",
|
28
|
-
"Programming Language :: Python :: 3.11",
|
29
|
-
"Programming Language :: Python :: 3.12",
|
30
|
-
],
|
31
|
-
python_requires=">=3.8",
|
32
|
-
install_requires=[
|
33
|
-
"requests>=2.25.0",
|
34
|
-
"python-dotenv>=1.0.0",
|
35
|
-
],
|
36
|
-
extras_require={
|
37
|
-
"dev": [
|
38
|
-
"pytest>=7.0.0",
|
39
|
-
"pytest-cov>=4.0.0",
|
40
|
-
"black>=23.0.0",
|
41
|
-
"isort>=5.0.0",
|
42
|
-
"flake8>=6.0.0",
|
43
|
-
"mypy>=1.0.0",
|
44
|
-
],
|
45
|
-
},
|
46
|
-
)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|