[docs]classScopeBuilder:""" Utility class for creating scope strings for a specified resource server. :param resource_server: The identifier, usually a domain name or a UUID, for the resource server to return scopes for. :param known_scopes: A list of scope names to pre-populate on this instance. This will set attributes on the instance using the URN scope format. :param known_url_scopes: A list of scope names to pre-populate on this instance. This will set attributes on the instance using the URL scope format. """_classattr_scope_names:list[str]=[]def__init__(self,resource_server:str,*,known_scopes:ScopeBuilderScopes=None,known_url_scopes:ScopeBuilderScopes=None,)->None:self.resource_server=resource_serverself._registered_scope_names:list[str]=[]self._register_scopes(known_scopes,self.urn_scope_string)self._register_scopes(known_url_scopes,self.url_scope_string)def_register_scopes(self,scopes:ScopeBuilderScopes,transform_func:t.Callable[[str],str])->None:scopes_dict=self._scopes_input_to_dict(scopes)forscope_name,scope_valinscopes_dict.items():self._registered_scope_names.append(scope_name)setattr(self,scope_name,transform_func(scope_val))def_scopes_input_to_dict(self,items:ScopeBuilderScopes)->dict[str,str]:""" ScopeBuilders accepts many collection-style types of scopes. This function normalizes all of those types into a standard {scope_name: scope_val} dict Translation Map: None => {} "my-str" => {"my-str": "my-str"} ["my-list"] => {"my-list": "my-list"} ("my-tuple-key", "my-tuple-val") => {"my-tuple-key": "my-tuple-val"} """ifitemsisNone:return{}elifisinstance(items,str):return{items:items}elifisinstance(items,tuple):return{items[0]:items[1]}else:items_dict={}foriteminitems:ifisinstance(item,str):items_dict[item]=itemelse:items_dict[item[0]]=item[1]returnitems_dict@propertydefscope_names(self)->list[str]:returnself._classattr_scope_names+self._registered_scope_names# custom __getattr__ instructs `mypy` that unknown attributes of a ScopeBuilder are# of type `str`, allowing for dynamic attribute names# to test, try creating a module with## from globus_sdk.scopes import TransferScopes# x = TransferScopes.all## without this method, the assignment to `x` would fail type checking# because `all` is unknown to mypy## note that the implementation just raises AttributeError; this is okay because# __getattr__ is only called as a last resort, when __getattribute__ has failed# normal attribute access will not be disrupteddef__getattr__(self,name:str)->str:raiseAttributeError(f"Unrecognized Attribute '{name}'")
[docs]defurn_scope_string(self,scope_name:str)->str:""" Return a complete string representing the scope with a given name for this client, in the Globus Auth URN format. Note that this module already provides many such scope strings for use with Globus services. **Examples** >>> sb = ScopeBuilder("transfer.api.globus.org") >>> sb.urn_scope_string("transfer.api.globus.org", "all") "urn:globus:auth:scope:transfer.api.globus.org:all" :param scope_name: The short name for the scope involved. """returnf"urn:globus:auth:scope:{self.resource_server}:{scope_name}"
[docs]defurl_scope_string(self,scope_name:str)->str:""" Return a complete string representing the scope with a given name for this client, in URL format. **Examples** >>> sb = ScopeBuilder("actions.globus.org") >>> sb.url_scope_string("actions.globus.org", "hello_world") "https://auth.globus.org/scopes/actions.globus.org/hello_world" :param scope_name: The short name for the scope involved. """returnf"https://auth.globus.org/scopes/{self.resource_server}/{scope_name}"