onlist 0.1.0__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.
@@ -0,0 +1,34 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
13
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
14
+ with:
15
+ python-version: "3.12"
16
+ - run: pip install build
17
+ - run: python -m build
18
+ - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
19
+ with:
20
+ name: dist
21
+ path: dist/
22
+
23
+ publish:
24
+ needs: build
25
+ runs-on: ubuntu-latest
26
+ environment: pypi
27
+ permissions:
28
+ id-token: write
29
+ steps:
30
+ - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
31
+ with:
32
+ name: dist
33
+ path: dist/
34
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,41 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.9", "3.11", "3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
16
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - run: pip install -e . && pip install pytest pytest-asyncio respx
20
+ - run: pytest -v
21
+
22
+ typecheck:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
26
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
27
+ with:
28
+ python-version: "3.12"
29
+ - run: pip install -e . && pip install mypy
30
+ - run: mypy src/onlist/
31
+
32
+ lint:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
36
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
37
+ with:
38
+ python-version: "3.12"
39
+ - run: pip install ruff
40
+ - run: ruff check src/ tests/
41
+ - run: ruff format --check src/ tests/
@@ -0,0 +1,16 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .mypy_cache/
10
+ .ruff_cache/
11
+ .pytest_cache/
12
+ .venv/
13
+ venv/
14
+ *.so
15
+ .env
16
+ .env.local
onlist-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Onlist (onlist.io)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
onlist-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,303 @@
1
+ Metadata-Version: 2.4
2
+ Name: onlist
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for Onlist, the AI API marketplace. Access GPT, Claude, Gemini, DeepSeek and 40+ models through one OpenAI-compatible API.
5
+ Project-URL: Homepage, https://onlist.io
6
+ Project-URL: Documentation, https://onlist.io/docs
7
+ Project-URL: Repository, https://github.com/OnlistTeam/onlist-python
8
+ Project-URL: API Reference, https://onlist.io/docs/api
9
+ Project-URL: Model Catalog, https://onlist.io/models
10
+ Project-URL: Provider Directory, https://onlist.io/providers
11
+ Project-URL: Changelog, https://github.com/OnlistTeam/onlist-python/releases
12
+ Project-URL: Issues, https://github.com/OnlistTeam/onlist-python/issues
13
+ Author-email: Onlist <dev@onlist.io>
14
+ License-Expression: MIT
15
+ License-File: LICENSE
16
+ Keywords: ai,ai-api,ai-gateway,anthropic,api,chat-completion,claude,deepseek,gemini,gpt,llm,llm-proxy,marketplace,model-router,onlist,openai,openrouter,sdk
17
+ Classifier: Development Status :: 4 - Beta
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: License :: OSI Approved :: MIT License
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
27
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.9
30
+ Requires-Dist: httpx>=0.25.0
31
+ Requires-Dist: openai>=1.0.0
32
+ Requires-Dist: pydantic>=2.0.0
33
+ Description-Content-Type: text/markdown
34
+
35
+ # Onlist Python SDK
36
+
37
+ The official Python client for [Onlist](https://onlist.io), the AI API marketplace.
38
+
39
+ Onlist aggregates 40+ AI model providers behind a single OpenAI-compatible API.
40
+ This SDK is a drop-in replacement for the OpenAI Python client, so you can switch
41
+ with one line of code.
42
+
43
+ [![PyPI version](https://img.shields.io/pypi/v/onlist.svg)](https://pypi.org/project/onlist/)
44
+ [![Python versions](https://img.shields.io/pypi/pyversions/onlist.svg)](https://pypi.org/project/onlist/)
45
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/OnlistTeam/onlist-python/blob/main/LICENSE)
46
+
47
+ ## Installation
48
+
49
+ ```bash
50
+ pip install onlist
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ```python
56
+ from onlist import Onlist
57
+
58
+ client = Onlist(api_key="sk-...") # or set ONLIST_API_KEY env var
59
+
60
+ response = client.chat.completions.create(
61
+ model="anthropic/claude-sonnet-4",
62
+ messages=[{"role": "user", "content": "What is Onlist?"}],
63
+ )
64
+ print(response.choices[0].message.content)
65
+ ```
66
+
67
+ Get your API key at [onlist.io](https://onlist.io).
68
+
69
+ ## Authentication
70
+
71
+ The client reads your API key from:
72
+ 1. The `api_key` parameter
73
+ 2. The `ONLIST_API_KEY` environment variable
74
+ 3. The `OPENAI_API_KEY` environment variable (fallback, for easy migration)
75
+
76
+ ```bash
77
+ export ONLIST_API_KEY="sk-..."
78
+ ```
79
+
80
+ ## Provider Routing
81
+
82
+ Onlist's marketplace lets you choose which provider serves your request.
83
+ Use the `provider` field via `extra_body`:
84
+
85
+ ```python
86
+ # Pin to a specific provider
87
+ response = client.chat.completions.create(
88
+ model="anthropic/claude-sonnet-4",
89
+ messages=[{"role": "user", "content": "Hello"}],
90
+ extra_body={"provider": "alice-shop"},
91
+ )
92
+
93
+ # Route to the cheapest provider
94
+ response = client.chat.completions.create(
95
+ model="openai/gpt-4o",
96
+ messages=[{"role": "user", "content": "Hello"}],
97
+ extra_body={"provider": {"sort": "price"}},
98
+ )
99
+
100
+ # Full routing control
101
+ response = client.chat.completions.create(
102
+ model="openai/gpt-4o",
103
+ messages=[{"role": "user", "content": "Hello"}],
104
+ extra_body={
105
+ "provider": {
106
+ "allow": ["alice-shop", "bob-relay"],
107
+ "sort": "price",
108
+ "allow_fallbacks": True,
109
+ "max_price": {"prompt": 0.000003, "completion": 0.000015},
110
+ }
111
+ },
112
+ )
113
+ ```
114
+
115
+ You can also use the typed helper:
116
+
117
+ ```python
118
+ from onlist import ProviderRouting
119
+
120
+ routing = ProviderRouting(
121
+ allow=["alice-shop", "bob-relay"],
122
+ sort="price",
123
+ )
124
+
125
+ response = client.chat.completions.create(
126
+ model="openai/gpt-4o",
127
+ messages=[{"role": "user", "content": "Hello"}],
128
+ extra_body={"provider": routing.model_dump(exclude_none=True)},
129
+ )
130
+ ```
131
+
132
+ ## Streaming
133
+
134
+ ```python
135
+ stream = client.chat.completions.create(
136
+ model="anthropic/claude-sonnet-4",
137
+ messages=[{"role": "user", "content": "Write a haiku about APIs"}],
138
+ stream=True,
139
+ )
140
+
141
+ for chunk in stream:
142
+ content = chunk.choices[0].delta.content
143
+ if content:
144
+ print(content, end="", flush=True)
145
+ ```
146
+
147
+ ## Async Usage
148
+
149
+ ```python
150
+ import asyncio
151
+ from onlist import AsyncOnlist
152
+
153
+ async def main():
154
+ client = AsyncOnlist(api_key="sk-...")
155
+
156
+ response = await client.chat.completions.create(
157
+ model="openai/gpt-4o",
158
+ messages=[{"role": "user", "content": "Hello!"}],
159
+ )
160
+ print(response.choices[0].message.content)
161
+
162
+ asyncio.run(main())
163
+ ```
164
+
165
+ ## Marketplace API
166
+
167
+ Query the Onlist marketplace for models and providers:
168
+
169
+ ```python
170
+ from onlist import Onlist
171
+
172
+ client = Onlist(api_key="sk-...")
173
+
174
+ # List available models with pricing
175
+ models = client.marketplace.models.list(limit=10)
176
+ for m in models.data:
177
+ print(f"{m['id']} - input: {m.get('pricing', {}).get('prompt', 'N/A')}")
178
+
179
+ # Get detailed model info with all provider offers
180
+ detail = client.marketplace.models.get("anthropic/claude-sonnet-4")
181
+ print(f"{detail.id} - {len(detail.providers)} providers")
182
+
183
+ # Browse providers
184
+ providers = client.marketplace.providers.list()
185
+ for p in providers.data:
186
+ print(f"{p.slug} - score: {p.score}")
187
+
188
+ # Get a specific provider's profile
189
+ provider = client.marketplace.providers.get("alice-shop")
190
+ print(f"{provider.display_name} - {provider.model_count} models")
191
+ ```
192
+
193
+ ## Other APIs
194
+
195
+ Since Onlist is fully OpenAI-compatible, all standard endpoints work:
196
+
197
+ ```python
198
+ # Embeddings
199
+ embedding = client.embeddings.create(
200
+ model="openai/text-embedding-3-small",
201
+ input="Hello world",
202
+ )
203
+
204
+ # Image generation
205
+ image = client.images.generate(
206
+ model="openai/gpt-image-2",
207
+ prompt="A sunset over Tokyo",
208
+ )
209
+
210
+ # Text-to-speech
211
+ audio = client.audio.speech.create(
212
+ model="openai/tts-1",
213
+ voice="alloy",
214
+ input="Welcome to Onlist.",
215
+ )
216
+ ```
217
+
218
+ ## Error Handling
219
+
220
+ For OpenAI-compatible API calls (`chat.completions`, `embeddings`, etc.), the
221
+ standard `openai` exceptions are raised:
222
+
223
+ ```python
224
+ import openai
225
+ from onlist import Onlist
226
+
227
+ client = Onlist(api_key="sk-...")
228
+
229
+ try:
230
+ response = client.chat.completions.create(
231
+ model="openai/gpt-4o",
232
+ messages=[{"role": "user", "content": "Hello"}],
233
+ )
234
+ except openai.AuthenticationError:
235
+ print("Invalid API key")
236
+ except openai.RateLimitError as e:
237
+ print(f"Rate limited: {e.message}")
238
+ ```
239
+
240
+ For marketplace API calls (`client.marketplace.*`), Onlist-specific exceptions
241
+ are raised:
242
+
243
+ ```python
244
+ from onlist import Onlist, AuthenticationError, APIError
245
+
246
+ client = Onlist(api_key="sk-...")
247
+
248
+ try:
249
+ providers = client.marketplace.providers.list()
250
+ except AuthenticationError:
251
+ print("Invalid API key for marketplace")
252
+ except APIError as e:
253
+ print(f"API error {e.status_code}: {e.message}")
254
+ ```
255
+
256
+ ## Migrate from OpenAI or OpenRouter
257
+
258
+ Already using the OpenAI SDK? Change one line:
259
+
260
+ ```diff
261
+ - from openai import OpenAI
262
+ - client = OpenAI(api_key="sk-...")
263
+ + from onlist import Onlist
264
+ + client = Onlist(api_key="sk-...")
265
+ ```
266
+
267
+ Or, if you prefer to keep using `openai` directly:
268
+
269
+ ```python
270
+ from openai import OpenAI
271
+
272
+ client = OpenAI(
273
+ api_key="your-onlist-key",
274
+ base_url="https://onlist.io/v1",
275
+ )
276
+ ```
277
+
278
+ ## Routing Metadata
279
+
280
+ Onlist returns routing information in response headers. Access them to see
281
+ which provider actually served your request:
282
+
283
+ ```python
284
+ # Use the with_raw_response pattern from the openai SDK:
285
+ raw_response = client.chat.completions.with_raw_response.create(
286
+ model="openai/gpt-4o",
287
+ messages=[{"role": "user", "content": "Hello"}],
288
+ )
289
+ print(raw_response.headers.get("x-onlist-route-id"))
290
+ print(raw_response.headers.get("x-onlist-provider"))
291
+
292
+ # Parse the completion as usual:
293
+ response = raw_response.parse()
294
+ print(response.choices[0].message.content)
295
+ ```
296
+
297
+ ## Links
298
+
299
+ - [Onlist Website](https://onlist.io)
300
+ - [API Documentation](https://onlist.io/docs)
301
+ - [Model Catalog](https://onlist.io/models)
302
+ - [Provider Directory](https://onlist.io/providers)
303
+ - [GitHub](https://github.com/OnlistTeam/onlist-python)
onlist-0.1.0/README.md ADDED
@@ -0,0 +1,269 @@
1
+ # Onlist Python SDK
2
+
3
+ The official Python client for [Onlist](https://onlist.io), the AI API marketplace.
4
+
5
+ Onlist aggregates 40+ AI model providers behind a single OpenAI-compatible API.
6
+ This SDK is a drop-in replacement for the OpenAI Python client, so you can switch
7
+ with one line of code.
8
+
9
+ [![PyPI version](https://img.shields.io/pypi/v/onlist.svg)](https://pypi.org/project/onlist/)
10
+ [![Python versions](https://img.shields.io/pypi/pyversions/onlist.svg)](https://pypi.org/project/onlist/)
11
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/OnlistTeam/onlist-python/blob/main/LICENSE)
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install onlist
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ ```python
22
+ from onlist import Onlist
23
+
24
+ client = Onlist(api_key="sk-...") # or set ONLIST_API_KEY env var
25
+
26
+ response = client.chat.completions.create(
27
+ model="anthropic/claude-sonnet-4",
28
+ messages=[{"role": "user", "content": "What is Onlist?"}],
29
+ )
30
+ print(response.choices[0].message.content)
31
+ ```
32
+
33
+ Get your API key at [onlist.io](https://onlist.io).
34
+
35
+ ## Authentication
36
+
37
+ The client reads your API key from:
38
+ 1. The `api_key` parameter
39
+ 2. The `ONLIST_API_KEY` environment variable
40
+ 3. The `OPENAI_API_KEY` environment variable (fallback, for easy migration)
41
+
42
+ ```bash
43
+ export ONLIST_API_KEY="sk-..."
44
+ ```
45
+
46
+ ## Provider Routing
47
+
48
+ Onlist's marketplace lets you choose which provider serves your request.
49
+ Use the `provider` field via `extra_body`:
50
+
51
+ ```python
52
+ # Pin to a specific provider
53
+ response = client.chat.completions.create(
54
+ model="anthropic/claude-sonnet-4",
55
+ messages=[{"role": "user", "content": "Hello"}],
56
+ extra_body={"provider": "alice-shop"},
57
+ )
58
+
59
+ # Route to the cheapest provider
60
+ response = client.chat.completions.create(
61
+ model="openai/gpt-4o",
62
+ messages=[{"role": "user", "content": "Hello"}],
63
+ extra_body={"provider": {"sort": "price"}},
64
+ )
65
+
66
+ # Full routing control
67
+ response = client.chat.completions.create(
68
+ model="openai/gpt-4o",
69
+ messages=[{"role": "user", "content": "Hello"}],
70
+ extra_body={
71
+ "provider": {
72
+ "allow": ["alice-shop", "bob-relay"],
73
+ "sort": "price",
74
+ "allow_fallbacks": True,
75
+ "max_price": {"prompt": 0.000003, "completion": 0.000015},
76
+ }
77
+ },
78
+ )
79
+ ```
80
+
81
+ You can also use the typed helper:
82
+
83
+ ```python
84
+ from onlist import ProviderRouting
85
+
86
+ routing = ProviderRouting(
87
+ allow=["alice-shop", "bob-relay"],
88
+ sort="price",
89
+ )
90
+
91
+ response = client.chat.completions.create(
92
+ model="openai/gpt-4o",
93
+ messages=[{"role": "user", "content": "Hello"}],
94
+ extra_body={"provider": routing.model_dump(exclude_none=True)},
95
+ )
96
+ ```
97
+
98
+ ## Streaming
99
+
100
+ ```python
101
+ stream = client.chat.completions.create(
102
+ model="anthropic/claude-sonnet-4",
103
+ messages=[{"role": "user", "content": "Write a haiku about APIs"}],
104
+ stream=True,
105
+ )
106
+
107
+ for chunk in stream:
108
+ content = chunk.choices[0].delta.content
109
+ if content:
110
+ print(content, end="", flush=True)
111
+ ```
112
+
113
+ ## Async Usage
114
+
115
+ ```python
116
+ import asyncio
117
+ from onlist import AsyncOnlist
118
+
119
+ async def main():
120
+ client = AsyncOnlist(api_key="sk-...")
121
+
122
+ response = await client.chat.completions.create(
123
+ model="openai/gpt-4o",
124
+ messages=[{"role": "user", "content": "Hello!"}],
125
+ )
126
+ print(response.choices[0].message.content)
127
+
128
+ asyncio.run(main())
129
+ ```
130
+
131
+ ## Marketplace API
132
+
133
+ Query the Onlist marketplace for models and providers:
134
+
135
+ ```python
136
+ from onlist import Onlist
137
+
138
+ client = Onlist(api_key="sk-...")
139
+
140
+ # List available models with pricing
141
+ models = client.marketplace.models.list(limit=10)
142
+ for m in models.data:
143
+ print(f"{m['id']} - input: {m.get('pricing', {}).get('prompt', 'N/A')}")
144
+
145
+ # Get detailed model info with all provider offers
146
+ detail = client.marketplace.models.get("anthropic/claude-sonnet-4")
147
+ print(f"{detail.id} - {len(detail.providers)} providers")
148
+
149
+ # Browse providers
150
+ providers = client.marketplace.providers.list()
151
+ for p in providers.data:
152
+ print(f"{p.slug} - score: {p.score}")
153
+
154
+ # Get a specific provider's profile
155
+ provider = client.marketplace.providers.get("alice-shop")
156
+ print(f"{provider.display_name} - {provider.model_count} models")
157
+ ```
158
+
159
+ ## Other APIs
160
+
161
+ Since Onlist is fully OpenAI-compatible, all standard endpoints work:
162
+
163
+ ```python
164
+ # Embeddings
165
+ embedding = client.embeddings.create(
166
+ model="openai/text-embedding-3-small",
167
+ input="Hello world",
168
+ )
169
+
170
+ # Image generation
171
+ image = client.images.generate(
172
+ model="openai/gpt-image-2",
173
+ prompt="A sunset over Tokyo",
174
+ )
175
+
176
+ # Text-to-speech
177
+ audio = client.audio.speech.create(
178
+ model="openai/tts-1",
179
+ voice="alloy",
180
+ input="Welcome to Onlist.",
181
+ )
182
+ ```
183
+
184
+ ## Error Handling
185
+
186
+ For OpenAI-compatible API calls (`chat.completions`, `embeddings`, etc.), the
187
+ standard `openai` exceptions are raised:
188
+
189
+ ```python
190
+ import openai
191
+ from onlist import Onlist
192
+
193
+ client = Onlist(api_key="sk-...")
194
+
195
+ try:
196
+ response = client.chat.completions.create(
197
+ model="openai/gpt-4o",
198
+ messages=[{"role": "user", "content": "Hello"}],
199
+ )
200
+ except openai.AuthenticationError:
201
+ print("Invalid API key")
202
+ except openai.RateLimitError as e:
203
+ print(f"Rate limited: {e.message}")
204
+ ```
205
+
206
+ For marketplace API calls (`client.marketplace.*`), Onlist-specific exceptions
207
+ are raised:
208
+
209
+ ```python
210
+ from onlist import Onlist, AuthenticationError, APIError
211
+
212
+ client = Onlist(api_key="sk-...")
213
+
214
+ try:
215
+ providers = client.marketplace.providers.list()
216
+ except AuthenticationError:
217
+ print("Invalid API key for marketplace")
218
+ except APIError as e:
219
+ print(f"API error {e.status_code}: {e.message}")
220
+ ```
221
+
222
+ ## Migrate from OpenAI or OpenRouter
223
+
224
+ Already using the OpenAI SDK? Change one line:
225
+
226
+ ```diff
227
+ - from openai import OpenAI
228
+ - client = OpenAI(api_key="sk-...")
229
+ + from onlist import Onlist
230
+ + client = Onlist(api_key="sk-...")
231
+ ```
232
+
233
+ Or, if you prefer to keep using `openai` directly:
234
+
235
+ ```python
236
+ from openai import OpenAI
237
+
238
+ client = OpenAI(
239
+ api_key="your-onlist-key",
240
+ base_url="https://onlist.io/v1",
241
+ )
242
+ ```
243
+
244
+ ## Routing Metadata
245
+
246
+ Onlist returns routing information in response headers. Access them to see
247
+ which provider actually served your request:
248
+
249
+ ```python
250
+ # Use the with_raw_response pattern from the openai SDK:
251
+ raw_response = client.chat.completions.with_raw_response.create(
252
+ model="openai/gpt-4o",
253
+ messages=[{"role": "user", "content": "Hello"}],
254
+ )
255
+ print(raw_response.headers.get("x-onlist-route-id"))
256
+ print(raw_response.headers.get("x-onlist-provider"))
257
+
258
+ # Parse the completion as usual:
259
+ response = raw_response.parse()
260
+ print(response.choices[0].message.content)
261
+ ```
262
+
263
+ ## Links
264
+
265
+ - [Onlist Website](https://onlist.io)
266
+ - [API Documentation](https://onlist.io/docs)
267
+ - [Model Catalog](https://onlist.io/models)
268
+ - [Provider Directory](https://onlist.io/providers)
269
+ - [GitHub](https://github.com/OnlistTeam/onlist-python)