boto3-refresh-session 2.0.6__py3-none-any.whl → 2.0.8__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.
@@ -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.6"
7
+ __version__ = "2.0.8"
8
8
  __title__ = "boto3-refresh-session"
9
9
  __author__ = "Mike Letts"
10
10
  __maintainer__ = "Mike Letts"
@@ -4,11 +4,12 @@ __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 RefreshMethod, TemporaryCredentials
9
+ from ..utils import TemporaryCredentials, refreshable_session
10
10
 
11
11
 
12
+ @refreshable_session
12
13
  class CustomRefreshableSession(BaseRefreshableSession, registry_key="custom"):
13
14
  """A :class:`boto3.session.Session` object that automatically refreshes
14
15
  temporary credentials returned by a custom credential getter provided
@@ -63,13 +64,17 @@ class CustomRefreshableSession(BaseRefreshableSession, registry_key="custom"):
63
64
  self,
64
65
  custom_credentials_method: Callable,
65
66
  custom_credentials_method_args: dict[str, Any] | None = None,
66
- defer_refresh: bool | None = None,
67
67
  **kwargs,
68
68
  ):
69
- self.defer_refresh = defer_refresh is not False
70
- self.refresh_method: RefreshMethod = "custom"
71
- super().__init__(**kwargs)
69
+ if "refresh_method" in kwargs:
70
+ BRSWarning(
71
+ "'refresh_method' cannot be set manually. "
72
+ "Reverting to 'custom'."
73
+ )
74
+ del kwargs["refresh_method"]
72
75
 
76
+ # initializing BRSSession
77
+ super().__init__(refresh_method="custom", **kwargs)
73
78
  self._custom_get_credentials = custom_credentials_method
74
79
  self._custom_get_credentials_args = (
75
80
  custom_credentials_method_args
@@ -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 RefreshMethod, TemporaryCredentials
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,11 +35,18 @@ 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, defer_refresh: bool | None = None, **kwargs):
38
- self.defer_refresh: bool = defer_refresh is not False
39
- self.refresh_method: RefreshMethod = "ecs-container-metadata"
40
- super().__init__(**kwargs) # mounting refreshable credentials
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)
41
48
 
49
+ # initializing various other attributes
42
50
  self._endpoint = self._resolve_endpoint()
43
51
  self._headers = self._build_headers()
44
52
  self._http = self._init_http_session()
@@ -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,14 +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
- self.defer_refresh: bool = defer_refresh is not False
51
- self.refresh_method: RefreshMethod = "sts-assume-role"
52
- super().__init__(**kwargs) # mounting refreshable credentials
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)
53
59
 
60
+ # initializing various other attributes
54
61
  self.assume_role_kwargs = assume_role_kwargs
55
62
 
56
63
  if sts_client_kwargs is not None:
@@ -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,
@@ -9,6 +12,7 @@ from typing import (
9
12
  Literal,
10
13
  TypedDict,
11
14
  TypeVar,
15
+ cast,
12
16
  )
13
17
 
14
18
  from boto3.session import Session
@@ -45,6 +49,52 @@ RefreshMethod = Literal[
45
49
  #: Type alias for all currently registered credential refresh methods.
46
50
  RegistryKey = TypeVar("RegistryKey", bound=str)
47
51
 
52
+ #: Type alias for a generic refreshable session type.
53
+ BRSSessionType = TypeVar("BRSSessionType", bound="BRSSession")
54
+
55
+
56
+ def refreshable_session(
57
+ cls: type[BRSSessionType],
58
+ ) -> type[BRSSessionType]:
59
+ """Wraps cls.__init__ so self.__post_init__ runs after init (if present).
60
+
61
+ Returns
62
+ -------
63
+ BRSSessionType
64
+ The decorated class.
65
+ """
66
+
67
+ init = getattr(cls, "__init__", None)
68
+
69
+ # synthesize __init__ if undefined in the class
70
+ if init in (None, object.__init__):
71
+
72
+ def __init__(self, *args, **kwargs):
73
+ super(cls, self).__init__(*args, **kwargs)
74
+ post = getattr(self, "__post_init__", None)
75
+ if callable(post) and not getattr(self, "_post_inited", False):
76
+ post()
77
+ setattr(self, "_post_inited", True)
78
+
79
+ cls.__init__ = __init__ # type: ignore[assignment]
80
+ return cls
81
+
82
+ # avoids double wrapping
83
+ if getattr(init, "__post_init_wrapped__", False):
84
+ return cls
85
+
86
+ @wraps(init)
87
+ def wrapper(self, *args, **kwargs):
88
+ init(self, *args, **kwargs)
89
+ post = getattr(self, "__post_init__", None)
90
+ if callable(post) and not getattr(self, "_post_inited", False):
91
+ post()
92
+ setattr(self, "_post_inited", True)
93
+
94
+ wrapper.__post_init_wrapped__ = True # type: ignore[attr-defined]
95
+ cls.__init__ = cast(Callable[..., None], wrapper)
96
+ return cls
97
+
48
98
 
49
99
  class Registry(Generic[RegistryKey]):
50
100
  """Gives any hierarchy a class-level registry."""
@@ -107,12 +157,28 @@ class CredentialProvider(ABC):
107
157
  class BRSSession(Session):
108
158
  """Wrapper for boto3.session.Session.
