11from __future__ import annotations
22
33import functools
4+ import inspect
45import json
56import logging
67import os
1920from globus_compute_sdk .sdk ._environments import get_web_service_url
2021from globus_compute_sdk .sdk .hardware_report import run_hardware_report
2122from globus_compute_sdk .sdk .utils import check_version
22- from globus_compute_sdk .sdk .utils .gare import GareLogin , gare_handler
23+ from globus_compute_sdk .sdk .utils .gare import gare_handler
2324from globus_compute_sdk .sdk .utils .uuid_like import UUID_LIKE_T
24- from globus_compute_sdk .sdk .web_client import (
25- FunctionRegistrationData ,
26- FunctionRegistrationMetadata ,
27- )
2825from globus_compute_sdk .serialize import (
2926 ComputeSerializer ,
3027 PureSourceTextInspect ,
3128 SerializationStrategy ,
3229)
3330from globus_compute_sdk .version import __version__ , compare_versions
34- from globus_sdk .gare import GlobusAuthorizationParameters
3531
3632from .auth .auth_client import ComputeAuthClient
3733from .auth .globus_app import get_globus_app
3834from .batch import Batch , create_user_runtime
39- from .login_manager import LoginManagerProtocol
4035
4136logger = logging .getLogger (__name__ )
4237
4338
39+ class FunctionRegistrationMetadata :
40+ def __init__ (self , python_version : str , sdk_version : str , serde_identifier : str ):
41+ self .python_version = python_version
42+ self .sdk_version = sdk_version
43+ self .serde_identifier = serde_identifier
44+
45+ def to_dict (self ):
46+ return {
47+ "python_version" : self .python_version ,
48+ "sdk_version" : self .sdk_version ,
49+ "serde_identifier" : self .serde_identifier ,
50+ }
51+
52+ def __repr__ (self ) -> str :
53+ args = ", " .join (f"{ k } ={ v !r} " for k , v in self .__dict__ .items ())
54+ return f"FunctionRegistrationMetadata({ args } )"
55+
56+
57+ class FunctionRegistrationData :
58+ def __init__ (
59+ self ,
60+ * ,
61+ function : t .Optional [t .Callable ] = None ,
62+ function_name : t .Optional [str ] = None ,
63+ function_code : t .Optional [str ] = None ,
64+ description : t .Optional [str ] = None ,
65+ metadata : t .Optional [FunctionRegistrationMetadata ] = None ,
66+ public : bool = False ,
67+ group : t .Optional [UUID_LIKE_T ] = None ,
68+ serializer : t .Optional [ComputeSerializer ] = None ,
69+ ha_endpoint_id : t .Optional [UUID_LIKE_T ] = None ,
70+ ):
71+ if function is not None :
72+ if any ((function_name , function_code , metadata )):
73+ raise ValueError (
74+ "`function` specified; cannot also specify `function_code`,"
75+ " `function_name`, or `metadata`"
76+ )
77+
78+ serializer = serializer if serializer else ComputeSerializer ()
79+ function_name = function .__name__
80+ function_code = serializer .pack_buffers ([serializer .serialize (function )])
81+ if description is None :
82+ description = inspect .getdoc (function )
83+ metadata = FunctionRegistrationMetadata (
84+ python_version = platform .python_version (),
85+ sdk_version = __version__ ,
86+ serde_identifier = serializer .code_serializer .identifier .strip (),
87+ )
88+
89+ elif None in (function_name , function_code , metadata ):
90+ raise ValueError (
91+ "Either `function` must be provided, or all three of `function_name`,"
92+ " `function_code`, and `metadata`."
93+ )
94+
95+ if ha_endpoint_id and (public or group ):
96+ raise ValueError (
97+ "`ha_endpoint_id` is mutually exclusive with `public` and `group`"
98+ )
99+
100+ self .function_name = function_name
101+ self .function_code = function_code
102+ self .description = description
103+ self .metadata = metadata
104+ self .public = public
105+ self .group = group
106+ self .ha_endpoint_id = ha_endpoint_id
107+
108+ def to_dict (self ):
109+ data = {
110+ "function_name" : self .function_name ,
111+ "function_code" : self .function_code ,
112+ "meta" : self .metadata .to_dict () if self .metadata else None ,
113+ }
114+ if self .description :
115+ data ["description" ] = self .description
116+ if self .public :
117+ data ["public" ] = True
118+ if self .group :
119+ data ["group" ] = self .group
120+ if self .ha_endpoint_id :
121+ data ["ha_endpoint_id" ] = self .ha_endpoint_id
122+ return data
123+
124+ def __repr__ (self ) -> str :
125+ args = ", " .join (f"{ k } ={ v !r} " for k , v in self .__dict__ .items ())
126+ return f"FunctionRegistrationData({ args } )"
127+
128+
44129def _client_gares_handler (f : t .Callable ):
45130 @functools .wraps (f )
46131 def _wrapper (self : Client , * args , ** kwargs ):
47- _login : GareLogin | None = None
48- if self . app :
49- _login = self . app . login
50- elif self . _login_manager :
132+ if not self . app :
133+ # Perhaps an authorizer is in use; there is no way to relogin so if an error
134+ # happens, then just let the naked exception raise
135+ return f ( self , * args , ** kwargs )
51136
52- def _login (auth_params : GlobusAuthorizationParameters ):
53- self .login_manager .run_login_flow (auth_params = auth_params )
54-
55- if _login :
56- return gare_handler (_login , f , self , * args , ** kwargs )
57-
58- # Perhaps an authorizer is in use; there is no way to relogin so if an error
59- # happens, then just let the naked exception raise
60- return f (self , * args , ** kwargs )
137+ return gare_handler (self .app .login , f , self , * args , ** kwargs )
61138
62139 return _wrapper
63140
@@ -96,7 +173,6 @@ def __init__(
96173 * ,
97174 code_serialization_strategy : SerializationStrategy | None = None ,
98175 data_serialization_strategy : SerializationStrategy | None = None ,
99- login_manager : LoginManagerProtocol | None = None ,
100176 app : globus_sdk .GlobusApp | None = None ,
101177 authorizer : globus_sdk .authorizers .GlobusAuthorizer | None = None ,
102178 ** kwargs ,
@@ -125,21 +201,14 @@ def __init__(
125201 Strategy to use when serializing function arguments. If None,
126202 globus_compute_sdk.serialize.DEFAULT_STRATEGY_DATA will be used.
127203
128- login_manager: LoginManagerProtocol [Deprecated]
129- Allows login logic to be overridden for specific use cases. If None,
130- a ``GlobusApp`` will be used. Mutually exclusive with ``app`` and
131- ``authorizer``.
132-
133- This argument is deprecated; use ``app`` or ``authorizer`` instead.
134-
135204 app: GlobusApp
136205 A ``GlobusApp`` that will handle authorization and storing and validating
137206 tokens. If None, a standard ``GlobusApp`` will be used. Mutually exclusive
138- with ``authorizer`` and ``login_manager`` .
207+ with ``authorizer``.
139208
140209 authorizer: GlobusAuthorizer
141210 A ``GlobusAuthorizer`` that will generate authorization headers. Mutually
142- exclusive with ``app`` and ``login_manager`` .
211+ exclusive with ``app``.
143212 """
144213 for arg_name in kwargs :
145214 msg = (
@@ -156,25 +225,16 @@ def __init__(
156225
157226 self .app : globus_sdk .GlobusApp | None = None
158227 self .authorizer : globus_sdk .authorizers .GlobusAuthorizer | None = None
159- self ._login_manager : LoginManagerProtocol | None = None
160228 self ._auth_client : globus_sdk .AuthClient | None = None
161229 self ._request_lock = threading .Lock ()
162230
163- if sum (bool (x ) for x in (app , authorizer , login_manager )) > 1 :
164- raise ValueError (
165- "'app', 'authorizer' and 'login_manager' are mutually exclusive."
166- )
231+ if app and authorizer :
232+ raise ValueError ("'app' and 'authorizer' are mutually exclusive." )
167233 elif authorizer :
168234 self .authorizer = authorizer
169235 self ._compute_web_client = _ComputeWebClient (
170236 base_url = self .web_service_address , authorizer = self .authorizer
171237 )
172- elif login_manager :
173- self .login_manager = login_manager
174- self ._compute_web_client = _ComputeWebClient (
175- base_url = self .web_service_address ,
176- authorizer = self .login_manager .get_web_client ().authorizer ,
177- )
178238 else :
179239 self .app = app if app else get_globus_app (environment = environment )
180240 self ._compute_web_client = _ComputeWebClient (
@@ -191,20 +251,6 @@ def __init__(
191251 if do_version_check :
192252 self .version_check ()
193253
194- @property
195- def login_manager (self ):
196- warnings .warn (
197- "The 'Client.login_manager' attribute is deprecated;"
198- " use 'Client.app' or 'Client.authorizer' instead." ,
199- UserWarning ,
200- stacklevel = 2 ,
201- )
202- return self ._login_manager
203-
204- @login_manager .setter
205- def login_manager (self , val : LoginManagerProtocol ):
206- self ._login_manager = val
207-
208254 @property
209255 def auth_client (self ):
210256 warnings .warn (
@@ -214,8 +260,6 @@ def auth_client(self):
214260 )
215261 if self ._auth_client :
216262 return self ._auth_client
217- elif self .login_manager :
218- self ._auth_client = self .login_manager .get_auth_client ()
219263 else :
220264 self ._auth_client = ComputeAuthClient (app = self .app )
221265 return self ._auth_client
@@ -250,9 +294,8 @@ def logout(self):
250294 )
251295 return
252296
253- auth_obj = self .app or self .login_manager
254- if auth_obj :
255- auth_obj .logout ()
297+ if self .app :
298+ self .app .logout ()
256299
257300 def _log_version_mismatch (self , worker_details : dict | None ) -> None :
258301 """
0 commit comments