Skip to content

Commit

Permalink
Promote gare from experimental
Browse files Browse the repository at this point in the history
The `auth_requirements_error` module is moved to `globus_sdk.gare` and
docs and importts are updated.

Included in this change, `GlobusAuthRequirementsError` has been
renamed to `GARE`, as the `Error` suffix to a name typically indicates
that a class is an exception class.

Aliasing has been put in place from `experimental` to the new code
location.

As a minor, related fix `_serializable.Serializable` now uses a
`Self` type annotation, rather than a type var. This improves the doc
rendering of the `from_dict` and `to_dict` methods, as they show the
self-type rather than an unbound type variable T.
  • Loading branch information
sirosen committed Sep 16, 2024
1 parent 3d10dca commit 666ec3b
Show file tree
Hide file tree
Showing 20 changed files with 155 additions and 114 deletions.
6 changes: 6 additions & 0 deletions changelog.d/20240916_102235_sirosen_move_consents.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Changed
~~~~~~~

- Globus Auth Requirements errors are no longer ``experimental``. They have
been moved to the ``globus_sdk.gare`` module and the primary document type
has been renamed from ``GlobusAuthRequirementsError`` to ``GARE``. (:pr:`NUMBER`)
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
Auth Requirements Errors
========================

Globus Auth Requirements Error is a response format that conveys to a client any
'Globus Auth Requirements Error' is a response format that conveys to a client any
modifications to a session (i.e., "boosting") that will be required
to complete a particular request.

The ``globus_sdk.experimental.auth_requirements_error`` module provides a
number of tools to make it easier to identify and handle these errors when they occur.
The ``globus_sdk.gare`` module provides a number of tools to make it easier to
identify and handle these errors when they occur.

GlobusAuthRequirementsError
---------------------------
GARE
----

The ``GlobusAuthRequirementsError`` class provides a model for working with Globus
Auth Requirements Error responses.
The ``GARE`` class provides a model for working with Globus Auth Requirements Error
responses.

Services in the Globus ecosystem may need to communicate authorization requirements
to their consumers. For example, a service may need to instruct clients to have the user
consent to an additional scope, ``"foo"``. In such a case, ``GlobusAuthRequirementsError``
can provide serialization into the well-known Globus Auth Requirements Error format:
consent to an additional scope, ``"foo"``. In such a case, ``GARE`` can provide
serialization into the well-known Globus Auth Requirements Error format:

