diff --git a/pydantic_ai_slim/pydantic_ai/providers/google_vertex.py b/pydantic_ai_slim/pydantic_ai/providers/google_vertex.py index ec436d764..67a70c675 100644 --- a/pydantic_ai_slim/pydantic_ai/providers/google_vertex.py +++ b/pydantic_ai_slim/pydantic_ai/providers/google_vertex.py @@ -116,6 +116,8 @@ def __init__( class _VertexAIAuth(httpx.Auth): """Auth class for Vertex AI API.""" + _refresh_lock: anyio.Lock = anyio.Lock() + credentials: BaseCredentials | ServiceAccountCredentials | None def __init__( @@ -169,10 +171,13 @@ async def _get_credentials(self) -> BaseCredentials | ServiceAccountCredentials: return creds async def _refresh_token(self) -> str: # pragma: no cover - assert self.credentials is not None - await anyio.to_thread.run_sync(self.credentials.refresh, Request()) # type: ignore[reportUnknownMemberType] - assert isinstance(self.credentials.token, str), f'Expected token to be a string, got {self.credentials.token}' # type: ignore[reportUnknownMemberType] - return self.credentials.token + async with self._refresh_lock: + assert self.credentials is not None + await anyio.to_thread.run_sync(self.credentials.refresh, Request()) # type: ignore[reportUnknownMemberType] + assert isinstance(self.credentials.token, str), ( # type: ignore[reportUnknownMemberType] + f'Expected token to be a string, got {self.credentials.token}' # type: ignore[reportUnknownMemberType] + ) + return self.credentials.token async def _async_google_auth() -> tuple[BaseCredentials, str | None]: