aws-python-helper 1.9.3__tar.gz → 1.11.0__tar.gz
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.
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/PKG-INFO +1 -1
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/base.py +79 -5
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/invoker/api_client.py +60 -20
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/repository/base.py +34 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/PKG-INFO +1 -1
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/pyproject.toml +1 -1
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/README.md +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/auth_middleware.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/auth_validators.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/dispatcher.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/exceptions.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/fetcher.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/handler.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/context/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/context/session.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/context/state_validator.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/database/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/database/database_proxy.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/database/external_database_proxy.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/database/external_mongo_manager.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/database/mongo_manager.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/fargate/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/fargate/executor.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/fargate/fetcher.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/fargate/handler.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/fargate/task_base.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/invoker/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/invoker/exceptions.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/invoker/lambda_invoker.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/base.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/fetcher.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/handler.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/model_index_sync/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/model_index_sync/base.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/model_query/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/model_query/base.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/monitoring/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/monitoring/run.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/permissions/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/permissions/catalog.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/repository/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/repository/audit.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/sns/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/sns/publisher.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/sqs/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/sqs/consumer_base.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/sqs/fetcher.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/sqs/handler.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/utils/__init__.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/utils/json_encoder.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/utils/response.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/utils/serializer.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/SOURCES.txt +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/dependency_links.txt +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/requires.txt +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/top_level.txt +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/setup.cfg +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/tests/test_audit_stamp.py +0 -0
- {aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/tests/test_sns_publisher.py +0 -0
|
@@ -4,7 +4,7 @@ API Base Class - Base class for all REST APIs
|
|
|
4
4
|
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
6
|
import logging
|
|
7
|
-
from typing import Dict, Any, Optional, List
|
|
7
|
+
from typing import Dict, Any, Optional, List, Tuple
|
|
8
8
|
from ..database.mongo_manager import MongoManager
|
|
9
9
|
from ..database.database_proxy import DatabaseProxy
|
|
10
10
|
from ..database.external_mongo_manager import ExternalMongoManager
|
|
@@ -12,6 +12,18 @@ from ..database.external_database_proxy import ExternalDatabaseProxy
|
|
|
12
12
|
from ..context.session import get_session
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
def _positive(value: Any) -> Optional[int]:
|
|
16
|
+
"""Un entero positivo de la query, o None si no lo es.
|
|
17
|
+
|
|
18
|
+
Llega como texto desde la URL, y puede llegar cualquier cosa.
|
|
19
|
+
"""
|
|
20
|
+
try:
|
|
21
|
+
number = int(value)
|
|
22
|
+
except (TypeError, ValueError):
|
|
23
|
+
return None
|
|
24
|
+
return number if number > 0 else None
|
|
25
|
+
|
|
26
|
+
|
|
15
27
|
class API(ABC):
|
|
16
28
|
"""
|
|
17
29
|
Base class for all REST APIs
|
|
@@ -186,20 +198,82 @@ class API(ABC):
|
|
|
186
198
|
"""
|
|
187
199
|
return self._is_authenticated
|
|
188
200
|
|
|
201
|
+
# Lo que una página puede pedir. El máximo no es una opinión: es lo que una
|
|
202
|
+
# respuesta de lambda aguanta sin que el navegador se atragante.
|
|
203
|
+
DEFAULT_PAGE_SIZE = 50
|
|
204
|
+
MAX_PAGE_SIZE = 200
|
|
205
|
+
|
|
206
|
+
def page_bounds(self) -> Tuple[int, int]:
|
|
207
|
+
"""Qué pedazo pidieron, acotado a algo que se pueda servir.
|
|
208
|
+
|
|
209
|
+
Sale de `page` y `size` de la query, que llegan como texto. Un valor que
|
|
210
|
+
no es un número, o que no tiene sentido, cae al default en vez de fallar:
|
|
211
|
+
un listado que devuelve 400 porque alguien escribió `page=abc` en la URL
|
|
212
|
+
es un listado roto por nada.
|
|
213
|
+
"""
|
|
214
|
+
page = max(1, _positive(self.data.get('page')) or 1)
|
|
215
|
+
size = _positive(self.data.get('size')) or self.DEFAULT_PAGE_SIZE
|
|
216
|
+
size = min(self.MAX_PAGE_SIZE, max(1, size))
|
|
217
|
+
return (page - 1) * size, size
|
|
218
|
+
|
|
219
|
+
def paged(
|
|
220
|
+
self, items: List[Any], total: int, key: str = 'items'
|
|
221
|
+
) -> Dict[str, Any]:
|
|
222
|
+
"""The body of a paged listing.
|
|
223
|
+
|
|
224
|
+
The total travels with the page because without it a panel cannot draw a
|
|
225
|
+
paginator, and whoever is looking cannot tell ten of twelve from ten of a
|
|
226
|
+
million.
|
|
227
|
+
|
|
228
|
+
`key` names the list so an endpoint can keep answering `users` or
|
|
229
|
+
`regions` instead of a generic `items`; what a listing is called is part
|
|
230
|
+
of how it reads.
|
|
231
|
+
"""
|
|
232
|
+
_, size = self.page_bounds()
|
|
233
|
+
page = max(1, _positive(self.data.get('page')) or 1)
|
|
234
|
+
return {
|
|
235
|
+
key: items,
|
|
236
|
+
'page': page,
|
|
237
|
+
'size': size,
|
|
238
|
+
'total': total,
|
|
239
|
+
'pages': (total + size - 1) // size if size else 0,
|
|
240
|
+
}
|
|
241
|
+
|
|
189
242
|
async def granted_permissions(self):
|
|
190
243
|
"""Which permissions the caller holds, or None when this API does not know.
|
|
191
244
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
core
|
|
245
|
+
By default they come from the token: core signs them in, so a service
|
|
246
|
+
authorizes on its own without asking anybody. That is the whole point —
|
|
247
|
+
a service that had to call core on every request would put core back in
|
|
248
|
+
the read path of the entire platform.
|
|
249
|
+
|
|
250
|
+
Override it where the list comes from somewhere else. Core does: it holds
|
|
251
|
+
the roles, so it reads them rather than trusting a claim it just signed.
|
|
195
252
|
|
|
196
253
|
Returning None with AUTHORIZATION=permission is refused, not waved
|
|
197
254
|
through. An endpoint that cannot say what its caller may do has to be a
|
|
198
255
|
closed door: the alternative is that forgetting to wire this up leaves it
|
|
199
256
|
open to anyone holding a token, which is the failure this whole mechanism
|
|
200
257
|
exists to prevent.
|
|
258
|
+
|
|
259
|
+
A token with no `permissions` claim yields an empty list, not None: it is
|
|
260
|
+
a caller who may do nothing, which is different from an endpoint that
|
|
261
|
+
cannot tell.
|
|
201
262
|
"""
|
|
202
|
-
|
|
263
|
+
auth = self.auth_data or {}
|
|
264
|
+
|
|
265
|
+
# La marca de dev y el token maestro responden por todo: son la forma de
|
|
266
|
+
# entrar cuando una configuración de permisos quedó mal.
|
|
267
|
+
if auth.get('is_bypass') or (auth.get('user') or {}).get('is_dev') is True:
|
|
268
|
+
from ..permissions import ALL
|
|
269
|
+
return [ALL]
|
|
270
|
+
|
|
271
|
+
claims = auth.get('token_data')
|
|
272
|
+
if not isinstance(claims, dict):
|
|
273
|
+
return None
|
|
274
|
+
|
|
275
|
+
granted = claims.get('permissions')
|
|
276
|
+
return list(granted) if isinstance(granted, list) else []
|
|
203
277
|
|
|
204
278
|
@property
|
|
205
279
|
def service_code(self) -> str:
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/invoker/api_client.py
RENAMED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import logging
|
|
3
2
|
import os
|
|
4
3
|
from typing import Any, Dict, Optional
|
|
@@ -13,26 +12,58 @@ _AUTH_HEADER = "Authorization"
|
|
|
13
12
|
_BEARER_PREFIX = "Bearer"
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
CORE = "core"
|
|
16
|
+
|
|
17
|
+
# Lo que este contenedor ya averiguó. Vive lo que vive la lambda, que es lo que
|
|
18
|
+
# se quiere: un servicio redesplegado con otra URL se conoce en el próximo
|
|
19
|
+
# arranque en frío, no dentro de horas.
|
|
20
|
+
_RESOLVED: Dict[str, str] = {}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _core_url() -> str:
|
|
24
|
+
"""Dónde está core. Es lo único que un servicio necesita saber de memoria.
|
|
25
|
+
|
|
26
|
+
Todo lo demás se lo pregunta a core, que lleva el registro de quién existe y
|
|
27
|
+
dónde responde. Una sola variable por servicio en vez de un mapa que había
|
|
28
|
+
que escribir en el secret de cada uno y mantener sincronizado a mano.
|
|
29
|
+
"""
|
|
30
|
+
url = (os.getenv("CORE_API_URL") or "").rstrip("/")
|
|
31
|
+
if not url:
|
|
19
32
|
raise ServiceNotConfiguredError(
|
|
20
|
-
"
|
|
33
|
+
"CORE_API_URL is not set: this service cannot reach core, and core is "
|
|
34
|
+
"where it learns about everything else."
|
|
21
35
|
)
|
|
22
|
-
|
|
23
|
-
urls = json.loads(raw)
|
|
24
|
-
except json.JSONDecodeError as exc:
|
|
25
|
-
raise ServiceNotConfiguredError(
|
|
26
|
-
"MICROSERVICE_URLS is not valid JSON"
|
|
27
|
-
) from exc
|
|
36
|
+
return url
|
|
28
37
|
|
|
29
|
-
|
|
38
|
+
|
|
39
|
+
async def resolve_service_url(service_name: str) -> str:
|
|
40
|
+
"""La dirección de un servicio, según el registro de core."""
|
|
41
|
+
if service_name == CORE:
|
|
42
|
+
return _core_url()
|
|
43
|
+
|
|
44
|
+
if service_name in _RESOLVED:
|
|
45
|
+
return _RESOLVED[service_name]
|
|
46
|
+
|
|
47
|
+
token = _resolve_token()
|
|
48
|
+
headers = {_AUTH_HEADER: f"{_BEARER_PREFIX} {token}"} if token else {}
|
|
49
|
+
|
|
50
|
+
async with httpx.AsyncClient(timeout=10) as client:
|
|
51
|
+
response = await client.get(f"{_core_url()}/services", headers=headers)
|
|
52
|
+
response.raise_for_status()
|
|
53
|
+
services = (response.json() or {}).get("services") or []
|
|
54
|
+
|
|
55
|
+
for service in services:
|
|
56
|
+
if service.get("api_url"):
|
|
57
|
+
_RESOLVED[service["code"]] = service["api_url"].rstrip("/")
|
|
58
|
+
|
|
59
|
+
url = _RESOLVED.get(service_name)
|
|
30
60
|
if not url:
|
|
31
|
-
|
|
61
|
+
known = ", ".join(sorted(_RESOLVED)) or "none"
|
|
32
62
|
raise ServiceNotConfiguredError(
|
|
33
|
-
f"
|
|
63
|
+
f"Core does not know a service called '{service_name}'. Registered: {known}. "
|
|
64
|
+
"A service appears here when it deploys."
|
|
34
65
|
)
|
|
35
|
-
return url
|
|
66
|
+
return url
|
|
36
67
|
|
|
37
68
|
|
|
38
69
|
def _resolve_token() -> Optional[str]:
|
|
@@ -61,8 +92,8 @@ class ApiClient:
|
|
|
61
92
|
client = ApiClient("dockets", headers={"constitution-state": "CT"})
|
|
62
93
|
|
|
63
94
|
Environment variables:
|
|
64
|
-
|
|
65
|
-
|
|
95
|
+
CORE_API_URL Where core answers. The only address a service
|
|
96
|
+
holds; everything else it asks core for.
|
|
66
97
|
INTER_SERVICE_TOKEN Bearer token for service-to-service calls
|
|
67
98
|
AUTH_BYPASS_TOKEN Fallback if INTER_SERVICE_TOKEN is not set
|
|
68
99
|
"""
|
|
@@ -73,7 +104,8 @@ class ApiClient:
|
|
|
73
104
|
headers: Optional[Dict[str, str]] = None,
|
|
74
105
|
timeout: int = 30,
|
|
75
106
|
):
|
|
76
|
-
self.
|
|
107
|
+
self._service_name = service_name
|
|
108
|
+
self._base_url: Optional[str] = None
|
|
77
109
|
self._timeout = timeout
|
|
78
110
|
self._headers = self._build_default_headers(headers or {})
|
|
79
111
|
self.logger = logging.getLogger(self.__class__.__name__)
|
|
@@ -86,7 +118,15 @@ class ApiClient:
|
|
|
86
118
|
headers.update(extra)
|
|
87
119
|
return headers
|
|
88
120
|
|
|
89
|
-
def _url(self, path: str) -> str:
|
|
121
|
+
async def _url(self, path: str) -> str:
|
|
122
|
+
"""La URL completa, resolviendo el servicio la primera vez que hace falta.
|
|
123
|
+
|
|
124
|
+
Se resuelve al usarse y no al construirse porque preguntarle a core es
|
|
125
|
+
una llamada de red, y un constructor que hace una llamada de red no se
|
|
126
|
+
puede usar en ningún lado sin pensarlo.
|
|
127
|
+
"""
|
|
128
|
+
if self._base_url is None:
|
|
129
|
+
self._base_url = await resolve_service_url(self._service_name)
|
|
90
130
|
return f"{self._base_url}/{path.lstrip('/')}"
|
|
91
131
|
|
|
92
132
|
async def get(self, path: str, params: Optional[Dict] = None) -> Any:
|
|
@@ -120,7 +160,7 @@ class ApiClient:
|
|
|
120
160
|
params: Optional[Dict] = None,
|
|
121
161
|
body: Optional[Dict] = None,
|
|
122
162
|
) -> Any:
|
|
123
|
-
url = self._url(path)
|
|
163
|
+
url = await self._url(path)
|
|
124
164
|
try:
|
|
125
165
|
async with httpx.AsyncClient(timeout=self._timeout) as client:
|
|
126
166
|
response = await client.request(
|
|
@@ -263,6 +263,40 @@ class Repository(ABC):
|
|
|
263
263
|
|
|
264
264
|
return self._collection_cache[key]
|
|
265
265
|
|
|
266
|
+
async def page(
|
|
267
|
+
self,
|
|
268
|
+
query: Optional[Dict[str, Any]] = None,
|
|
269
|
+
*,
|
|
270
|
+
sort: Optional[List[tuple]] = None,
|
|
271
|
+
skip: int = 0,
|
|
272
|
+
limit: int = 50,
|
|
273
|
+
projection: Optional[Dict[str, Any]] = None,
|
|
274
|
+
) -> Tuple[List[Dict[str, Any]], int]:
|
|
275
|
+
"""A page of this collection and how many there are in total.
|
|
276
|
+
|
|
277
|
+
The count is a separate query and not a `$facet`: counting a filtered
|
|
278
|
+
million is expensive, and putting it in the same pipeline makes the page
|
|
279
|
+
wait for the count.
|
|
280
|
+
|
|
281
|
+
With no filter the total is **estimated**, which reads collection
|
|
282
|
+
metadata instead of the documents. Over a large collection that is the
|
|
283
|
+
difference between instant and a second full read, and the number is only
|
|
284
|
+
there to draw a paginator — nobody needs to know there are exactly
|
|
285
|
+
1,221,736 rather than about that.
|
|
286
|
+
"""
|
|
287
|
+
query = query or {}
|
|
288
|
+
cursor = self.collection.find(query, projection)
|
|
289
|
+
if sort:
|
|
290
|
+
cursor = cursor.sort(sort)
|
|
291
|
+
items = await cursor.skip(skip).limit(limit).to_list(length=limit)
|
|
292
|
+
|
|
293
|
+
total = (
|
|
294
|
+
await self.collection.count_documents(query)
|
|
295
|
+
if query
|
|
296
|
+
else await self.collection.estimated_document_count()
|
|
297
|
+
)
|
|
298
|
+
return items, total
|
|
299
|
+
|
|
266
300
|
async def ensure_indexes(self, database_name: Optional[str] = None):
|
|
267
301
|
"""
|
|
268
302
|
Creates all indexes defined in the `indexes` property, blocking until done.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/auth_middleware.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/api/auth_validators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/context/state_validator.py
RENAMED
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/database/database_proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/database/mongo_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/invoker/exceptions.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/invoker/lambda_invoker.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/__init__.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/base.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/fetcher.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/lambda_standalone/handler.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/model_index_sync/__init__.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/model_index_sync/base.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/model_query/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/monitoring/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/permissions/__init__.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/permissions/catalog.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/repository/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper/utils/json_encoder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/requires.txt
RENAMED
|
File without changes
|
{aws_python_helper-1.9.3 → aws_python_helper-1.11.0}/aws_python_helper.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|