.. code-block:: python
from globus_sdk.experimental.auth_requirements_error import GlobusAuthRequirementsError
from globus_sdk.gare import GARE
error = GlobusAuthRequirementsError(
error_doc = GARE(
code="ConsentRequired",
authorization_parameters=GlobusAuthorizationParameters(
required_scopes=["foo"],
Expand All @@ -42,9 +42,9 @@ by specifying ``include_extra=True`` when calling ``to_dict()``.

.. code-block:: python
from globus_sdk.experimental.auth_requirements_error import GlobusAuthRequirementsError
from globus_sdk.gare import GARE
error = GlobusAuthRequirementsError(
error = GARE(
code="ConsentRequired",
authorization_parameters=GlobusAuthorizationParameters(
required_scopes=["foo"],
Expand All @@ -61,8 +61,8 @@ by specifying ``include_extra=True`` when calling ``to_dict()``.
# Render a dictionary with extra fields
error.to_dict(include_extra=True)
These fields are stored by both the ``GlobusAuthRequirementsError`` and
``GlobusAuthenticationParameters`` classes in an ``extra`` attribute.
These fields are stored by both the ``GARE`` and ``GlobusAuthenticationParameters``
classes in an ``extra`` attribute.

.. note::

Expand All @@ -75,37 +75,34 @@ These fields are stored by both the ``GlobusAuthRequirementsError`` and
Parsing Responses
-----------------

If you are writing a client to a Globus API, the ``auth_requirements_error`` subpackage
provides utilities to detect legacy Globus Auth requirements error response
formats and normalize them.
If you are writing a client to a Globus API, the ``gare`` subpackage provides utilities
to detect legacy Globus Auth requirements error response formats and normalize them.

To detect if a ``GlobusAPIError``, ``ErrorSubdocument``, or JSON response
dictionary represents an error that can be converted to a Globus Auth
Requirements Error, you can use, e.g.,:

.. code-block:: python
from globus_sdk.experimental import auth_requirements_error
from globus_sdk import gare
error_dict = {
"code": "ConsentRequired",
"message": "Missing required foo consent",
}
# The dict is not a Globus Auth Requirements Error, so `False` is returned.
auth_requirements_error.utils.is_auth_requirements_error(error_dict)
gare.is_auth_requirements_error(error_dict)
# The dict is not a Globus Auth Requirements Error and cannot be converted.
auth_requirements_error.utils.to_auth_requirements_error(error_dict) # None
gare.to_auth_requirements_error(error_dict) # None
error_dict = {
"code": "ConsentRequired",
"message": "Missing required foo consent",
"required_scopes": ["urn:globus:auth:scope:transfer.api.globus.org:all[*foo]"],
}
auth_requirements_error.utils.is_auth_requirements_error(error_dict) # True
auth_requirements_error.utils.to_auth_requirements_error(
error_dict
) # GlobusAuthRequirementsError
gare.is_auth_requirements_error(error_dict) # True
gare.to_auth_requirements_error(error_dict) # GARE
.. note::

Expand All @@ -118,22 +115,38 @@ Requirements Error, you can use, e.g.,:

.. code-block:: python
auth_requirements_error.utils.to_auth_requirements_error(
other_error
) # GlobusAuthRequirementsError
auth_requirements_error.utils.to_auth_requirements_errors(
[other_error]
) # [GlobusAuthRequirementsError, ...]
gare.to_auth_requirements_error(other_error) # GARE
gare.to_auth_requirements_errors([other_error]) # [GARE, ...]
Notes
-----

``GlobusAuthRequirementsError`` enforces types strictly when parsing a Globus
Auth Requirements Error response dictionary, and will raise a ``ValueError`` if a
``GARE`` enforces types strictly when parsing a Globus Auth Requirements Error
response dictionary, and will raise a :class:`globus_sdk.ValidationError` if a
supported field is supplied with a value of the wrong type.

``GlobusAuthRequirementsError`` does not attempt to mimic or itself enforce
any logic specific to the Globus Auth service with regard to what represents a valid
combination of fields (e.g., ``session_required_mfa`` requires either
``session_required_identities`` or ``session_required_single_domain``
in order to be properly handled).
``GARE`` does not attempt to mimic or itself enforce any logic specific to the
Globus Auth service with regard to what represents a valid combination of fields
(e.g., ``session_required_mfa`` requires either ``session_required_identities`` or
``session_required_single_domain`` in order to be properly handled).

Reference
---------

.. currentmodule:: globus_sdk.gare

.. autoclass:: GARE
:members:
:inherited-members:

.. autoclass:: GlobusAuthorizationParameters
:members:
:inherited-members:

.. autofunction:: to_auth_requirements_error

.. autofunction:: to_auth_requirements_errors

.. autofunction:: is_auth_requirements_error

.. autofunction:: has_auth_requirements_errors
1 change: 1 addition & 0 deletions docs/authorization/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Components of the Globus SDK which handle application authorization.

globus_authorizers
scopes_and_consents/index
gare
1 change: 0 additions & 1 deletion docs/experimental/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ Globus SDK Experimental Components
:caption: Contents
:maxdepth: 1

auth_requirements_errors
scope_parser
consents
globus_app
Expand Down
8 changes: 6 additions & 2 deletions src/globus_sdk/_serializable.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from __future__ import annotations

import inspect
import sys
import typing as t

T = t.TypeVar("T", bound="Serializable")
if sys.version_info >= (3, 11):
from typing import Self
else:
from typing_extensions import Self


class Serializable:
Expand All @@ -30,7 +34,7 @@ def _supported_fields(cls) -> list[str]:
]

@classmethod
def from_dict(cls: type[T], data: dict[str, t.Any]) -> T:
def from_dict(cls, data: dict[str, t.Any]) -> Self:
"""
Instantiate from a dictionary.
Expand Down
46 changes: 46 additions & 0 deletions src/globus_sdk/experimental/auth_requirements_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from __future__ import annotations

import sys
import typing as t

__all__ = (
"GlobusAuthRequirementsError",
"GlobusAuthorizationParameters",
"to_auth_requirements_error",
"to_auth_requirements_errors",
"is_auth_requirements_error",
"has_auth_requirements_errors",
)

# legacy aliases
# (when accessed, these will emit deprecation warnings)
if t.TYPE_CHECKING:
from globus_sdk.gare import GARE as GlobusAuthRequirementsError
from globus_sdk.gare import (
GlobusAuthorizationParameters,
has_auth_requirements_errors,
is_auth_requirements_error,
to_auth_requirements_error,
to_auth_requirements_errors,
)
else:

def __getattr__(name: str) -> t.Any:
import globus_sdk.gare as gare_module
from globus_sdk.exc import warn_deprecated

warn_deprecated(
"'globus_sdk.experimental.auth_requirements_error' has been renamed to "
"'globus_sdk.gare'. "
f"Importing '{name}' from `globus_sdk.experimental` is deprecated."
)

# rename GlobusAuthRequirementsError -> GARE
if name == "GlobusAuthRequirementsError":
name = "GARE"

value = getattr(gare_module, name, None)
if value is None:
raise AttributeError(f"module {__name__} has no attribute {name}")
setattr(sys.modules[__name__], name, value)
return value
4 changes: 1 addition & 3 deletions src/globus_sdk/experimental/globus_app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
from globus_sdk import AuthClient, AuthLoginClient, GlobusSDKUsageError, Scope
from globus_sdk._types import ScopeCollectionType, UUIDLike
from globus_sdk.authorizers import GlobusAuthorizer
from globus_sdk.experimental.auth_requirements_error import (
GlobusAuthorizationParameters,
)
from globus_sdk.experimental.tokenstorage import TokenStorage
from globus_sdk.gare import GlobusAuthorizationParameters
from globus_sdk.scopes import AuthScopes, scopes_to_scope_list

from ._types import TokenStorageProvider
Expand Down
4 changes: 1 addition & 3 deletions src/globus_sdk/experimental/globus_app/client_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

from globus_sdk import AuthLoginClient, ConfidentialAppAuthClient, GlobusSDKUsageError
from globus_sdk._types import ScopeCollectionType, UUIDLike
from globus_sdk.experimental.auth_requirements_error import (
GlobusAuthorizationParameters,
)
from globus_sdk.gare import GlobusAuthorizationParameters

from .app import GlobusApp
from .authorizer_factory import ClientCredentialsAuthorizerFactory
Expand Down
4 changes: 1 addition & 3 deletions src/globus_sdk/experimental/globus_app/user_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@
NativeAppAuthClient,
)
from globus_sdk._types import ScopeCollectionType, UUIDLike
from globus_sdk.experimental.auth_requirements_error import (
GlobusAuthorizationParameters,
)
from globus_sdk.experimental.login_flow_manager import (
CommandLineLoginFlowManager,
LoginFlowManager,
)
from globus_sdk.gare import GlobusAuthorizationParameters

from ._types import LoginFlowManagerProvider
from .app import GlobusApp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
GlobusSDKUsageError,
OAuthTokenResponse,
)
from globus_sdk.experimental.auth_requirements_error import (
GlobusAuthorizationParameters,
)
from globus_sdk.gare import GlobusAuthorizationParameters

from .login_flow_manager import LoginFlowManager

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,10 @@
from string import Template

from globus_sdk import AuthLoginClient, GlobusSDKUsageError, OAuthTokenResponse
from globus_sdk.experimental.auth_requirements_error import (
GlobusAuthorizationParameters,
)
from globus_sdk.experimental.login_flow_manager.login_flow_manager import (
LoginFlowManager,
)
from globus_sdk.gare import GlobusAuthorizationParameters

from ._local_server import (
DEFAULT_HTML_TEMPLATE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@
NativeAppAuthClient,
OAuthTokenResponse,
)
from globus_sdk.experimental.auth_requirements_error import (
GlobusAuthorizationParameters,
)
from globus_sdk.gare import GlobusAuthorizationParameters


class LoginFlowManager(metaclass=abc.ABCMeta):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
from ._auth_requirements_error import (
GlobusAuthorizationParameters,
GlobusAuthRequirementsError,
)
from ._auth_requirements_error import GARE, GlobusAuthorizationParameters
from ._functional_api import (
has_auth_requirements_errors,
is_auth_requirements_error,
Expand All @@ -10,7 +7,7 @@
)

__all__ = [
"GlobusAuthRequirementsError",
"GARE",
"GlobusAuthorizationParameters",
"to_auth_requirements_error",
"to_auth_requirements_errors",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ class GlobusAuthorizationParameters(Serializable):
Data class containing authorization parameters that can be passed during
an authentication flow to control how the user will authenticate.
When used with a GlobusAuthRequirementsError this represents the additional
authorization parameters needed in order to complete a request that had
insufficient authorization state.
When used with a GARE this represents the additional authorization
parameters needed in order to complete a request that had insufficient
authorization state.
:ivar session_message: A message to be displayed to the user.
:vartype session_message: str, optional
Expand Down Expand Up @@ -77,7 +77,7 @@ def __init__(
self.extra = extra or {}


class GlobusAuthRequirementsError(Serializable):
class GARE(Serializable):
"""
Represents a Globus Auth Requirements Error.
Expand Down
Loading

0 comments on commit 666ec3b

Please sign in to comment.