Skip to content

Commit 359554c

Browse files
authored
Set 'us-central1' by default on GoogleProvider (#2031)
1 parent e2e6a44 commit 359554c

38 files changed

+850
-804
lines changed

pydantic_ai_slim/pydantic_ai/providers/google.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,12 @@ def __init__(
104104
self._client = genai.Client(
105105
vertexai=vertexai,
106106
project=project or os.environ.get('GOOGLE_CLOUD_PROJECT'),
107-
location=location or os.environ.get('GOOGLE_CLOUD_LOCATION'),
107+
# From https://github.com/pydantic/pydantic-ai/pull/2031/files#r2169682149:
108+
# Currently `us-central1` supports the most models by far of any region including `global`, but not
109+
# all of them. `us-central1` has all google models but is missing some Anthropic partner models,
110+
# which use `us-east5` instead. `global` has fewer models but higher availability.
111+
# For more details, check: https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations#available-regions
112+
location=location or os.environ.get('GOOGLE_CLOUD_LOCATION') or 'us-central1',
108113
credentials=credentials,
109114
http_options={'headers': {'User-Agent': get_user_agent()}},
110115
)

tests/conftest.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import sys
99
from collections.abc import AsyncIterator, Iterator
1010
from contextlib import contextmanager
11+
from dataclasses import dataclass
1112
from datetime import datetime
1213
from pathlib import Path
1314
from types import ModuleType
@@ -175,8 +176,8 @@ def check_import() -> bool:
175176
import_success = True
176177

177178

178-
@pytest.fixture(autouse=True)
179-
def set_event_loop(anyio_backend: str) -> Iterator[None]:
179+
@pytest.fixture(scope='session', autouse=True)
180+
def event_loop() -> Iterator[None]:
180181
new_loop = asyncio.new_event_loop()
181182
asyncio.set_event_loop(new_loop)
182183
yield
@@ -315,6 +316,55 @@ def bedrock_provider():
315316
pytest.skip('boto3 is not installed')
316317

317318

319+
@pytest.fixture(autouse=True)
320+
def vertex_provider_auth(mocker: MockerFixture) -> None: # pragma: lax no cover
321+
# Locally, we authenticate via `gcloud` CLI, so we don't need to patch anything.
322+
if not os.getenv('CI', False):
323+
return # pragma: lax no cover
324+
325+
try:
326+
from google.genai import _api_client
327+
except ImportError:
328+
pytest.skip('google is not installed')
329+
330+
@dataclass
331+
class NoOpCredentials:
332+
token = 'my-token'
333+
quota_project_id = 'pydantic-ai'
334+
335+
def refresh(self, request: httpx.Request): ...
336+
337+
def expired(self) -> bool:
338+
return False
339+
340+
return_value = (NoOpCredentials(), 'pydantic-ai')
341+
mocker.patch.object(_api_client, '_load_auth', return_value=return_value)
342+
343+
344+
@pytest.fixture()
345+
async def vertex_provider():
346+
# NOTE: You need to comment out this line to rewrite the cassettes locally.
347+
if not os.getenv('CI', False): # pragma: lax no cover
348+
pytest.skip('Requires properly configured local google vertex config to pass')
349+
350+
try:
351+
from google import genai
352+
353+
from pydantic_ai.providers.google import GoogleProvider
354+
except ImportError: # pragma: lax no cover
355+
pytest.skip('google is not installed')
356+
357+
project = os.getenv('GOOGLE_PROJECT', 'pydantic-ai')
358+
location = os.getenv('GOOGLE_LOCATION', 'us-central1')
359+
client = genai.Client(vertexai=True, project=project, location=location)
360+
361+
try:
362+
yield GoogleProvider(client=client)
363+
finally:
364+
client.aio._api_client._httpx_client.close() # type: ignore
365+
await client.aio._api_client._async_httpx_client.aclose() # type: ignore
366+
367+
318368
@pytest.fixture()
319369
def model(
320370
request: pytest.FixtureRequest,

tests/models/cassettes/test_google/test_google_model.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ interactions:
3030
alt-svc:
3131
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
3232
content-length:
33-
- '644'
33+
- '687'
3434
content-type:
3535
- application/json; charset=UTF-8
3636
server-timing:
37-
- gfet4t7; dur=322
37+
- gfet4t7; dur=531
3838
transfer-encoding:
3939
- chunked
4040
vary:
@@ -43,14 +43,15 @@ interactions:
4343
- Referer
4444
parsed_body:
4545
candidates:
46-
- avgLogprobs: -0.0009223055941137401
46+
- avgLogprobs: -0.0007684422995556484
4747
content:
4848
parts:
4949
- text: |
5050
Hello there! How can I help you today?
5151
role: model
5252
finishReason: STOP
5353
modelVersion: gemini-1.5-flash
54+
responseId: wVpeaPOdAaXTnvgPlIeSoQg
5455
usageMetadata:
5556
candidatesTokenCount: 11
5657
candidatesTokensDetails:

tests/models/cassettes/test_google/test_google_model_document_url_input.yaml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ interactions:
252252
accept-ranges:
253253
- bytes
254254
age:
255-
- '427557'
255+
- '264068'
256256
alt-svc:
257257
- h3=":443"; ma=86400
258258
cache-control:
@@ -268,7 +268,7 @@ interactions:
268268
etag:
269269
- '"33d0-438b181451e00"'
270270
expires:
271-
- Tue, 13 May 2025 21:19:22 GMT
271+
- Tue, 24 Jun 2025 13:27:15 GMT
272272
last-modified:
273273
- Mon, 27 Aug 2007 17:15:36 GMT
274274
strict-transport-security:
@@ -312,11 +312,11 @@ interactions:
312312
alt-svc:
313313
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
314314
content-length:
315-
- '751'
315+
- '776'
316316
content-type:
317317
- application/json; charset=UTF-8
318318
server-timing:
319-
- gfet4t7; dur=1704
319+
- gfet4t7; dur=1228
320320
transfer-encoding:
321321
- chunked
322322
vary:
@@ -325,26 +325,27 @@ interactions:
325325
- Referer
326326
parsed_body:
327327
candidates:
328-
- avgLogprobs: -0.27702528635660806
328+
- avgLogprobs: -0.28572704394658405
329329
content:
330330
parts:
331331
- text: |
332-
The main content of the document is the phrase "Dummy PDF file".
332+
The document appears to be a "Dummy PDF file".
333333
role: model
334334
finishReason: STOP
335335
modelVersion: gemini-2.0-flash
336+
responseId: 4FpeaJWYOLq3nvgP0vasuQk
336337
usageMetadata:
337-
candidatesTokenCount: 15
338+
candidatesTokenCount: 12
338339
candidatesTokensDetails:
339340
- modality: TEXT
340-
tokenCount: 15
341+
tokenCount: 12
341342
promptTokenCount: 1305
342343
promptTokensDetails:
343344
- modality: TEXT
344345
tokenCount: 15
345346
- modality: DOCUMENT
346347
tokenCount: 1290
347-
totalTokenCount: 1320
348+
totalTokenCount: 1317
348349
status:
349350
code: 200
350351
message: OK

tests/models/cassettes/test_google/test_google_model_empty_user_prompt.yaml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ interactions:
3030
alt-svc:
3131
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
3232
content-length:
33-
- '736'
33+
- '701'
3434
content-type:
3535
- application/json; charset=UTF-8
3636
server-timing:
37-
- gfet4t7; dur=361
37+
- gfet4t7; dur=444
3838
transfer-encoding:
3939
- chunked
4040
vary:
@@ -43,25 +43,25 @@ interactions:
4343
- Referer
4444
parsed_body:
4545
candidates:
46-
- avgLogprobs: -0.20726837430681502
46+
- avgLogprobs: -0.11437161529765409
4747
content:
4848
parts:
4949
- text: |
50-
Please provide me with a question or task. I need some information to be able to help you.
50+
I'm ready to assist you. Please tell me what you need.
5151
role: model
5252
finishReason: STOP
5353
modelVersion: gemini-1.5-flash
54-
responseId: y5BBaPCQELGqmecP68OBiAc
54+
responseId: 5lpeaN7wJ___698Pv8HGgAg
5555
usageMetadata:
56-
candidatesTokenCount: 21
56+
candidatesTokenCount: 17
5757
candidatesTokensDetails:
5858
- modality: TEXT
59-
tokenCount: 21
59+
tokenCount: 17
6060
promptTokenCount: 7
6161
promptTokensDetails:
6262
- modality: TEXT
6363
tokenCount: 7
64-
totalTokenCount: 28
64+
totalTokenCount: 24
6565
status:
6666
code: 200
6767
message: OK

tests/models/cassettes/test_google/test_google_model_image_as_binary_content_input.yaml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ interactions:
3333
alt-svc:
3434
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
3535
content-length:
36-
- '713'
36+
- '756'
3737
content-type:
3838
- application/json; charset=UTF-8
3939
server-timing:
40-
- gfet4t7; dur=4099
40+
- gfet4t7; dur=2659
4141
transfer-encoding:
4242
- chunked
4343
vary:
@@ -53,17 +53,18 @@ interactions:
5353
role: model
5454
finishReason: STOP
5555
modelVersion: gemini-2.0-flash
56+
responseId: 2VpeaPm3DaHp1PIPwK-EmAM
5657
usageMetadata:
5758
candidatesTokenCount: 9
5859
candidatesTokensDetails:
5960
- modality: TEXT
6061
tokenCount: 9
6162
promptTokenCount: 3367
6263
promptTokensDetails:
63-
- modality: IMAGE
64-
tokenCount: 3354
6564
- modality: TEXT
6665
tokenCount: 13
66+
- modality: IMAGE
67+
tokenCount: 3354
6768
totalTokenCount: 3376
6869
status:
6970
code: 200

tests/models/cassettes/test_google/test_google_model_image_url_input.yaml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ interactions:
580580
access-control-allow-origin:
581581
- '*'
582582
age:
583-
- '432185'
583+
- '1386476'
584584
cache-control:
585585
- public, max-age=31536000
586586
connection:
@@ -632,11 +632,11 @@ interactions:
632632
alt-svc:
633633
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
634634
content-length:
635-
- '696'
635+
- '740'
636636
content-type:
637637
- application/json; charset=UTF-8
638638
server-timing:
639-
- gfet4t7; dur=979
639+
- gfet4t7; dur=1424
640640
transfer-encoding:
641641
- chunked
642642
vary:
@@ -645,26 +645,27 @@ interactions:
645645
- Referer
646646
parsed_body:
647647
candidates:
648-
- avgLogprobs: -0.2194784709385463
648+
- avgLogprobs: -0.1821905771891276
649649
content:
650650
parts:
651651
- text: |
652-
That's a potato!
652+
That is a potato.
653653
role: model
654654
finishReason: STOP
655655
modelVersion: gemini-2.0-flash
656+
responseId: 3VpeaPexBLq3nvgP0vasuQk
656657
usageMetadata:
657-
candidatesTokenCount: 7
658+
candidatesTokenCount: 6
658659
candidatesTokensDetails:
659660
- modality: TEXT
660-
tokenCount: 7
661+
tokenCount: 6
661662
promptTokenCount: 1817
662663
promptTokensDetails:
663664
- modality: TEXT
664665
tokenCount: 11
665666
- modality: IMAGE
666667
tokenCount: 1806
667-
totalTokenCount: 1824
668+
totalTokenCount: 1823
668669
status:
669670
code: 200
670671
message: OK

tests/models/cassettes/test_google/test_google_model_instructions.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ interactions:
3030
alt-svc:
3131
- h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
3232
content-length:
33-
- '637'
33+
- '680'
3434
content-type:
3535
- application/json; charset=UTF-8
3636
server-timing:
37-
- gfet4t7; dur=449
37+
- gfet4t7; dur=444
3838
transfer-encoding:
3939
- chunked
4040
vary:
@@ -43,14 +43,15 @@ interactions:
4343
- Referer
4444
parsed_body:
4545
candidates:
46-
- avgLogprobs: -0.00021161907352507114
46+
- avgLogprobs: -0.0001856483577284962
4747
content:
4848
parts:
4949
- text: |
5050
The capital of France is Paris.
5151
role: model
5252
finishReason: STOP
5353
modelVersion: gemini-2.0-flash
54+
responseId: 41peaK-wOMSenvgPh-vRiAY
5455
usageMetadata:
5556
candidatesTokenCount: 8
5657
candidatesTokensDetails:

0 commit comments

Comments
 (0)