22from contextlib import asynccontextmanager
33from dataclasses import dataclass
44from datetime import datetime , timedelta , timezone
5- from typing import TYPE_CHECKING , Union , cast
5+ from typing import TYPE_CHECKING , cast
66from urllib .parse import urlencode
77
88from pydantic import BaseModel , SecretStr , TypeAdapter , field_validator
1919@dataclass
2020class GitHubExchangeError :
2121 error : str
22- error_description : Union [ str , None ] = None
22+ error_description : str | None = None
2323
2424
2525@dataclass
@@ -33,33 +33,33 @@ def check_scope(cls, v: str) -> list[str]:
3333 return [s for s in v .split (',' ) if s ]
3434
3535
36- github_exchange_type = TypeAdapter (Union [ GitHubExchange , GitHubExchangeError ] )
36+ github_exchange_type = TypeAdapter (GitHubExchange | GitHubExchangeError )
3737
3838
3939class GithubUser (BaseModel ):
4040 login : str
41- name : Union [ str , None ]
42- email : Union [ str , None ]
41+ name : str | None
42+ email : str | None
4343 avatar_url : str
4444 created_at : datetime
4545 updated_at : datetime
4646 public_repos : int
4747 public_gists : int
4848 followers : int
4949 following : int
50- company : Union [ str , None ]
51- blog : Union [ str , None ]
52- location : Union [ str , None ]
53- hireable : Union [ bool , None ]
54- bio : Union [ str , None ]
55- twitter_username : Union [ str , None ] = None
50+ company : str | None
51+ blog : str | None
52+ location : str | None
53+ hireable : bool | None
54+ bio : str | None
55+ twitter_username : str | None = None
5656
5757
5858class GitHubEmail (BaseModel ):
5959 email : str
6060 primary : bool
6161 verified : bool
62- visibility : Union [ str , None ]
62+ visibility : str | None
6363
6464
6565github_emails_ta = TypeAdapter (list [GitHubEmail ])
@@ -76,10 +76,10 @@ def __init__(
7676 github_client_id : str ,
7777 github_client_secret : SecretStr ,
7878 * ,
79- redirect_uri : Union [ str , None ] = None ,
80- scopes : Union [ list [str ], None ] = None ,
81- state_provider : Union [ 'StateProvider' , bool ] = True ,
82- exchange_cache_age : Union [ timedelta , None ] = timedelta (seconds = 30 ),
79+ redirect_uri : str | None = None ,
80+ scopes : list [str ] | None = None ,
81+ state_provider : 'StateProvider | bool' = True ,
82+ exchange_cache_age : timedelta | None = timedelta (seconds = 30 ),
8383 ):
8484 """
8585 Arguments:
@@ -114,9 +114,9 @@ async def create(
114114 client_id : str ,
115115 client_secret : SecretStr ,
116116 * ,
117- redirect_uri : Union [ str , None ] = None ,
118- state_provider : Union [ 'StateProvider' , bool ] = True ,
119- exchange_cache_age : Union [ timedelta , None ] = timedelta (seconds = 10 ),
117+ redirect_uri : str | None = None ,
118+ state_provider : 'StateProvider | bool' = True ,
119+ exchange_cache_age : timedelta | None = timedelta (seconds = 10 ),
120120 ) -> AsyncIterator ['GitHubAuthProvider' ]:
121121 """
122122 Async context manager to create a GitHubAuth instance with a new `httpx.AsyncClient`.
@@ -146,7 +146,7 @@ async def authorization_url(self) -> str:
146146 params ['state' ] = await self ._state_provider .new_state ()
147147 return f'https://github.com/login/oauth/authorize?{ urlencode (params )} '
148148
149- async def exchange_code (self , code : str , state : Union [ str , None ] = None ) -> GitHubExchange :
149+ async def exchange_code (self , code : str , state : str | None = None ) -> GitHubExchange :
150150 """
151151 Exchange a code for an access token.
152152
@@ -164,7 +164,7 @@ async def exchange_code(self, code: str, state: Union[str, None] = None) -> GitH
164164 else :
165165 return await self ._exchange_code (code , state )
166166
167- async def _exchange_code (self , code : str , state : Union [ str , None ] = None ) -> GitHubExchange :
167+ async def _exchange_code (self , code : str , state : str | None = None ) -> GitHubExchange :
168168 if self ._state_provider :
169169 if state is None :
170170 raise AuthError ('Missing GitHub auth state' , code = 'missing_state' )
@@ -224,7 +224,7 @@ class ExchangeCache:
224224 def __init__ (self ):
225225 self ._data : dict [str , tuple [datetime , GitHubExchange ]] = {}
226226
227- def get (self , key : str , max_age : timedelta ) -> Union [ GitHubExchange , None ] :
227+ def get (self , key : str , max_age : timedelta ) -> GitHubExchange | None :
228228 self ._purge (max_age )
229229 if v := self ._data .get (key ):
230230 return v [1 ]
0 commit comments