22from dataclasses import dataclass
33from datetime import datetime
44from enum import StrEnum , auto
5- from typing import Any , ClassVar , Generic , Literal , TypeVar , override
5+ from typing import Any , ClassVar , Generic , Literal , Self , TypeVar
66
77from pydantic import BaseModel , ConfigDict , Field , NonNegativeInt , PositiveInt
88
@@ -143,8 +143,11 @@ class ValidationError(Exception):
143143 errors : list [str ]
144144
145145
146- class ResourceOwnerPasswordOAuth2Credentials (BaseModel ):
147- grant_type : ClassVar [str ] = "password"
146+ class _BaseOAuth2CredentialsData (BaseModel ):
147+ """
148+ Abstract base class containing common OAuth2 credential fields.
149+ """
150+
148151 client_credentials_placement : ClassVar [OAuth2ClientCredentialsPlacement ] = (
149152 OAuth2ClientCredentialsPlacement .FORM
150153 )
@@ -161,241 +164,93 @@ class ResourceOwnerPasswordOAuth2Credentials(BaseModel):
161164 json_schema_extra = {"secret" : True },
162165 )
163166
164- @classmethod
165- def with_client_credentials_placement (
166- cls ,
167- placement : OAuth2ClientCredentialsPlacement ,
168- ) -> type ["ResourceOwnerPasswordOAuth2Credentials" ]:
169- """
170- Returns a subclass with a custom client credentials placement.
171- """
172-
173- return type (cls .__name__ , (cls ,), {"client_credentials_placement" : placement })
174-
175-
176- class ClientCredentialsOAuth2Credentials (BaseModel ):
177- grant_type : ClassVar [str ] = "client_credentials"
178- client_credentials_placement : ClassVar [OAuth2ClientCredentialsPlacement ] = (
179- OAuth2ClientCredentialsPlacement .HEADERS
180- )
181-
182167 # This configuration provides a "title" annotation for the UI to display
183168 # instead of the class name.
184169 model_config = ConfigDict (
185170 title = "OAuth" ,
186171 )
187172
188- credentials_title : Literal ["OAuth Credentials" ] = Field (
189- default = "OAuth Credentials" , json_schema_extra = {"type" : "string" }
190- )
191- client_id : str = Field (
192- title = "Client Id" ,
193- json_schema_extra = {"secret" : True },
194- )
195- client_secret : str = Field (
196- title = "Client Secret" ,
197- json_schema_extra = {"secret" : True },
198- )
199-
200- @classmethod
201- def with_client_credentials_placement (
202- cls ,
203- placement : OAuth2ClientCredentialsPlacement ,
204- ) -> type ["ClientCredentialsOAuth2Credentials" ]:
205- """
206- Returns a subclass with a custom client credentials placement.
207- """
208-
209- return type (cls .__name__ , (cls ,), {"client_credentials_placement" : placement })
210-
211-
212- class AuthorizationCodeFlowOAuth2Credentials (BaseModel , metaclass = abc .ABCMeta ):
213- grant_type : ClassVar [str ] = "authorization_code"
214- client_credentials_placement : ClassVar [OAuth2ClientCredentialsPlacement ] = (
215- OAuth2ClientCredentialsPlacement .FORM
216- )
217-
218- credentials_title : Literal ["OAuth Credentials" ] = Field (
219- default = "OAuth Credentials" , json_schema_extra = {"type" : "string" }
220- )
221- client_id : str = Field (
222- title = "Client Id" ,
223- json_schema_extra = {"secret" : True },
224- )
225- client_secret : str = Field (
226- title = "Client Secret" ,
227- json_schema_extra = {"secret" : True },
228- )
229-
230- @abc .abstractmethod
231- def _you_must_build_oauth2_credentials_for_a_provider (self ): ...
232-
233173 @classmethod
234174 def with_client_credentials_placement (
235175 cls ,
236176 placement : OAuth2ClientCredentialsPlacement ,
237- ) -> type ["AuthorizationCodeFlowOAuth2Credentials" ]:
177+ ) -> type [Self ]:
238178 """
239179 Returns a subclass with a custom client credentials placement.
240180 """
241181
242- return type (cls .__name__ , (cls ,), {"client_credentials_placement" : placement })
182+ return type (
183+ str (cls .__name__ ), (cls ,), {"client_credentials_placement" : placement }
184+ ) # pyright: ignore[reportReturnType]
243185
244186 @classmethod
245- def for_provider (
246- cls ,
247- provider : str ,
248- ) -> type ["AuthorizationCodeFlowOAuth2Credentials" ]:
187+ def for_provider (cls , provider : str ) -> type [Self ]:
249188 """
250189 Builds an OAuth2Credentials model for the given OAuth2 `provider`.
251190 This routine is only available in Pydantic V2 environments.
252191 """
253192 from pydantic import ConfigDict
254193
255- return type (
194+ return type ( # pyright: ignore[reportReturnType]
256195 cls .__name__ ,
257196 (cls ,),
258197 {
259198 "model_config" : ConfigDict (
260199 json_schema_extra = {"x-oauth2-provider" : provider },
261200 title = "OAuth" ,
262201 ),
263- "_you_must_build_oauth2_credentials_for_a_provider" : lambda _ : None ,
202+ "_you_must_build_oauth2_credentials_for_a_provider" : lambda _ : None , # pyright: ignore[reportUnknownLambdaType]
264203 },
265204 )
266205
267206
268- class LongLivedClientCredentialsOAuth2Credentials (BaseModel , metaclass = abc .ABCMeta ):
269- # This configuration provides a "title" annotation for the UI to display
270- # instead of the class name.
271- model_config = ConfigDict (
272- title = "OAuth" ,
273- )
207+ class ResourceOwnerPasswordOAuth2Credentials (_BaseOAuth2CredentialsData ):
208+ grant_type : ClassVar [str ] = "password"
274209
275- credentials_title : Literal ["OAuth Credentials" ] = Field (
276- default = "OAuth Credentials" , json_schema_extra = {"type" : "string" }
277- )
278- client_id : str = Field (
279- title = "Client Id" ,
280- json_schema_extra = {"secret" : True },
281- )
282- client_secret : str = Field (
283- title = "Client Secret" ,
284- json_schema_extra = {"secret" : True },
210+
211+ class ClientCredentialsOAuth2Credentials (_BaseOAuth2CredentialsData ):
212+ grant_type : ClassVar [str ] = "client_credentials"
213+ client_credentials_placement : ClassVar [OAuth2ClientCredentialsPlacement ] = (
214+ OAuth2ClientCredentialsPlacement .HEADERS
285215 )
286- access_token : str = Field (title = "Access Token" , json_schema_extra = {"secret" : True })
216+
217+
218+ class AuthorizationCodeFlowOAuth2Credentials (
219+ _BaseOAuth2CredentialsData , metaclass = abc .ABCMeta
220+ ):
221+ grant_type : ClassVar [str ] = "authorization_code"
287222
288223 @abc .abstractmethod
289224 def _you_must_build_oauth2_credentials_for_a_provider (self ): ...
290225
291- @classmethod
292- def for_provider (
293- cls ,
294- provider : str ,
295- ) -> type ["LongLivedClientCredentialsOAuth2Credentials" ]:
296- """
297- Builds an OAuth2Credentials model for the given OAuth2 `provider`.
298- This routine is only available in Pydantic V2 environments.
299- """
300- from pydantic import ConfigDict
301226
302- return type (
303- cls .__name__ ,
304- (cls ,),
305- {
306- "model_config" : ConfigDict (
307- json_schema_extra = {"x-oauth2-provider" : provider },
308- title = "OAuth" ,
309- ),
310- "_you_must_build_oauth2_credentials_for_a_provider" : lambda _ : None ,
311- },
312- )
227+ class LongLivedClientCredentialsOAuth2Credentials (
228+ _BaseOAuth2CredentialsData , metaclass = abc .ABCMeta
229+ ):
230+ access_token : str = Field (title = "Access Token" , json_schema_extra = {"secret" : True })
231+
232+ @abc .abstractmethod
233+ def _you_must_build_oauth2_credentials_for_a_provider (self ): ...
313234
314235
315- class BaseOAuth2Credentials (BaseModel , metaclass = abc .ABCMeta ):
236+ class BaseOAuth2Credentials (_BaseOAuth2CredentialsData , metaclass = abc .ABCMeta ):
316237 grant_type : ClassVar [str ] = "refresh_token"
317- client_credentials_placement : ClassVar [OAuth2ClientCredentialsPlacement ] = (
318- OAuth2ClientCredentialsPlacement .FORM
319- )
320238
321- credentials_title : Literal ["OAuth Credentials" ] = Field (
322- default = "OAuth Credentials" , json_schema_extra = {"type" : "string" }
323- )
324- client_id : str = Field (
325- title = "Client Id" ,
326- json_schema_extra = {"secret" : True },
327- )
328- client_secret : str = Field (
329- title = "Client Secret" ,
330- json_schema_extra = {"secret" : True },
331- )
332239 refresh_token : str = Field (
333240 title = "Refresh Token" ,
334241 json_schema_extra = {"secret" : True },
335242 )
336243
337- @classmethod
338- def with_client_credentials_placement (
339- cls ,
340- placement : OAuth2ClientCredentialsPlacement ,
341- ) -> type ["BaseOAuth2Credentials" ]:
342- """
343- Returns a subclass with a custom client credentials placement.
344- """
345-
346- return type (cls .__name__ , (cls ,), {"client_credentials_placement" : placement })
347-
348244 @abc .abstractmethod
349245 def _you_must_build_oauth2_credentials_for_a_provider (self ): ...
350246
351- @classmethod
352- def for_provider (cls , provider : str ) -> type ["BaseOAuth2Credentials" ]:
353- """
354- Builds an OAuth2Credentials model for the given OAuth2 `provider`.
355- This routine is only available in Pydantic V2 environments.
356- """
357- from pydantic import ConfigDict
358-
359- return type (
360- cls .__name__ ,
361- (cls ,),
362- {
363- "model_config" : ConfigDict (
364- json_schema_extra = {"x-oauth2-provider" : provider },
365- title = "OAuth" ,
366- ),
367- "_you_must_build_oauth2_credentials_for_a_provider" : lambda _ : None ,
368- },
369- )
370-
371247
372248class RotatingOAuth2Credentials (BaseOAuth2Credentials , metaclass = abc .ABCMeta ):
373249 access_token : str = Field (title = "Access Token" , json_schema_extra = {"secret" : True })
374250 access_token_expires_at : datetime = Field (
375251 title = "Access token expiration time." ,
376252 )
377253
378- @classmethod
379- @override
380- def for_provider (cls , provider : str ) -> type ["RotatingOAuth2Credentials" ]:
381- """
382- Builds an OAuth2Credentials model for the given OAuth2 `provider`.
383- This routine is only available in Pydantic V2 environments.
384- """
385- from pydantic import ConfigDict
386-
387- return type (
388- cls .__name__ ,
389- (cls ,),
390- {
391- "model_config" : ConfigDict (
392- json_schema_extra = {"x-oauth2-provider" : provider },
393- title = "OAuth" ,
394- ),
395- "_you_must_build_oauth2_credentials_for_a_provider" : lambda _ : None ,
396- },
397- )
398-
399254
400255class GoogleServiceAccountSpec (BaseModel ):
401256 scopes : list [str ]
0 commit comments