boto3-refresh-session 1.0.4__py3-none-any.whl → 6.2.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boto3_refresh_session/__init__.py +14 -4
- boto3_refresh_session/exceptions.py +51 -0
- boto3_refresh_session/methods/__init__.py +10 -0
- boto3_refresh_session/methods/custom.py +141 -0
- boto3_refresh_session/methods/iot/__init__.py +7 -0
- boto3_refresh_session/methods/iot/core.py +40 -0
- boto3_refresh_session/methods/iot/x509.py +570 -0
- boto3_refresh_session/methods/sts.py +230 -0
- boto3_refresh_session/session.py +67 -123
- boto3_refresh_session/utils/__init__.py +10 -0
- boto3_refresh_session/utils/cache.py +94 -0
- boto3_refresh_session/utils/internal.py +437 -0
- boto3_refresh_session/utils/typing.py +133 -0
- boto3_refresh_session-6.2.5.dist-info/METADATA +564 -0
- boto3_refresh_session-6.2.5.dist-info/RECORD +18 -0
- {boto3_refresh_session-1.0.4.dist-info → boto3_refresh_session-6.2.5.dist-info}/WHEEL +1 -1
- boto3_refresh_session-6.2.5.dist-info/licenses/NOTICE +12 -0
- boto3_refresh_session-1.0.4.dist-info/METADATA +0 -102
- boto3_refresh_session-1.0.4.dist-info/RECORD +0 -6
- {boto3_refresh_session-1.0.4.dist-info → boto3_refresh_session-6.2.5.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
__all__ = []
|
|
2
2
|
|
|
3
|
-
from . import session
|
|
4
|
-
from .
|
|
3
|
+
from . import exceptions, session
|
|
4
|
+
from .exceptions import *
|
|
5
|
+
from .methods.custom import *
|
|
6
|
+
from .methods.iot import *
|
|
7
|
+
from .methods.sts import *
|
|
8
|
+
from .session import *
|
|
5
9
|
|
|
6
|
-
__all__.extend(
|
|
7
|
-
|
|
10
|
+
__all__.extend(session.__all__)
|
|
11
|
+
__all__.extend(exceptions.__all__)
|
|
12
|
+
__version__ = "6.2.5"
|
|
13
|
+
__title__ = "boto3-refresh-session"
|
|
14
|
+
__author__ = "Mike Letts"
|
|
15
|
+
__maintainer__ = "Mike Letts"
|
|
16
|
+
__license__ = "MIT"
|
|
17
|
+
__email__ = "lettsmt@gmail.com"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Custom exception and warning types for boto3-refresh-session."""
|
|
2
|
+
|
|
3
|
+
__all__ = ["BRSError", "BRSWarning"]
|
|
4
|
+
|
|
5
|
+
import warnings
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BRSError(Exception):
|
|
9
|
+
"""The base exception for boto3-refresh-session.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
message : str, optional
|
|
14
|
+
The message to raise.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, message: str | None = None):
|
|
18
|
+
self.message = "" if message is None else message
|
|
19
|
+
super().__init__(self.message)
|
|
20
|
+
|
|
21
|
+
def __str__(self) -> str:
|
|
22
|
+
return self.message
|
|
23
|
+
|
|
24
|
+
def __repr__(self) -> str:
|
|
25
|
+
return f"{self.__class__.__name__}({self.message!r})"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BRSWarning(UserWarning):
|
|
29
|
+
"""The base warning for boto3-refresh-session.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
message : str, optional
|
|
34
|
+
The message to raise.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, message: str | None = None):
|
|
38
|
+
self.message = "" if message is None else message
|
|
39
|
+
super().__init__(self.message)
|
|
40
|
+
|
|
41
|
+
def __str__(self) -> str:
|
|
42
|
+
return self.message
|
|
43
|
+
|
|
44
|
+
def __repr__(self) -> str:
|
|
45
|
+
return f"{self.__class__.__name__}({self.message!r})"
|
|
46
|
+
|
|
47
|
+
@classmethod
|
|
48
|
+
def warn(cls, message: str, *, stacklevel: int = 2):
|
|
49
|
+
"""Emits a BRSWarning with a consistent stacklevel."""
|
|
50
|
+
|
|
51
|
+
warnings.warn(cls(message), stacklevel=stacklevel)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""Custom refreshable session using a user-provided credential getter."""
|
|
2
|
+
|
|
3
|
+
__all__ = ["CustomRefreshableSession"]
|
|
4
|
+
|
|
5
|
+
from ..exceptions import BRSError, BRSWarning
|
|
6
|
+
from ..utils import (
|
|
7
|
+
BaseRefreshableSession,
|
|
8
|
+
CustomCredentialsMethod,
|
|
9
|
+
CustomCredentialsMethodArgs,
|
|
10
|
+
Identity,
|
|
11
|
+
TemporaryCredentials,
|
|
12
|
+
refreshable_session,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@refreshable_session
|
|
17
|
+
class CustomRefreshableSession(BaseRefreshableSession, registry_key="custom"):
|
|
18
|
+
"""A :class:`boto3.session.Session` object that automatically refreshes
|
|
19
|
+
temporary credentials returned by a custom credential getter provided
|
|
20
|
+
by the user. Useful for users with highly sophisticated or idiosyncratic
|
|
21
|
+
authentication flows.
|
|
22
|
+
|
|
23
|
+
Parameters
|
|
24
|
+
----------
|
|
25
|
+
custom_credentials_method: CustomCredentialsMethod
|
|
26
|
+
Required. Accepts a callable object that returns temporary AWS
|
|
27
|
+
security credentials. That object must return a dictionary containing
|
|
28
|
+
'access_key', 'secret_key', 'token', and 'expiry_time' when called.
|
|
29
|
+
custom_credentials_method_args : CustomCredentialsMethodArgs, optional
|
|
30
|
+
Optional keyword arguments for the function passed to the
|
|
31
|
+
``custom_credentials_method`` parameter.
|
|
32
|
+
defer_refresh : bool, optional
|
|
33
|
+
If ``True`` then temporary credentials are not automatically refreshed
|
|
34
|
+
until they are explicitly needed. If ``False`` then temporary
|
|
35
|
+
credentials refresh immediately upon expiration. It is highly
|
|
36
|
+
recommended that you use ``True``. Default is ``True``.
|
|
37
|
+
advisory_timeout : int, optional
|
|
38
|
+
USE THIS ARGUMENT WITH CAUTION!!!
|
|
39
|
+
|
|
40
|
+
Botocore will attempt to refresh credentials early according to
|
|
41
|
+
this value (in seconds), but will continue using the existing
|
|
42
|
+
credentials if refresh fails. Default is 15 minutes (900 seconds).
|
|
43
|
+
mandatory_timeout : int, optional
|
|
44
|
+
USE THIS ARGUMENT WITH CAUTION!!!
|
|
45
|
+
|
|
46
|
+
Botocore requires a successful refresh before continuing. If
|
|
47
|
+
refresh fails in this window (in seconds), API calls may fail.
|
|
48
|
+
Default is 10 minutes (600 seconds).
|
|
49
|
+
cache_clients : bool, optional
|
|
50
|
+
If ``True`` then clients created by this session will be cached and
|
|
51
|
+
reused for subsequent calls to :meth:`client()` with the same
|
|
52
|
+
parameter signatures. Due to the memory overhead of clients, the
|
|
53
|
+
default is ``True`` in order to protect system resources.
|
|
54
|
+
|
|
55
|
+
Other Parameters
|
|
56
|
+
----------------
|
|
57
|
+
kwargs : dict
|
|
58
|
+
Optional keyword arguments for the :class:`boto3.session.Session`
|
|
59
|
+
object.
|
|
60
|
+
|
|
61
|
+
Examples
|
|
62
|
+
--------
|
|
63
|
+
Write (or import) the callable object for obtaining temporary AWS security
|
|
64
|
+
credentials.
|
|
65
|
+
|
|
66
|
+
>>> def your_custom_credential_getter(your_param, another_param):
|
|
67
|
+
>>> ...
|
|
68
|
+
>>> return {
|
|
69
|
+
>>> 'access_key': ...,
|
|
70
|
+
>>> 'secret_key': ...,
|
|
71
|
+
>>> 'token': ...,
|
|
72
|
+
>>> 'expiry_time': ...,
|
|
73
|
+
>>> }
|
|
74
|
+
|
|
75
|
+
Pass that callable object to ``RefreshableSession``.
|
|
76
|
+
|
|
77
|
+
>>> sess = RefreshableSession(
|
|
78
|
+
>>> method='custom',
|
|
79
|
+
>>> custom_credentials_method=your_custom_credential_getter,
|
|
80
|
+
>>> custom_credentials_method_args=...,
|
|
81
|
+
>>> )
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(
|
|
85
|
+
self,
|
|
86
|
+
custom_credentials_method: CustomCredentialsMethod,
|
|
87
|
+
custom_credentials_method_args: (
|
|
88
|
+
CustomCredentialsMethodArgs | None
|
|
89
|
+
) = None,
|
|
90
|
+
**kwargs,
|
|
91
|
+
):
|
|
92
|
+
if "refresh_method" in kwargs:
|
|
93
|
+
BRSWarning.warn(
|
|
94
|
+
"'refresh_method' cannot be set manually. "
|
|
95
|
+
"Reverting to 'custom'."
|
|
96
|
+
)
|
|
97
|
+
del kwargs["refresh_method"]
|
|
98
|
+
|
|
99
|
+
# initializing BRSSession
|
|
100
|
+
super().__init__(refresh_method="custom", **kwargs)
|
|
101
|
+
|
|
102
|
+
# initializing various other attributes
|
|
103
|
+
self._custom_get_credentials: CustomCredentialsMethod = (
|
|
104
|
+
custom_credentials_method
|
|
105
|
+
)
|
|
106
|
+
self._custom_get_credentials_args: CustomCredentialsMethodArgs = (
|
|
107
|
+
custom_credentials_method_args
|
|
108
|
+
if custom_credentials_method_args is not None
|
|
109
|
+
else {}
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def _get_credentials(self) -> TemporaryCredentials:
|
|
113
|
+
credentials: TemporaryCredentials = self._custom_get_credentials(
|
|
114
|
+
**self._custom_get_credentials_args
|
|
115
|
+
)
|
|
116
|
+
required_keys = {"access_key", "secret_key", "token", "expiry_time"}
|
|
117
|
+
|
|
118
|
+
if missing := required_keys - credentials.keys():
|
|
119
|
+
raise BRSError(
|
|
120
|
+
f"The dict returned by custom_credentials_method is missing "
|
|
121
|
+
"these key-value pairs: "
|
|
122
|
+
f"{', '.join(repr(param) for param in missing)}. "
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
return credentials
|
|
126
|
+
|
|
127
|
+
def get_identity(self) -> Identity:
|
|
128
|
+
"""Returns metadata about the custom credential getter.
|
|
129
|
+
|
|
130
|
+
Returns
|
|
131
|
+
-------
|
|
132
|
+
Identity
|
|
133
|
+
Dict containing information about the custom credential getter.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
source = getattr(
|
|
137
|
+
self._custom_get_credentials,
|
|
138
|
+
"__name__",
|
|
139
|
+
repr(self._custom_get_credentials),
|
|
140
|
+
)
|
|
141
|
+
return {"method": "custom", "source": repr(source)}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""IoT refreshable session factory for selecting auth methods."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = ["IoTRefreshableSession"]
|
|
6
|
+
|
|
7
|
+
from typing import get_args
|
|
8
|
+
|
|
9
|
+
from ...exceptions import BRSError
|
|
10
|
+
from ...utils import (
|
|
11
|
+
BaseIoTRefreshableSession,
|
|
12
|
+
BaseRefreshableSession,
|
|
13
|
+
IoTAuthenticationMethod,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class IoTRefreshableSession(BaseRefreshableSession, registry_key="iot"):
|
|
18
|
+
def __new__(
|
|
19
|
+
cls,
|
|
20
|
+
authentication_method: IoTAuthenticationMethod = "x509",
|
|
21
|
+
**kwargs,
|
|
22
|
+
) -> BaseIoTRefreshableSession:
|
|
23
|
+
if authentication_method not in (
|
|
24
|
+
methods := cls.get_available_authentication_methods()
|
|
25
|
+
):
|
|
26
|
+
raise BRSError(
|
|
27
|
+
f"{authentication_method!r} is an invalid authentication "
|
|
28
|
+
"method parameter. Available authentication methods are "
|
|
29
|
+
f"{', '.join(repr(meth) for meth in methods)}."
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
return BaseIoTRefreshableSession.registry[authentication_method](
|
|
33
|
+
**kwargs
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def get_available_authentication_methods(cls) -> list[str]:
|
|
38
|
+
args = list(get_args(IoTAuthenticationMethod))
|
|
39
|
+
args.remove("__iot_sentinel__")
|
|
40
|
+
return args
|