TokenStorage

The TokenStorage component provides a way of storing and loading the tokens received from authentication and token refreshes.

Usage

TokenStorage is available under the name globus_sdk.tokenstorage.

Storage adapters are the main objects of this subpackage. Primarily, usage should revolve around creating a storage adapter, potentially loading data from it, and using it as the on_refresh handler for an authorizer.

For example:

import os
import globus_sdk
from globus_sdk.tokenstorage import SimpleJSONFileAdapter

my_file_adapter = SimpleJSONFileAdapter(os.path.expanduser("~/mytokens.json"))

if not my_file_adapter.file_exists():
    # ... do a login low, getting back initial tokens
    # elided for simplicity here
    token_response = ...
    # now store the tokens, and pull out the tokens for the
    # resource server we want
    my_file_adapter.store(token_response)
    by_rs = token_response.by_resource_server
    tokens = by_rs["transfer.api.globus.org"]
else:
    # otherwise, we already did this whole song-and-dance, so just
    # load the tokens from that file
    tokens = my_file_adapter.get_token_data("transfer.api.globus.org")


# RereshTokenAuthorizer and ClientCredentialsAuthorizer both use
# `on_refresh` callbacks
# this feature is therefore only relevant for those auth types
#
# auth_client is the internal auth client used for refreshes,
# and which was used in the login flow
# note that this is all normal authorizer usage wherein
# my_file_adapter is providing the on_refresh callback
auth_client = ...
authorizer = globus_sdk.RefreshTokenAuthorizer(
    tokens["refresh_token"],
    auth_client,
    access_token=tokens["access_token"],
    expires_at=tokens["access_token_expires"],
    on_refresh=my_file_adapter.on_refresh,
)

# or, for client credentials
authorizer = globus_sdk.ClientCredentialsAuthorizer(
    auth_client,
    ["urn:globus:auth:transfer.api.globus.org:all"],
    access_token=tokens["access_token"],
    expires_at=tokens["access_token_expires"],
    on_refresh=my_file_adapter.on_refresh,
)

# and then use the authorizer on a client!
tc = globus_sdk.TransferClient(authorizer=authorizer)

Adapter Types

globus_sdk.tokenstorage provides base classes for building your own storage adapters, and two complete adapters.

The SimpleJSONFileAdapter is good for the “simplest possible” storage, using a JSON file to store token data.

The SQLiteAdapter is the next step up in complexity, for applications like the globus-cli which need to store various tokens and additional configuration. In addition to basic token storage, the SQLiteAdapter provides for namespacing of the token data, and for additional configuration storage.

Reference

class globus_sdk.tokenstorage.StorageAdapter[source]

Bases: object

abstract get_token_data(resource_server: str) Optional[Dict][source]

Lookup token data for a resource server

Either returns a dict with the access token, refresh token (optional), and expiration time, or returns None, indicating that there was no data for that resource server.

on_refresh(token_response: globus_sdk.services.auth.response.OAuthTokenResponse) None[source]

By default, the on_refresh handler for a token storage adapter simply stores the token response.

class globus_sdk.tokenstorage.FileAdapter[source]

Bases: globus_sdk.tokenstorage.base.StorageAdapter

File adapters are for single-user cases, where we can assume that there’s a simple file-per-user and users are only ever attempting to read their own files.

file_exists() bool[source]

Check if the file used by this file storage adapter exists.

user_only_umask() Iterator[None][source]

a context manager to deny rwx to Group and World, x to User

this does not create a file, but ensures that if a file is created while in the context manager, its permissions will be correct on unix systems

class globus_sdk.tokenstorage.SimpleJSONFileAdapter(filename: str)[source]

Bases: globus_sdk.tokenstorage.base.FileAdapter

Parameters

filename – the name of the file to write to and read from

A storage adapter for storing tokens in JSON files.

store(token_response: globus_sdk.services.auth.response.OAuthTokenResponse) None[source]

By default, self.on_refresh is just an alias for this function.

Given a token response, extract all the token data and write it to self.filename as JSON data. Additionally will write the version of globus_sdk.tokenstorage which was in use.

Under the assumption that this may be running on a system with multiple local users, this sets the umask such that only the owner of the resulting file can read or write it.

get_by_resource_server() Dict[source]

Read only the by_resource_server formatted data from the file, discarding any other keys.

This returns a dict in the same format as OAuthTokenResponse.by_resource_server

get_token_data(resource_server: str) Optional[Dict][source]

Lookup token data for a resource server

Either returns a dict with the access token, refresh token (optional), and expiration time, or returns None, indicating that there was no data for that resource server.

class globus_sdk.tokenstorage.SQLiteAdapter(dbname: str, *, namespace: str = 'DEFAULT')[source]

Bases: globus_sdk.tokenstorage.base.FileAdapter

Parameters
  • dbname – The name of the DB file to write to and read from. If the string “:memory:” is used, an in-memory database will be used instead.

  • namespace – A “namespace” to use within the database. All operations will be performed indexed under this string, so that multiple distinct sets of tokens may be stored in the database. You might use usernames as the namespace to implement a multi-user system, or profile names to allow multiple Globus accounts to be used by a single user.

A storage adapter for storing tokens in sqlite databases.

SQLite adapters are for more complex cases, where there may be multiple users or “profiles” in play, and additionally a dynamic set of resource servers which need to be stored in an extensible way.

The namespace is a user-supplied way of partitioning data, and any token responses passed to the storage adapter are broken apart and stored indexed by resource_server. If you have a more complex use-case in which this scheme will be insufficient, you should encode that in your choice of namespace values.

store_config(config_name: str, config_dict: Mapping) None[source]
Parameters
  • config_name – A string name for the configuration value

  • config_dict – A dict of config which will be stored serialized as JSON

Store a config dict under the current namespace in the config table. Allows arbitrary configuration data to be namespaced under the namespace, so that application config may be associated with the stored tokens.

Uses sqlite “REPLACE” to perform the operation.

read_config(config_name: str) Optional[Dict][source]
Parameters

config_name – A string name for the configuration value

Load a config dict under the current namespace in the config table. If no value is found, returns None

remove_config(config_name: str) bool[source]
Parameters

config_name – A string name for the configuration value

Delete a previously stored configuration value.

Returns True if data was deleted, False if none was found to delete.

store(token_response: globus_sdk.services.auth.response.OAuthTokenResponse) None[source]
Parameters

token_response – a globus_sdk.OAuthTokenResponse object containing token data to store

By default, self.on_refresh is just an alias for this function.

Given a token response, extract the token data for the resource servers and write it to self.dbname, stored under the adapter’s namespace

get_token_data(resource_server: str) Optional[Dict[str, Any]][source]

Load the token data JSON for a specific resource server.

In the event that the server cannot be found in the DB, return None.

Parameters

resource_server – The name of a resource server to lookup in the DB, as one would use as a key in OAuthTokenResponse.by_resource_server

get_by_resource_server() Dict[str, Any][source]

Load the token data JSON and return the resulting dict objects, indexed by resource server.

This should look identical to an OAuthTokenResponse.by_resource_server in format and content. (But it is not attached to a token response object.)

remove_tokens_for_resource_server(resource_server: str) bool[source]

Given a resource server to target, delete tokens for that resource server from the database (limited to the current namespace). You can use this as part of a logout command implementation, loading token data as a dict, and then deleting the data for each resource server.

Returns True if token data was deleted, False if none was found to delete.

Parameters

resource_server – The name of the resource server to remove from the DB, as one would use as a key in OAuthTokenResponse.by_resource_server