1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
.. _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 <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 <https://app.globus.org/settings/developers>`_.
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 <https://docs.globus.org/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
<https://app.globus.org/settings/developers/registration/public_installed_client>`_)
May use a "confidential" OAuth2 client (`Register a portal or science gateway
<https://app.globus.org/settings/developers/registration/confidential_client>`_)
- Must use a "confidential" OAuth2 client
(`Register a service account
<https://app.globus.org/settings/developers/registration/client_identity>`_)
.. 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:
|