boto3-refresh-session 2.0.7__py3-none-any.whl → 2.0.9__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 +1 -1
- boto3_refresh_session/methods/custom.py +27 -13
- boto3_refresh_session/methods/ecs.py +15 -7
- boto3_refresh_session/methods/iot/certificate.typed +2 -1
- boto3_refresh_session/methods/iot/cognito.typed +2 -1
- boto3_refresh_session/methods/sts.py +13 -7
- boto3_refresh_session/utils.py +82 -2
- {boto3_refresh_session-2.0.7.dist-info → boto3_refresh_session-2.0.9.dist-info}/METADATA +1 -1
- boto3_refresh_session-2.0.9.dist-info/RECORD +17 -0
- boto3_refresh_session-2.0.7.dist-info/RECORD +0 -17
- {boto3_refresh_session-2.0.7.dist-info → boto3_refresh_session-2.0.9.dist-info}/LICENSE +0 -0
- {boto3_refresh_session-2.0.7.dist-info → boto3_refresh_session-2.0.9.dist-info}/NOTICE +0 -0
- {boto3_refresh_session-2.0.7.dist-info → boto3_refresh_session-2.0.9.dist-info}/WHEEL +0 -0
@@ -4,7 +4,7 @@ from .methods.sts import STSRefreshableSession
|
|
4
4
|
from .session import RefreshableSession
|
5
5
|
|
6
6
|
__all__ = ["RefreshableSession"]
|
7
|
-
__version__ = "2.0.
|
7
|
+
__version__ = "2.0.9"
|
8
8
|
__title__ = "boto3-refresh-session"
|
9
9
|
__author__ = "Mike Letts"
|
10
10
|
__maintainer__ = "Mike Letts"
|
@@ -4,11 +4,17 @@ __all__ = ["CustomRefreshableSession"]
|
|
4
4
|
|
5
5
|
from typing import Any, Callable
|
6
6
|
|
7
|
-
from ..exceptions import BRSError
|
7
|
+
from ..exceptions import BRSError, BRSWarning
|
8
8
|
from ..session import BaseRefreshableSession
|
9
|
-
from ..utils import
|
9
|
+
from ..utils import (
|
10
|
+
CustomCredentialsMethod,
|
11
|
+
CustomCredentialsMethodArgs,
|
12
|
+
TemporaryCredentials,
|
13
|
+
refreshable_session,
|
14
|
+
)
|
10
15
|
|
11
16
|
|
17
|
+
@refreshable_session
|
12
18
|
class CustomRefreshableSession(BaseRefreshableSession, registry_key="custom"):
|
13
19
|
"""A :class:`boto3.session.Session` object that automatically refreshes
|
14
20
|
temporary credentials returned by a custom credential getter provided
|
@@ -17,11 +23,11 @@ class CustomRefreshableSession(BaseRefreshableSession, registry_key="custom"):
|
|
17
23
|
|
18
24
|
Parameters
|
19
25
|
----------
|
20
|
-
custom_credentials_method:
|
26
|
+
custom_credentials_method: CustomCredentialsMethod
|
21
27
|
Required. Accepts a callable object that returns temporary AWS
|
22
28
|
security credentials. That object must return a dictionary containing
|
23
29
|
'access_key', 'secret_key', 'token', and 'expiry_time' when called.
|
24
|
-
custom_credentials_method_args :
|
30
|
+
custom_credentials_method_args : CustomCredentialsMethodArgs, optional
|
25
31
|
Optional keyword arguments for the function passed to the
|
26
32
|
``custom_credentials_method`` parameter.
|
27
33
|
defer_refresh : bool, optional
|
@@ -61,21 +67,29 @@ class CustomRefreshableSession(BaseRefreshableSession, registry_key="custom"):
|
|
61
67
|
|
62
68
|
def __init__(
|
63
69
|
self,
|
64
|
-
custom_credentials_method:
|
65
|
-
custom_credentials_method_args:
|
66
|
-
|
70
|
+
custom_credentials_method: CustomCredentialsMethod,
|
71
|
+
custom_credentials_method_args: (
|
72
|
+
CustomCredentialsMethodArgs | None
|
73
|
+
) = None,
|
67
74
|
**kwargs,
|
68
75
|
):
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
if "refresh_method" in kwargs:
|
77
|
+
BRSWarning(
|
78
|
+
"'refresh_method' cannot be set manually. "
|
79
|
+
"Reverting to 'custom'."
|
80
|
+
)
|
81
|
+
del kwargs["refresh_method"]
|
82
|
+
|
83
|
+
# initializing BRSSession
|
84
|
+
super().__init__(refresh_method="custom", **kwargs)
|
85
|
+
self._custom_get_credentials: CustomCredentialsMethod = (
|
86
|
+
custom_credentials_method
|
87
|
+
)
|
88
|
+
self._custom_get_credentials_args: CustomCredentialsMethodArgs = (
|
74
89
|
custom_credentials_method_args
|
75
90
|
if custom_credentials_method_args is not None
|
76
91
|
else {}
|
77
92
|
)
|
78
|
-
self.__post_init__()
|
79
93
|
|
80
94
|
def _get_credentials(self) -> TemporaryCredentials:
|
81
95
|
credentials: TemporaryCredentials = self._custom_get_credentials(
|
@@ -6,9 +6,9 @@ import os
|
|
6
6
|
|
7
7
|
import requests
|
8
8
|
|
9
|
-
from ..exceptions import BRSError
|
9
|
+
from ..exceptions import BRSError, BRSWarning
|
10
10
|
from ..session import BaseRefreshableSession
|
11
|
-
from ..utils import
|
11
|
+
from ..utils import TemporaryCredentials, refreshable_session
|
12
12
|
|
13
13
|
_ECS_CREDENTIALS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
14
14
|
_ECS_CREDENTIALS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
@@ -16,6 +16,7 @@ _ECS_AUTHORIZATION_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
|
|
16
16
|
_DEFAULT_ENDPOINT_BASE = "http://169.254.170.2"
|
17
17
|
|
18
18
|
|
19
|
+
@refreshable_session
|
19
20
|
class ECSRefreshableSession(BaseRefreshableSession, registry_key="ecs"):
|
20
21
|
"""A boto3 session that automatically refreshes temporary AWS credentials
|
21
22
|
from the ECS container credentials metadata endpoint.
|
@@ -34,14 +35,21 @@ class ECSRefreshableSession(BaseRefreshableSession, registry_key="ecs"):
|
|
34
35
|
Optional keyword arguments passed to :class:`boto3.session.Session`.
|
35
36
|
"""
|
36
37
|
|
37
|
-
def __init__(self,
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
def __init__(self, **kwargs):
|
39
|
+
if "refresh_method" in kwargs:
|
40
|
+
BRSWarning(
|
41
|
+
"'refresh_method' cannot be set manually. "
|
42
|
+
"Reverting to 'ecs-container-metadata'."
|
43
|
+
)
|
44
|
+
del kwargs["refresh_method"]
|
45
|
+
|
46
|
+
# initializing BRSSession
|
47
|
+
super().__init__(refresh_method="ecs-container-metadata", **kwargs)
|
48
|
+
|
49
|
+
# initializing various other attributes
|
41
50
|
self._endpoint = self._resolve_endpoint()
|
42
51
|
self._headers = self._build_headers()
|
43
52
|
self._http = self._init_http_session()
|
44
|
-
self.__post_init__()
|
45
53
|
|
46
54
|
def _resolve_endpoint(self) -> str:
|
47
55
|
uri = os.environ.get(_ECS_CREDENTIALS_FULL_URI) or os.environ.get(
|
@@ -4,10 +4,11 @@ from pathlib import Path
|
|
4
4
|
from typing import Any
|
5
5
|
|
6
6
|
from ...exceptions import BRSError
|
7
|
-
from ...utils import PKCS11, TemporaryCredentials
|
7
|
+
from ...utils import PKCS11, TemporaryCredentials, refreshable_session
|
8
8
|
from .core import BaseIoTRefreshableSession
|
9
9
|
|
10
10
|
|
11
|
+
@refreshable_session
|
11
12
|
class IoTCertificateRefreshableSession(
|
12
13
|
BaseIoTRefreshableSession, registry_key="certificate"
|
13
14
|
):
|
@@ -2,10 +2,11 @@ __all__ = ["IoTCognitoRefreshableSession"]
|
|
2
2
|
|
3
3
|
from typing import Any
|
4
4
|
|
5
|
-
from ...utils import TemporaryCredentials
|
5
|
+
from ...utils import TemporaryCredentials, refreshable_session
|
6
6
|
from .core import BaseIoTRefreshableSession
|
7
7
|
|
8
8
|
|
9
|
+
@refreshable_session
|
9
10
|
class IoTCognitoRefreshableSession(
|
10
11
|
BaseIoTRefreshableSession, registry_key="cognito"
|
11
12
|
):
|
@@ -8,12 +8,13 @@ from ..exceptions import BRSWarning
|
|
8
8
|
from ..session import BaseRefreshableSession
|
9
9
|
from ..utils import (
|
10
10
|
AssumeRoleParams,
|
11
|
-
RefreshMethod,
|
12
11
|
STSClientParams,
|
13
12
|
TemporaryCredentials,
|
13
|
+
refreshable_session,
|
14
14
|
)
|
15
15
|
|
16
16
|
|
17
|
+
@refreshable_session
|
17
18
|
class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
18
19
|
"""A :class:`boto3.session.Session` object that automatically refreshes
|
19
20
|
temporary AWS credentials using an IAM role that is assumed via STS.
|
@@ -43,13 +44,20 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
43
44
|
def __init__(
|
44
45
|
self,
|
45
46
|
assume_role_kwargs: AssumeRoleParams,
|
46
|
-
defer_refresh: bool | None = None,
|
47
47
|
sts_client_kwargs: STSClientParams | None = None,
|
48
48
|
**kwargs,
|
49
49
|
):
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
if "refresh_method" in kwargs:
|
51
|
+
BRSWarning(
|
52
|
+
"'refresh_method' cannot be set manually. "
|
53
|
+
"Reverting to 'sts-assume-role'."
|
54
|
+
)
|
55
|
+
del kwargs["refresh_method"]
|
56
|
+
|
57
|
+
# initializing BRSSession
|
58
|
+
super().__init__(refresh_method="sts-assume-role", **kwargs)
|
59
|
+
|
60
|
+
# initializing various other attributes
|
53
61
|
self.assume_role_kwargs = assume_role_kwargs
|
54
62
|
|
55
63
|
if sts_client_kwargs is not None:
|
@@ -66,8 +74,6 @@ class STSRefreshableSession(BaseRefreshableSession, registry_key="sts"):
|
|
66
74
|
else:
|
67
75
|
self._sts_client = self.client(service_name="sts")
|
68
76
|
|
69
|
-
self.__post_init__()
|
70
|
-
|
71
77
|
def _get_credentials(self) -> TemporaryCredentials:
|
72
78
|
temporary_credentials = self._sts_client.assume_role(
|
73
79
|
**self.assume_role_kwargs
|
boto3_refresh_session/utils.py
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
1
3
|
from abc import ABC, abstractmethod
|
2
4
|
from datetime import datetime
|
5
|
+
from functools import wraps
|
3
6
|
from typing import (
|
4
7
|
Any,
|
5
8
|
Callable,
|
@@ -7,8 +10,12 @@ from typing import (
|
|
7
10
|
Generic,
|
8
11
|
List,
|
9
12
|
Literal,
|
13
|
+
Mapping,
|
14
|
+
Protocol,
|
15
|
+
TypeAlias,
|
10
16
|
TypedDict,
|
11
17
|
TypeVar,
|
18
|
+
cast,
|
12
19
|
)
|
13
20
|
|
14
21
|
from boto3.session import Session
|
@@ -45,6 +52,52 @@ RefreshMethod = Literal[
|
|
45
52
|
#: Type alias for all currently registered credential refresh methods.
|
46
53
|
RegistryKey = TypeVar("RegistryKey", bound=str)
|
47
54
|
|
55
|
+
#: Type alias for a generic refreshable session type.
|
56
|
+
BRSSessionType = TypeVar("BRSSessionType", bound="BRSSession")
|
57
|
+
|
58
|
+
|
59
|
+
def refreshable_session(
|
60
|
+
cls: type[BRSSessionType],
|
61
|
+
) -> type[BRSSessionType]:
|
62
|
+
"""Wraps cls.__init__ so self.__post_init__ runs after init (if present).
|
63
|
+
|
64
|
+
Returns
|
65
|
+
-------
|
66
|
+
BRSSessionType
|
67
|
+
The decorated class.
|
68
|
+
"""
|
69
|
+
|
70
|
+
init = getattr(cls, "__init__", None)
|
71
|
+
|
72
|
+
# synthesize __init__ if undefined in the class
|
73
|
+
if init in (None, object.__init__):
|
74
|
+
|
75
|
+
def __init__(self, *args, **kwargs):
|
76
|
+
super(cls, self).__init__(*args, **kwargs)
|
77
|
+
post = getattr(self, "__post_init__", None)
|
78
|
+
if callable(post) and not getattr(self, "_post_inited", False):
|
79
|
+
post()
|
80
|
+
setattr(self, "_post_inited", True)
|
81
|
+
|
82
|
+
cls.__init__ = __init__ # type: ignore[assignment]
|
83
|
+
return cls
|
84
|
+
|
85
|
+
# avoids double wrapping
|
86
|
+
if getattr(init, "__post_init_wrapped__", False):
|
87
|
+
return cls
|
88
|
+
|
89
|
+
@wraps(init)
|
90
|
+
def wrapper(self, *args, **kwargs):
|
91
|
+
init(self, *args, **kwargs)
|
92
|
+
post = getattr(self, "__post_init__", None)
|
93
|
+
if callable(post) and not getattr(self, "_post_inited", False):
|
94
|
+
post()
|
95
|
+
setattr(self, "_post_inited", True)
|
96
|
+
|
97
|
+
wrapper.__post_init_wrapped__ = True # type: ignore[attr-defined]
|
98
|
+
cls.__init__ = cast(Callable[..., None], wrapper)
|
99
|
+
return cls
|
100
|
+
|
48
101
|
|
49
102
|
class Registry(Generic[RegistryKey]):
|
50
103
|
"""Gives any hierarchy a class-level registry."""
|
@@ -76,6 +129,17 @@ class TemporaryCredentials(TypedDict):
|
|
76
129
|
expiry_time: datetime | str
|
77
130
|
|
78
131
|
|
132
|
+
class _CustomCredentialsMethod(Protocol):
|
133
|
+
def __call__(self, **kwargs: Any) -> TemporaryCredentials: ...
|
134
|
+
|
135
|
+
|
136
|
+
#: Type alias for custom credential retrieval methods.
|
137
|
+
CustomCredentialsMethod: TypeAlias = _CustomCredentialsMethod
|
138
|
+
|
139
|
+
#: Type alias for custom credential method arguments.
|
140
|
+
CustomCredentialsMethodArgs: TypeAlias = Mapping[str, Any]
|
141
|
+
|
142
|
+
|
79
143
|
class RefreshableTemporaryCredentials(TypedDict):
|
80
144
|
"""Refreshable IAM credentials.
|
81
145
|
|
@@ -107,12 +171,28 @@ class CredentialProvider(ABC):
|
|
107
171
|
class BRSSession(Session):
|
108
172
|
"""Wrapper for boto3.session.Session.
|
109
173
|
|
174
|
+
Parameters
|
175
|
+
----------
|
176
|
+
refresh_method : RefreshMethod
|
177
|
+
The method to use for refreshing temporary credentials.
|
178
|
+
defer_refresh : bool, default=True
|
179
|
+
If True, the initial credential refresh is deferred until the
|
180
|
+
credentials are first accessed. If False, the initial refresh
|
181
|
+
|
110
182
|
Other Parameters
|
111
183
|
----------------
|
112
184
|
kwargs : Any
|
113
|
-
Optional keyword arguments for initializing boto3.session.Session.
|
185
|
+
Optional keyword arguments for initializing boto3.session.Session.
|
186
|
+
"""
|
114
187
|
|
115
|
-
def __init__(
|
188
|
+
def __init__(
|
189
|
+
self,
|
190
|
+
refresh_method: RefreshMethod,
|
191
|
+
defer_refresh: bool | None = None,
|
192
|
+
**kwargs,
|
193
|
+
):
|
194
|
+
self.refresh_method: RefreshMethod = refresh_method
|
195
|
+
self.defer_refresh: bool = defer_refresh is not False
|
116
196
|
super().__init__(**kwargs)
|
117
197
|
|
118
198
|
def __post_init__(self):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: boto3-refresh-session
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.9
|
4
4
|
Summary: A simple Python package for refreshing the temporary security credentials in a boto3.session.Session object automatically.
|
5
5
|
License: MIT
|
6
6
|
Keywords: boto3,botocore,aws,sts,ecs,credentials,token,refresh
|
@@ -0,0 +1,17 @@
|
|
1
|
+
boto3_refresh_session/__init__.py,sha256=oUmq6AKEMx1Gvi0U6BPMiktIargvfJVoMwyC4jm60eA,387
|
2
|
+
boto3_refresh_session/exceptions.py,sha256=cP5d9S8QnUEwXIU3pzMGr6jMOz447kddNJ_UIRERMrk,964
|
3
|
+
boto3_refresh_session/methods/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
boto3_refresh_session/methods/custom.py,sha256=fMqaSgbmv-mfDMe1lXEPF1V4dQcwPsCN8qcRHW2IeqE,4209
|
5
|
+
boto3_refresh_session/methods/ecs.py,sha256=aXQXS7beS2RBXIeQkUNQkM4zhtDQv0n1Mkf9wnFbOTE,3931
|
6
|
+
boto3_refresh_session/methods/iot/__init__.typed,sha256=Z33nIB6oCsz9TZwikHfNHgY1SKxkSCdB5rwdPSUl3C4,135
|
7
|
+
boto3_refresh_session/methods/iot/certificate.typed,sha256=xBucJJfRb0_iKuhbtRxOWeRERzyJxo7iYW6-0VbmdA0,1816
|
8
|
+
boto3_refresh_session/methods/iot/cognito.typed,sha256=OgFYOCDIkt2QC_F0KLL_BrxVxT6qMwjn-0yi4ZIwZYo,431
|
9
|
+
boto3_refresh_session/methods/iot/core.typed,sha256=tL-ngB2XYq0XtxhS9mbggCJYdX3eEE0u1Gvcq8sEYGE,1422
|
10
|
+
boto3_refresh_session/methods/sts.py,sha256=FvblbuXDaczEfsRIs59eKOodrJjHcMKHrnrmxjXfNeU,3401
|
11
|
+
boto3_refresh_session/session.py,sha256=_Z3uB5Xq3S-dFqOFmWhMQbcd__NPGThjULLPStHI6E4,2914
|
12
|
+
boto3_refresh_session/utils.py,sha256=9Nru9GWWMAboDRJMstKIBFtKA2R8u3DFFcCvsQYSNCI,7976
|
13
|
+
boto3_refresh_session-2.0.9.dist-info/LICENSE,sha256=I3ZYTXAjbIly6bm6J-TvFTuuHwTKws4h89QaY5c5HiY,1067
|
14
|
+
boto3_refresh_session-2.0.9.dist-info/METADATA,sha256=0M9RJlmPWHbmYrbgz1MjLU7BaSsm8wpr4dAkuJJ86Hs,8795
|
15
|
+
boto3_refresh_session-2.0.9.dist-info/NOTICE,sha256=1s8r33qbl1z0YvPB942iWgvbkP94P_e8AnROr1qXXuw,939
|
16
|
+
boto3_refresh_session-2.0.9.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
17
|
+
boto3_refresh_session-2.0.9.dist-info/RECORD,,
|
@@ -1,17 +0,0 @@
|
|
1
|
-
boto3_refresh_session/__init__.py,sha256=3VYnpC-52TTWbTfkoYwW5o7ImCNWsLGeKNWk5CmL5k8,387
|
2
|
-
boto3_refresh_session/exceptions.py,sha256=cP5d9S8QnUEwXIU3pzMGr6jMOz447kddNJ_UIRERMrk,964
|
3
|
-
boto3_refresh_session/methods/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
boto3_refresh_session/methods/custom.py,sha256=JDDfBszAesNV2gSv8lJvGxCpbM9-lUn0L9HDt-rPETM,3846
|
5
|
-
boto3_refresh_session/methods/ecs.py,sha256=qejldriuTVpHPSkquHeo4vLGbe0_WAg_iayuJFk6W9Q,3728
|
6
|
-
boto3_refresh_session/methods/iot/__init__.typed,sha256=Z33nIB6oCsz9TZwikHfNHgY1SKxkSCdB5rwdPSUl3C4,135
|
7
|
-
boto3_refresh_session/methods/iot/certificate.typed,sha256=yvKptwH-GagBREI_1AXs_mCaU6vL3AcUDQ58vn7V8QM,1774
|
8
|
-
boto3_refresh_session/methods/iot/cognito.typed,sha256=0VorzOXHpsVemiGWZzHE9fuX-MZcpqzWQ4nK3gNDUMg,389
|
9
|
-
boto3_refresh_session/methods/iot/core.typed,sha256=tL-ngB2XYq0XtxhS9mbggCJYdX3eEE0u1Gvcq8sEYGE,1422
|
10
|
-
boto3_refresh_session/methods/sts.py,sha256=SjeVNXXB50wLINr5GhjALrnytPleu6UeE0BBAJU28Lc,3226
|
11
|
-
boto3_refresh_session/session.py,sha256=_Z3uB5Xq3S-dFqOFmWhMQbcd__NPGThjULLPStHI6E4,2914
|
12
|
-
boto3_refresh_session/utils.py,sha256=z-lN5szAETD88-h4pNEwBDcqAPqzeGo5QJ0hNUJdDWA,5560
|
13
|
-
boto3_refresh_session-2.0.7.dist-info/LICENSE,sha256=I3ZYTXAjbIly6bm6J-TvFTuuHwTKws4h89QaY5c5HiY,1067
|
14
|
-
boto3_refresh_session-2.0.7.dist-info/METADATA,sha256=fhSKcYLuhphxBm8uLmzAKt7kO4YE1dbl3gsPj_Li4DU,8795
|
15
|
-
boto3_refresh_session-2.0.7.dist-info/NOTICE,sha256=1s8r33qbl1z0YvPB942iWgvbkP94P_e8AnROr1qXXuw,939
|
16
|
-
boto3_refresh_session-2.0.7.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
17
|
-
boto3_refresh_session-2.0.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|