aws-python-helper 1.9.0__tar.gz → 1.9.2__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.0 → aws_python_helper-1.9.2}/PKG-INFO +1 -1
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/repository/audit.py +22 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/sns/publisher.py +11 -7
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper.egg-info/PKG-INFO +1 -1
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper.egg-info/SOURCES.txt +3 -1
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/pyproject.toml +1 -1
- aws_python_helper-1.9.2/tests/test_audit_stamp.py +88 -0
- aws_python_helper-1.9.2/tests/test_sns_publisher.py +125 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/README.md +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/auth_middleware.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/auth_validators.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/base.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/dispatcher.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/exceptions.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/fetcher.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/handler.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/context/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/context/session.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/context/state_validator.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/database/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/database/database_proxy.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/database/external_database_proxy.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/database/external_mongo_manager.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/database/mongo_manager.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/fargate/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/fargate/executor.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/fargate/fetcher.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/fargate/handler.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/fargate/task_base.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/invoker/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/invoker/api_client.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/invoker/exceptions.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/invoker/lambda_invoker.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/base.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/fetcher.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/handler.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/model_index_sync/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/model_index_sync/base.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/model_query/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/model_query/base.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/monitoring/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/monitoring/run.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/permissions/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/permissions/catalog.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/repository/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/repository/base.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/sns/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/sqs/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/sqs/consumer_base.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/sqs/fetcher.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/sqs/handler.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/utils/__init__.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/utils/json_encoder.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/utils/response.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/utils/serializer.py +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper.egg-info/dependency_links.txt +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper.egg-info/requires.txt +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper.egg-info/top_level.txt +0 -0
- {aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/setup.cfg +0 -0
|
@@ -124,6 +124,23 @@ def _merge_into_set(update: Dict[str, Any], values: Dict[str, Any], operator: st
|
|
|
124
124
|
section.setdefault(key, value)
|
|
125
125
|
|
|
126
126
|
|
|
127
|
+
def _written_elsewhere(update: Dict[str, Any], key: str, operator: str) -> bool:
|
|
128
|
+
"""Si otro operador de esta misma actualización ya escribe ese campo.
|
|
129
|
+
|
|
130
|
+
Mongo rechaza el update entero si dos operadores tocan la misma ruta —
|
|
131
|
+
`$set: {status}` junto a `$setOnInsert: {status}` da "would create a
|
|
132
|
+
conflict at 'status'" — y el sello no tiene por qué ser el que lo provoque.
|
|
133
|
+
Si el llamador ya escribe el campo, el insert va a quedar con su valor, así
|
|
134
|
+
que el sello ahí sobra.
|
|
135
|
+
"""
|
|
136
|
+
for other, section in update.items():
|
|
137
|
+
if other == operator or not other.startswith('$') or not isinstance(section, dict):
|
|
138
|
+
continue
|
|
139
|
+
if key in section:
|
|
140
|
+
return True
|
|
141
|
+
return False
|
|
142
|
+
|
|
143
|
+
|
|
127
144
|
def stamp_update(
|
|
128
145
|
update: Union[Dict[str, Any], List[Dict[str, Any]]],
|
|
129
146
|
upsert: bool = False,
|
|
@@ -164,6 +181,11 @@ def stamp_update(
|
|
|
164
181
|
born = {CREATED_AT: now, CREATED_BY: who}
|
|
165
182
|
if statuses:
|
|
166
183
|
born[STATUS] = default_status or statuses[0]
|
|
184
|
+
born = {
|
|
185
|
+
key: value
|
|
186
|
+
for key, value in born.items()
|
|
187
|
+
if not _written_elsewhere(update, key, '$setOnInsert')
|
|
188
|
+
}
|
|
167
189
|
_merge_into_set(update, born, '$setOnInsert')
|
|
168
190
|
return update
|
|
169
191
|
|
|
@@ -276,13 +276,18 @@ class SNSPublisher(ABC):
|
|
|
276
276
|
|
|
277
277
|
return formatted
|
|
278
278
|
|
|
279
|
-
def _format_message(
|
|
279
|
+
def _format_message(
|
|
280
|
+
self, message: Dict[str, Any], index: Optional[int] = None
|
|
281
|
+
) -> Dict[str, Any]:
|
|
280
282
|
"""
|
|
281
283
|
Formats the message for SNS
|
|
282
|
-
|
|
284
|
+
|
|
283
285
|
Args:
|
|
284
286
|
message: Message to format
|
|
285
|
-
|
|
287
|
+
index: Position inside a batch. `publish_batch` needs an `Id` per
|
|
288
|
+
entry; plain `publish` does not take one at all, so a single
|
|
289
|
+
message leaves it out.
|
|
290
|
+
|
|
286
291
|
Returns:
|
|
287
292
|
Formatted message
|
|
288
293
|
"""
|
|
@@ -305,10 +310,9 @@ class SNSPublisher(ABC):
|
|
|
305
310
|
session_json = self._serialize_message(session_dict)
|
|
306
311
|
attributes['session'] = base64.b64encode(session_json.encode('utf-8')).decode('utf-8')
|
|
307
312
|
|
|
308
|
-
params = {
|
|
309
|
-
|
|
310
|
-
'
|
|
311
|
-
}
|
|
313
|
+
params: Dict[str, Any] = {'Message': content}
|
|
314
|
+
if index is not None:
|
|
315
|
+
params['Id'] = str(index)
|
|
312
316
|
|
|
313
317
|
# Add subject if exists
|
|
314
318
|
if subject:
|
|
@@ -55,4 +55,6 @@ aws_python_helper/sqs/handler.py
|
|
|
55
55
|
aws_python_helper/utils/__init__.py
|
|
56
56
|
aws_python_helper/utils/json_encoder.py
|
|
57
57
|
aws_python_helper/utils/response.py
|
|
58
|
-
aws_python_helper/utils/serializer.py
|
|
58
|
+
aws_python_helper/utils/serializer.py
|
|
59
|
+
tests/test_audit_stamp.py
|
|
60
|
+
tests/test_sns_publisher.py
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""What the audit stamp must never do to a write.
|
|
2
|
+
|
|
3
|
+
Runs on its own, no dependencies:
|
|
4
|
+
|
|
5
|
+
python tests/test_audit_stamp.py
|
|
6
|
+
|
|
7
|
+
These are here because the stamp broke a write in production once: an upsert
|
|
8
|
+
that set `status` itself collided with the `$setOnInsert` the stamp added, and
|
|
9
|
+
Mongo refused the whole update with "would create a conflict at 'status'". It
|
|
10
|
+
failed at runtime, on one endpoint, in a log nobody was reading.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
17
|
+
|
|
18
|
+
from aws_python_helper.repository.audit import stamp_update # noqa: E402
|
|
19
|
+
|
|
20
|
+
STATUSES = ["active", "inactive"]
|
|
21
|
+
|
|
22
|
+
failures = []
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def check(label, condition, detail=""):
|
|
26
|
+
mark = "ok " if condition else "FAIL"
|
|
27
|
+
print(f" {mark} {label}{' ' + detail if detail else ''}")
|
|
28
|
+
if not condition:
|
|
29
|
+
failures.append(label)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def conflicts(update):
|
|
33
|
+
"""Los campos que dos operadores de un mismo update escriben a la vez.
|
|
34
|
+
|
|
35
|
+
Es lo que Mongo rechaza, y rechaza el update entero: no escribe nada.
|
|
36
|
+
"""
|
|
37
|
+
sections = [
|
|
38
|
+
(name, section) for name, section in update.items()
|
|
39
|
+
if name.startswith("$") and isinstance(section, dict)
|
|
40
|
+
]
|
|
41
|
+
clash = set()
|
|
42
|
+
for index, (_, first) in enumerate(sections):
|
|
43
|
+
for _, second in sections[index + 1:]:
|
|
44
|
+
clash |= set(first) & set(second)
|
|
45
|
+
return clash
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
print("no two operators may write the same path")
|
|
49
|
+
for label, update in [
|
|
50
|
+
("upsert that sets status itself", {"$set": {"name": "ct", "status": "active"}}),
|
|
51
|
+
("upsert that sets created_at itself", {"$set": {"created_at": "fixed"}}),
|
|
52
|
+
("upsert that sets created_by itself", {"$set": {"created_by": {"name": "x"}}}),
|
|
53
|
+
("plain upsert", {"$set": {"name": "ct"}}),
|
|
54
|
+
("upsert with $inc alongside", {"$set": {"name": "ct"}, "$inc": {"hits": 1}}),
|
|
55
|
+
]:
|
|
56
|
+
result = stamp_update(dict(update), upsert=True, statuses=STATUSES, default_status="active")
|
|
57
|
+
found = conflicts(result)
|
|
58
|
+
check(label, not found, f"conflicts={sorted(found)}" if found else "")
|
|
59
|
+
|
|
60
|
+
print("\nthe stamp is still complete when nothing conflicts")
|
|
61
|
+
result = stamp_update({"$set": {"name": "ct"}}, upsert=True, statuses=STATUSES, default_status="active")
|
|
62
|
+
check("status on insert", result["$setOnInsert"].get("status") == "active")
|
|
63
|
+
check("created_at on insert", "created_at" in result["$setOnInsert"])
|
|
64
|
+
check("created_by on insert", "created_by" in result["$setOnInsert"])
|
|
65
|
+
check("updated_at always", "updated_at" in result["$set"])
|
|
66
|
+
|
|
67
|
+
print("\nthe caller's own value wins")
|
|
68
|
+
result = stamp_update({"$set": {"status": "inactive"}}, upsert=True, statuses=STATUSES, default_status="active")
|
|
69
|
+
check("status stays what the caller set", result["$set"]["status"] == "inactive")
|
|
70
|
+
check("no default forced on top", "status" not in result.get("$setOnInsert", {}))
|
|
71
|
+
|
|
72
|
+
print("\nwithout upsert there is no insert stamp")
|
|
73
|
+
result = stamp_update({"$set": {"status": "inactive"}}, upsert=False, statuses=STATUSES)
|
|
74
|
+
check("no $setOnInsert", "$setOnInsert" not in result)
|
|
75
|
+
|
|
76
|
+
print("\nwithout a vocabulary no status is invented")
|
|
77
|
+
result = stamp_update({"$set": {"name": "ct"}}, upsert=True, statuses=None)
|
|
78
|
+
check("no status", "status" not in result.get("$setOnInsert", {}))
|
|
79
|
+
|
|
80
|
+
print("\na pipeline update takes stages, not operators")
|
|
81
|
+
result = stamp_update([{"$set": {"name": "ct"}}], upsert=True, statuses=STATUSES)
|
|
82
|
+
check("still a list", isinstance(result, list))
|
|
83
|
+
check("stamp appended last", result[-1]["$set"].get("updated_at") is not None)
|
|
84
|
+
|
|
85
|
+
if failures:
|
|
86
|
+
print(f"\n{len(failures)} failed: {failures}")
|
|
87
|
+
raise SystemExit(1)
|
|
88
|
+
print("\nall good")
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"""What the publisher must hand to boto3.
|
|
2
|
+
|
|
3
|
+
Runs on its own, no dependencies:
|
|
4
|
+
|
|
5
|
+
python tests/test_sns_publisher.py
|
|
6
|
+
|
|
7
|
+
These exist because a single publish crashed in production with
|
|
8
|
+
`_format_message() missing 1 required positional argument: 'index'`. Every test
|
|
9
|
+
until then mocked `publish` itself, so the code that builds the boto3 call was
|
|
10
|
+
never executed — the mock was above the bug.
|
|
11
|
+
|
|
12
|
+
So here the fake is the **boto3 client**, not the publisher: everything the
|
|
13
|
+
publisher actually does runs.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
import asyncio
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
19
|
+
import sys
|
|
20
|
+
|
|
21
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
22
|
+
|
|
23
|
+
from aws_python_helper.sns.publisher import MAX_BATCH_ENTRIES, SNSPublisher # noqa: E402
|
|
24
|
+
|
|
25
|
+
failures = []
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def check(label, condition, detail=""):
|
|
29
|
+
print(f" {'ok ' if condition else 'FAIL'} {label}{' ' + detail if detail else ''}")
|
|
30
|
+
if not condition:
|
|
31
|
+
failures.append(label)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class FakeSNS:
|
|
35
|
+
"""Se queja igual que boto3 ante un parámetro que SNS no acepta."""
|
|
36
|
+
|
|
37
|
+
VALID_PUBLISH = {"TopicArn", "Message", "Subject", "MessageAttributes",
|
|
38
|
+
"MessageStructure", "MessageDeduplicationId", "MessageGroupId"}
|
|
39
|
+
|
|
40
|
+
def __init__(self):
|
|
41
|
+
self.published = []
|
|
42
|
+
self.batches = []
|
|
43
|
+
|
|
44
|
+
def publish(self, **kwargs):
|
|
45
|
+
extra = set(kwargs) - self.VALID_PUBLISH
|
|
46
|
+
if extra:
|
|
47
|
+
raise TypeError(f"Unknown parameter in input: {sorted(extra)}")
|
|
48
|
+
self.published.append(kwargs)
|
|
49
|
+
return {"MessageId": f"m{len(self.published)}"}
|
|
50
|
+
|
|
51
|
+
def publish_batch(self, TopicArn, PublishBatchRequestEntries):
|
|
52
|
+
if len(PublishBatchRequestEntries) > MAX_BATCH_ENTRIES:
|
|
53
|
+
raise Exception("TooManyEntriesInBatchRequest")
|
|
54
|
+
for entry in PublishBatchRequestEntries:
|
|
55
|
+
if "Id" not in entry:
|
|
56
|
+
raise Exception("An entry in a batch needs an Id")
|
|
57
|
+
self.batches.append(PublishBatchRequestEntries)
|
|
58
|
+
return {"Successful": [{"MessageId": f"b{i}"} for i in range(len(PublishBatchRequestEntries))],
|
|
59
|
+
"Failed": []}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class Publisher(SNSPublisher):
|
|
63
|
+
pass
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def publisher():
|
|
67
|
+
p = Publisher("arn:aws:sns:us-east-2:1:Topic-dev")
|
|
68
|
+
p._sns_client = FakeSNS()
|
|
69
|
+
return p
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
async def main():
|
|
73
|
+
print("a single message")
|
|
74
|
+
p = publisher()
|
|
75
|
+
result = await p.publish({"content": {"run_id": "abc", "status": "launched"}})
|
|
76
|
+
sent = p._sns_client.published[0]
|
|
77
|
+
check("it publishes", len(p._sns_client.published) == 1)
|
|
78
|
+
check("no Id, which publish does not accept", "Id" not in sent)
|
|
79
|
+
check("the body travels", json.loads(sent["Message"])["run_id"] == "abc")
|
|
80
|
+
check("returns the message id", result == "m1")
|
|
81
|
+
|
|
82
|
+
print("\na single message with attributes and subject")
|
|
83
|
+
p = publisher()
|
|
84
|
+
await p.publish({
|
|
85
|
+
"content": {"x": 1},
|
|
86
|
+
"attributes": {"service": "business"},
|
|
87
|
+
"subject": "hello",
|
|
88
|
+
})
|
|
89
|
+
sent = p._sns_client.published[0]
|
|
90
|
+
check("subject", sent.get("Subject") == "hello")
|
|
91
|
+
check("attributes", "MessageAttributes" in sent)
|
|
92
|
+
|
|
93
|
+
print("\na batch")
|
|
94
|
+
p = publisher()
|
|
95
|
+
ok, failed = await p.publish([{"content": {"n": i}} for i in range(188)])
|
|
96
|
+
check("split into tens", len(p._sns_client.batches) == 19,
|
|
97
|
+
f"batches={len(p._sns_client.batches)}")
|
|
98
|
+
check("none over the limit", all(len(b) <= MAX_BATCH_ENTRIES for b in p._sns_client.batches))
|
|
99
|
+
check("every entry has an Id", all("Id" in e for b in p._sns_client.batches for e in b))
|
|
100
|
+
check("ids unique inside each call",
|
|
101
|
+
all(len({e["Id"] for e in b}) == len(b) for b in p._sns_client.batches))
|
|
102
|
+
check("all reported published", len(ok) == 188 and not failed)
|
|
103
|
+
|
|
104
|
+
print("\na batch of one still goes as a batch")
|
|
105
|
+
p = publisher()
|
|
106
|
+
await p.publish([{"content": {"n": 1}}])
|
|
107
|
+
check("one call", len(p._sns_client.batches) == 1)
|
|
108
|
+
check("nothing through publish()", not p._sns_client.published)
|
|
109
|
+
|
|
110
|
+
print("\na message with no content is refused, not sent")
|
|
111
|
+
p = publisher()
|
|
112
|
+
try:
|
|
113
|
+
await p.publish({"attributes": {"service": "business"}})
|
|
114
|
+
check("raises", False)
|
|
115
|
+
except ValueError:
|
|
116
|
+
check("raises", True)
|
|
117
|
+
check("nothing published", not p._sns_client.published)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
asyncio.run(main())
|
|
121
|
+
|
|
122
|
+
if failures:
|
|
123
|
+
print(f"\n{len(failures)} failed: {failures}")
|
|
124
|
+
raise SystemExit(1)
|
|
125
|
+
print("\nall good")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/api/auth_middleware.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/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
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/context/state_validator.py
RENAMED
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/database/database_proxy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/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
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/invoker/lambda_invoker.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/__init__.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/base.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/fetcher.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/lambda_standalone/handler.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/model_index_sync/__init__.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/model_index_sync/base.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/model_query/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/monitoring/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/permissions/__init__.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper/permissions/catalog.py
RENAMED
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/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
|
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
{aws_python_helper-1.9.0 → aws_python_helper-1.9.2}/aws_python_helper.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|