109
159
 
160
+ Parameters
161
+ ----------
162
+ refresh_method : RefreshMethod
163
+ The method to use for refreshing temporary credentials.
164
+ defer_refresh : bool, default=True
165
+ If True, the initial credential refresh is deferred until the
166
+ credentials are first accessed. If False, the initial refresh
167
+
110
168
  Other Parameters
111
169
  ----------------
112
170
  kwargs : Any
113
- Optional keyword arguments for initializing boto3.session.Session."""
171
+ Optional keyword arguments for initializing boto3.session.Session.
172
+ """
114
173
 
115
- def __init__(self, **kwargs):
174
+ def __init__(
175
+ self,
176
+ refresh_method: RefreshMethod,
177
+ defer_refresh: bool | None = None,
178
+ **kwargs,
179
+ ):
180
+ self.refresh_method: RefreshMethod = refresh_method
181
+ self.defer_refresh: bool = defer_refresh is not False
116
182
  super().__init__(**kwargs)
117
183
 
118
184
  def __post_init__(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: boto3-refresh-session
3
- Version: 2.0.6
3
+ Version: 2.0.8
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=HfXKz-omIFHEIEjjPVuwpmkqrAox_HU_IFXeTrVTazU,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=-KzDFOykdbjXMwGYVJZP8Qbwz8zEbS0R8BtJE8vvfWw,3976
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=SBzqLeCsAWpDJfGNjIvYPZ5cEKClluOzATHgLKxSWMA,7590
13
+ boto3_refresh_session-2.0.8.dist-info/LICENSE,sha256=I3ZYTXAjbIly6bm6J-TvFTuuHwTKws4h89QaY5c5HiY,1067
14
+ boto3_refresh_session-2.0.8.dist-info/METADATA,sha256=MQZkpUhHdFISwB07q_tKXNV6iGlRaWJ-TaX0x4MSrBw,8795
15
+ boto3_refresh_session-2.0.8.dist-info/NOTICE,sha256=1s8r33qbl1z0YvPB942iWgvbkP94P_e8AnROr1qXXuw,939
16
+ boto3_refresh_session-2.0.8.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
17
+ boto3_refresh_session-2.0.8.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- boto3_refresh_session/__init__.py,sha256=ngE9JZBwTOaSEfIBSSv7MAAKx5YQDz6gfVdNERSolSE,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=W12lt83jrSy4MsCBEdd2BfeG1v509cmb3DxAMsKqijI,3812
5
- boto3_refresh_session/methods/ecs.py,sha256=6iquaA1aKvEKr_A6ySxMXnTC9drZXjzdM025S30Dyqo,3736
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=KuWCUmGUOsvakDYSK1zXRlRYHgIXqdrcvXmszqGBg0I,3233
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.6.dist-info/LICENSE,sha256=I3ZYTXAjbIly6bm6J-TvFTuuHwTKws4h89QaY5c5HiY,1067
14
- boto3_refresh_session-2.0.6.dist-info/METADATA,sha256=KkQk5KZbB77r5KgGMKVMx5H6HElHhrtj0SQ6O1dz9c0,8795
15
- boto3_refresh_session-2.0.6.dist-info/NOTICE,sha256=1s8r33qbl1z0YvPB942iWgvbkP94P_e8AnROr1qXXuw,939
16
- boto3_refresh_session-2.0.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
17
- boto3_refresh_session-2.0.6.dist-info/RECORD,,