.. _globus_apps: .. currentmodule:: globus_sdk GlobusApps ========== .. note:: Currently ``GlobusApp`` can only be used in scripts (e.g., notebooks or automation) and applications directly responsible for a user's login flow. Web services and other hosted applications operating as an OAuth2 resource server should see :ref:`globus_authorizers` instead. :class:`GlobusApp` is a high level construct designed to simplify authentication for interactions with :ref:`globus-sdk services `. A ``GlobusApp`` uses an OAuth2 client to obtain and manage OAuth2 tokens required for API interactions. OAuth2 clients must be created external to the SDK by registering an application at the `Globus Developer's Console `_. The following section provides a comparison of the specific types of ``GlobusApps`` to aid in selecting the proper one for your use case. Types of GlobusApps ------------------- There are two flavors of ``GlobusApp`` available in the SDK: * :class:`UserApp`, for interactions in which an end user communicates with Globus services and * :class:`ClientApp`, for interactions in which an OAuth2 client, operating as a "service account", communicates with Globus services. The following table provides a comparison of these two options: .. list-table:: :widths: 50 50 :header-rows: 1 * - **UserApp** - **ClientApp** * - Appropriate for performing actions as a specific end user (e.g., the `Globus CLI `_) - Appropriate for automating actions as a service account * - Created resources (e.g., collections or flows) by default are owned by an end user - Created resources (e.g., collections or flows) by default are owned by the OAuth2 client * - Existing resource access is evaluated based on an end user's permissions - Existing resource access is evaluated based on the OAuth2 client's permissions * - OAuth2 tokens are obtained by putting an end user through a login flow (this occurs in a web browser) - OAuth2 tokens are obtained by programmatically exchanging an OAuth2 client's secret * - Should typically use a "native" OAuth2 client (`Register a thick client `_) May use a "confidential" OAuth2 client (`Register a portal or science gateway `_) - Must use a "confidential" OAuth2 client (`Register a service account `_) .. note:: Not all Globus operations support both app types. Particularly when dealing with sensitive data, services may enforce that a a user be the primary data access actor. In these cases, a ``ClientApp`` will be rejected and a ``UserApp`` must be used instead. Closing Resources via GlobusApps -------------------------------- When used as context managers, ``GlobusApp``\s automatically call their ``close()`` method on exit. Closing an app closes the token storage attached to it, unless it was created explicitly. This covers any token storage created by the app on init, but not those which are created and passed in via the config. For most cases, users are recommended to use the context manager form, and to allow ``GlobusApp`` to both create and close the token storage. For example, .. code-block:: python from globus_sdk import GlobusAppConfig, UserApp # create an app configured to create its own sqlite storage config = GlobusAppConfig(token_storage="sqlite") with UserApp("sample-app", client_id="FILL_IN_HERE", config=config) as app: ... # any clients, usage, etc. # after the context manager, any storage is implicitly closed However, when token storage instances are created by the user, they are not automatically closed, and the user is responsible for closing them. For example, in the following usage, the user must close the token storage: .. code-block:: python from globus_sdk import GlobusAppConfig, UserApp from globus_sdk.token_storage import SQLiteTokenStorage # this token storage is created by the user and will not be closed automatically sql_storage = SQLiteTokenStorage("tokens.sqlite") # create an app configured to use this storage config = GlobusAppConfig(token_storage=sql_storage) with UserApp("sample-app", client_id="FILL_IN_HERE", config=config) as app: do_stuff(app) # a second app uses the same storage, and shares the resource with UserApp("a-different-app", client_id="OTHER_ID", config=config) as app: do_stuff(app) # At this stage, the storage will still be open. # It should be explicitly closed: sql_storage.close() Reference --------- The interfaces of these classes, defined below, intentionally include many "sane defaults" (i.e., storing oauth2 access tokens in a json file). These defaults may be overridden to customize the app's behavior. For more information on what you can customize and how, see :ref:`globus_app_config`. .. autoclass:: GlobusApp() :members: :exclude-members: scope_requirements :member-order: bysource .. In the above class, "scope_requirements" is excluded because it's a ``@property``. Sphinx wants to document it as a method but that's not how it's invoked. Instead documentation is included in the class docstring as an ``ivar``. Implementations ^^^^^^^^^^^^^^^ .. autoclass:: UserApp :members: .. autoclass:: ClientApp :members: