Skip to content

Commit 9cf0f06

Browse files
sambarnesdmontagu
andauthored
feat: add optional base_url kwarg to OpenAIModel (#243)
Co-authored-by: David Montague <[email protected]>
1 parent 592a88c commit 9cf0f06

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

docs/install.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,23 @@ agent = Agent(model)
128128
...
129129
```
130130

131+
#### `base_url` argument
132+
133+
To use another OpenAI-compatible API, such as [OpenRouter](https://openrouter.ai), you can make use of the [`base_url` argument][pydantic_ai.models.openai.OpenAIModel.__init__]:
134+
135+
```python {title="openai_model_base_url.py"}
136+
from pydantic_ai import Agent
137+
from pydantic_ai.models.openai import OpenAIModel
138+
139+
model = OpenAIModel(
140+
'anthropic/claude-3.5-sonnet',
141+
base_url='https://openrouter.ai/api/v1',
142+
api_key='your-api-key',
143+
)
144+
agent = Agent(model)
145+
...
146+
```
147+
131148
#### Custom OpenAI Client
132149

133150
`OpenAIModel` also accepts a custom `AsyncOpenAI` client via the [`openai_client` parameter][pydantic_ai.models.openai.OpenAIModel.__init__],

pydantic_ai_slim/pydantic_ai/models/openai.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ def __init__(
7070
self,
7171
model_name: OpenAIModelName,
7272
*,
73+
base_url: str | None = None,
7374
api_key: str | None = None,
7475
openai_client: AsyncOpenAI | None = None,
7576
http_client: AsyncHTTPClient | None = None,
@@ -80,22 +81,25 @@ def __init__(
8081
model_name: The name of the OpenAI model to use. List of model names available
8182
[here](https://github.com/openai/openai-python/blob/v1.54.3/src/openai/types/chat_model.py#L7)
8283
(Unfortunately, despite being ask to do so, OpenAI do not provide `.inv` files for their API).
84+
base_url: The base url for the OpenAI requests. If not provided, the `OPENAI_BASE_URL` environment variable
85+
will be used if available. Otherwise, defaults to OpenAI's base url.
8386
api_key: The API key to use for authentication, if not provided, the `OPENAI_API_KEY` environment variable
8487
will be used if available.
8588
openai_client: An existing
8689
[`AsyncOpenAI`](https://github.com/openai/openai-python?tab=readme-ov-file#async-usage)
87-
client to use, if provided, `api_key` and `http_client` must be `None`.
90+
client to use. If provided, `base_url`, `api_key`, and `http_client` must be `None`.
8891
http_client: An existing `httpx.AsyncClient` to use for making HTTP requests.
8992
"""
9093
self.model_name: OpenAIModelName = model_name
9194
if openai_client is not None:
9295
assert http_client is None, 'Cannot provide both `openai_client` and `http_client`'
96+
assert base_url is None, 'Cannot provide both `openai_client` and `base_url`'
9397
assert api_key is None, 'Cannot provide both `openai_client` and `api_key`'
9498
self.client = openai_client
9599
elif http_client is not None:
96-
self.client = AsyncOpenAI(api_key=api_key, http_client=http_client)
100+
self.client = AsyncOpenAI(base_url=base_url, api_key=api_key, http_client=http_client)
97101
else:
98-
self.client = AsyncOpenAI(api_key=api_key, http_client=cached_async_http_client())
102+
self.client = AsyncOpenAI(base_url=base_url, api_key=api_key, http_client=cached_async_http_client())
99103

100104
async def agent_model(
101105
self,

tests/models/test_openai.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,19 @@
4949

5050
def test_init():
5151
m = OpenAIModel('gpt-4', api_key='foobar')
52+
assert str(m.client.base_url) == 'https://api.openai.com/v1/'
5253
assert m.client.api_key == 'foobar'
5354
assert m.name() == 'openai:gpt-4'
5455

5556

57+
def test_init_with_base_url():
58+
m = OpenAIModel('gpt-4', base_url='https://example.com/v1', api_key='foobar')
59+
assert str(m.client.base_url) == 'https://example.com/v1/'
60+
assert m.client.api_key == 'foobar'
61+
assert m.name() == 'openai:gpt-4'
62+
m.name()
63+
64+
5665
@dataclass
5766
class MockAsyncStream:
5867
_iter: Iterator[chat.ChatCompletionChunk]

0 commit comments

Comments
 (0)