4848P = ParamSpec ("P" )
4949R = t .TypeVar ("R" )
5050
51+ # string-ized annotation to avoid triggering eager imports
52+ CLIENT_T = t .TypeVar ("CLIENT_T" , bound = "globus_sdk.BaseClient" )
53+
5154
5255class LoginManager :
5356 def __init__ (self ) -> None :
5457 self .storage = CLIStorage ()
5558 self ._nonstatic_requirements : dict [str , list [Scope ]] = {}
5659
60+ self ._client_pool : set [globus_sdk .BaseClient ] = set ()
61+
5762 def close (self ) -> None :
5863 self .storage .close ()
64+ for c in self ._client_pool :
65+ c .close ()
66+ self ._client_pool .clear ()
67+
68+ def _into_client_pool (self , client : CLIENT_T ) -> CLIENT_T :
69+ self ._client_pool .add (client )
70+ return client
5971
6072 def add_requirement (self , rs_name : str , scopes : t .Sequence [Scope ]) -> None :
6173 self ._nonstatic_requirements [rs_name ] = list (scopes )
@@ -373,25 +385,35 @@ def get_transfer_client(self) -> CustomTransferClient:
373385 from ..services .transfer import CustomTransferClient
374386
375387 authorizer = self ._get_client_authorizer (TransferScopes .resource_server )
376- return CustomTransferClient (authorizer = authorizer , app_name = version .app_name )
388+ return self ._into_client_pool (
389+ CustomTransferClient (authorizer = authorizer , app_name = version .app_name )
390+ )
377391
378392 def get_auth_client (self ) -> CustomAuthClient :
379393 from ..services .auth import CustomAuthClient
380394
381395 authorizer = self ._get_client_authorizer (AuthScopes .resource_server )
382- return CustomAuthClient (authorizer = authorizer , app_name = version .app_name )
396+ return self ._into_client_pool (
397+ CustomAuthClient (authorizer = authorizer , app_name = version .app_name )
398+ )
383399
384400 def get_groups_client (self ) -> globus_sdk .GroupsClient :
385401 authorizer = self ._get_client_authorizer (GroupsScopes .resource_server )
386- return globus_sdk .GroupsClient (authorizer = authorizer , app_name = version .app_name )
402+ return self ._into_client_pool (
403+ globus_sdk .GroupsClient (authorizer = authorizer , app_name = version .app_name )
404+ )
387405
388406 def get_flows_client (self ) -> globus_sdk .FlowsClient :
389407 authorizer = self ._get_client_authorizer (FlowsScopes .resource_server )
390- return globus_sdk .FlowsClient (authorizer = authorizer , app_name = version .app_name )
408+ return self ._into_client_pool (
409+ globus_sdk .FlowsClient (authorizer = authorizer , app_name = version .app_name )
410+ )
391411
392412 def get_search_client (self ) -> globus_sdk .SearchClient :
393413 authorizer = self ._get_client_authorizer (SearchScopes .resource_server )
394- return globus_sdk .SearchClient (authorizer = authorizer , app_name = version .app_name )
414+ return self ._into_client_pool (
415+ globus_sdk .SearchClient (authorizer = authorizer , app_name = version .app_name )
416+ )
395417
396418 def get_timer_client (
397419 self , * , flow_id : uuid .UUID | None = None
@@ -404,7 +426,9 @@ def get_timer_client(
404426 self ._assert_requester_has_timer_flow_consent (flow_id )
405427
406428 authorizer = self ._get_client_authorizer (TimersScopes .resource_server )
407- return globus_sdk .TimersClient (authorizer = authorizer , app_name = version .app_name )
429+ return self ._into_client_pool (
430+ globus_sdk .TimersClient (authorizer = authorizer , app_name = version .app_name )
431+ )
408432
409433 def _assert_requester_has_timer_flow_consent (self , flow_id : uuid .UUID ) -> None :
410434 flow_scope = SpecificFlowScopes (flow_id ).user
@@ -445,7 +469,9 @@ def get_specific_flow_client(
445469 ) -> globus_sdk .SpecificFlowClient :
446470 # Create a SpecificFlowClient without an authorizer
447471 # to take advantage of its scope creation code.
448- client = globus_sdk .SpecificFlowClient (flow_id , app_name = version .app_name )
472+ client = self ._into_client_pool (
473+ globus_sdk .SpecificFlowClient (flow_id , app_name = version .app_name )
474+ )
449475 assert client .scopes is not None
450476 self .add_requirement (client .scopes .resource_server , [client .scopes .user ])
451477
@@ -531,11 +557,13 @@ def get_gcs_client(
531557 f"Please run:\n \n { login_context .login_command } \n "
532558 ),
533559 )
534- return CustomGCSClient (
535- epish .get_gcs_address (),
536- source_epish = epish ,
537- authorizer = authorizer ,
538- app_name = version .app_name ,
560+ return self ._into_client_pool (
561+ CustomGCSClient (
562+ epish .get_gcs_address (),
563+ source_epish = epish ,
564+ authorizer = authorizer ,
565+ app_name = version .app_name ,
566+ )
539567 )
540568
541569 def get_current_identity_id (self ) -> str :
0 commit comments