2121from fastapi .openapi .models import OAuth2
2222from fastapi .openapi .models import OAuthFlowAuthorizationCode
2323from fastapi .openapi .models import OAuthFlows
24+ import google .auth .credentials
2425from google .auth .exceptions import RefreshError
2526from google .auth .transport .requests import Request
26- from google .oauth2 .credentials import Credentials
27+ import google .oauth2 .credentials
2728from pydantic import BaseModel
2829from pydantic import model_validator
2930
4041
4142@experimental
4243class BigQueryCredentialsConfig (BaseModel ):
43- """Configuration for Google API tools. (Experimental)"""
44+ """Configuration for Google API tools (Experimental).
45+
46+ Please do not use this in production, as it may be deprecated later.
47+ """
4448
4549 # Configure the model to allow arbitrary types like Credentials
4650 model_config = {"arbitrary_types_allowed" : True }
4751
48- credentials : Optional [Credentials ] = None
49- """the existing oauth credentials to use. If set,this credential will be used
52+ credentials : Optional [google . auth . credentials . Credentials ] = None
53+ """The existing auth credentials to use. If set, this credential will be used
5054 for every end user, end users don't need to be involved in the oauthflow. This
5155 field is mutually exclusive with client_id, client_secret and scopes.
5256 Don't set this field unless you are sure this credential has the permission to
5357 access every end user's data.
5458
55- Example usage: when the agent is deployed in Google Cloud environment and
59+ Example usage 1: When the agent is deployed in Google Cloud environment and
5660 the service account (used as application default credentials) has access to
5761 all the required BigQuery resource. Setting this credential to allow user to
5862 access the BigQuery resource without end users going through oauth flow.
5963
60- To get application default credential: `google.auth.default(...)`. See more
64+ To get application default credential, use : `google.auth.default(...)`. See more
6165 details in https://cloud.google.com/docs/authentication/application-default-credentials.
6266
67+ Example usage 2: When the agent wants to access the user's BigQuery resources
68+ using the service account key credentials.
69+
70+ To load service account key credentials, use: `google.auth.load_credentials_from_file(...)`.
71+ See more details in https://cloud.google.com/iam/docs/service-account-creds#user-managed-keys.
72+
6373 When the deployed environment cannot provide a pre-existing credential,
6474 consider setting below client_id, client_secret and scope for end users to go
6575 through oauth flow, so that agent can access the user data.
@@ -86,7 +96,9 @@ def __post_init__(self) -> BigQueryCredentialsConfig:
8696 " client_id/client_secret/scopes."
8797 )
8898
89- if self .credentials :
99+ if self .credentials and isinstance (
100+ self .credentials , google .oauth2 .credentials .Credentials
101+ ):
90102 self .client_id = self .credentials .client_id
91103 self .client_secret = self .credentials .client_secret
92104 self .scopes = self .credentials .scopes
@@ -115,7 +127,7 @@ def __init__(self, credentials_config: BigQueryCredentialsConfig):
115127
116128 async def get_valid_credentials (
117129 self , tool_context : ToolContext
118- ) -> Optional [Credentials ]:
130+ ) -> Optional [google . auth . credentials . Credentials ]:
119131 """Get valid credentials, handling refresh and OAuth flow as needed.
120132
121133 Args:
@@ -127,7 +139,7 @@ async def get_valid_credentials(
127139 # First, try to get credentials from the tool context
128140 creds_json = tool_context .state .get (BIGQUERY_TOKEN_CACHE_KEY , None )
129141 creds = (
130- Credentials .from_authorized_user_info (
142+ google . oauth2 . credentials . Credentials .from_authorized_user_info (
131143 json .loads (creds_json ), self .credentials_config .scopes
132144 )
133145 if creds_json
@@ -138,6 +150,11 @@ async def get_valid_credentials(
138150 if not creds :
139151 creds = self .credentials_config .credentials
140152
153+ # If non-oauth credentials are provided then use them as is. This helps
154+ # in flows such as service account keys
155+ if creds and not isinstance (creds , google .oauth2 .credentials .Credentials ):
156+ return creds
157+
141158 # Check if we have valid credentials
142159 if creds and creds .valid :
143160 return creds
@@ -159,7 +176,7 @@ async def get_valid_credentials(
159176
160177 async def _perform_oauth_flow (
161178 self , tool_context : ToolContext
162- ) -> Optional [Credentials ]:
179+ ) -> Optional [google . oauth2 . credentials . Credentials ]:
163180 """Perform OAuth flow to get new credentials.
164181
165182 Args:
@@ -199,7 +216,7 @@ async def _perform_oauth_flow(
199216
200217 if auth_response :
201218 # OAuth flow completed, create credentials
202- creds = Credentials (
219+ creds = google . oauth2 . credentials . Credentials (
203220 token = auth_response .oauth2 .access_token ,
204221 refresh_token = auth_response .oauth2 .refresh_token ,
205222 token_uri = auth_scheme .flows .authorizationCode .tokenUrl ,
0 commit comments