reach_commons 0.18.26__tar.gz → 0.18.27__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.
- {reach_commons-0.18.26 → reach_commons-0.18.27}/PKG-INFO +1 -1
- {reach_commons-0.18.26 → reach_commons-0.18.27}/pyproject.toml +1 -1
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/sqs.py +85 -48
- {reach_commons-0.18.26 → reach_commons-0.18.27}/README.md +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/__init__.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/app_logging/__init__.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/app_logging/http_logger.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/app_logging/log_deprecated_endpoints.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/app_logging/logger.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/app_logging/logging_config.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/clients/__init__.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/clients/event_processor.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/clients/hubspot.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/clients/outscraper.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/clients/reach_data_bridge.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/clients/reach_ops_api.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/mongo/__init__.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/mongo/customer_persistence.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/mongo/customer_persistence_async.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/mongo/validation/__init__.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/__init__.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/commons.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/dynamo_db.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/exceptions.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/firehose.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/kms.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_aws/s3.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/reach_base_model.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/redis_manager.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/sms_smart_encoding.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/utils.py +0 -0
- {reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/validations.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# isort .; black .; poetry build; poetry publish
|
|
2
2
|
[tool.poetry]
|
|
3
3
|
name = "reach_commons"
|
|
4
|
-
version = "0.18.
|
|
4
|
+
version = "0.18.27"
|
|
5
5
|
description = "Reach Commons is a versatile utility library designed to streamline and enhance development workflows within the Reach ecosystem."
|
|
6
6
|
authors = ["Engineering <engineering@getreach.ai>"]
|
|
7
7
|
license = "MIT"
|
|
@@ -146,38 +146,61 @@ class SQSClient(BaseSQSClient):
|
|
|
146
146
|
|
|
147
147
|
return True
|
|
148
148
|
|
|
149
|
-
def
|
|
149
|
+
def get_queue_metrics(self) -> dict:
|
|
150
|
+
"""
|
|
151
|
+
Retorna métricas aproximadas da fila SQS.
|
|
152
|
+
|
|
153
|
+
{
|
|
154
|
+
"visible": int,
|
|
155
|
+
"in_flight": int,
|
|
156
|
+
"delayed": int,
|
|
157
|
+
"oldest_age_seconds": int,
|
|
158
|
+
}
|
|
159
|
+
"""
|
|
150
160
|
try:
|
|
151
161
|
resp = self.client.get_queue_attributes(
|
|
152
162
|
QueueUrl=self.topic_name,
|
|
153
163
|
AttributeNames=[
|
|
154
|
-
"ApproximateNumberOfMessages",
|
|
155
|
-
"ApproximateNumberOfMessagesNotVisible",
|
|
156
|
-
"ApproximateNumberOfMessagesDelayed",
|
|
164
|
+
"ApproximateNumberOfMessages", # visible
|
|
165
|
+
"ApproximateNumberOfMessagesNotVisible", # in-flight
|
|
166
|
+
"ApproximateNumberOfMessagesDelayed", # delayed
|
|
167
|
+
"ApproximateAgeOfOldestMessage",
|
|
157
168
|
],
|
|
158
169
|
)
|
|
159
|
-
visible = int(resp["Attributes"].get("ApproximateNumberOfMessages", 0))
|
|
160
|
-
in_flight = int(
|
|
161
|
-
resp["Attributes"].get("ApproximateNumberOfMessagesNotVisible", 0)
|
|
162
|
-
)
|
|
163
|
-
delayed = int(
|
|
164
|
-
resp["Attributes"].get("ApproximateNumberOfMessagesDelayed", 0)
|
|
165
|
-
)
|
|
166
170
|
|
|
167
|
-
|
|
171
|
+
attrs = resp.get("Attributes", {})
|
|
172
|
+
|
|
173
|
+
visible = int(attrs.get("ApproximateNumberOfMessages", 0))
|
|
174
|
+
in_flight = int(attrs.get("ApproximateNumberOfMessagesNotVisible", 0))
|
|
175
|
+
delayed = int(attrs.get("ApproximateNumberOfMessagesDelayed", 0))
|
|
176
|
+
oldest_age_seconds = int(attrs.get("ApproximateAgeOfOldestMessage", 0))
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
"visible": visible,
|
|
180
|
+
"in_flight": in_flight,
|
|
181
|
+
"delayed": delayed,
|
|
182
|
+
"oldest_age_seconds": oldest_age_seconds,
|
|
183
|
+
}
|
|
184
|
+
|
|
168
185
|
except ClientError as exc:
|
|
169
186
|
self.logger.error(
|
|
170
187
|
"error_fetching_queue_attributes, topic_name=%s, error=%s",
|
|
171
188
|
self.topic_name,
|
|
172
189
|
str(exc),
|
|
173
190
|
)
|
|
174
|
-
|
|
175
|
-
return
|
|
191
|
+
|
|
192
|
+
return {
|
|
193
|
+
"visible": 0,
|
|
194
|
+
"in_flight": 0,
|
|
195
|
+
"delayed": 0,
|
|
196
|
+
"oldest_age_seconds": 0,
|
|
197
|
+
}
|
|
176
198
|
|
|
177
199
|
def publish_with_capacity_guard(
|
|
178
200
|
self,
|
|
179
201
|
message_data: dict,
|
|
180
|
-
|
|
202
|
+
max_visible_capacity: int,
|
|
203
|
+
max_total_capacity: int = None,
|
|
181
204
|
delay_seconds: int = 60,
|
|
182
205
|
message_attributes: dict = None,
|
|
183
206
|
) -> dict:
|
|
@@ -185,44 +208,56 @@ class SQSClient(BaseSQSClient):
|
|
|
185
208
|
Attempts to publish a message while enforcing an approximate queue capacity limit.
|
|
186
209
|
|
|
187
210
|
Behavior:
|
|
188
|
-
- If the queue is below `
|
|
189
|
-
|
|
211
|
+
- If the queue is below `max_visible_capacity` (and optional `max_total_capacity`),
|
|
212
|
+
the message is published normally.
|
|
213
|
+
- If the queue is at or above the threshold(s), the message is NOT published.
|
|
190
214
|
|
|
191
215
|
Returns a dict with:
|
|
192
|
-
- posted: bool
|
|
193
|
-
- visible_count: int
|
|
194
|
-
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Result = sqs.publish_with_capacity_guard(
|
|
200
|
-
message_data={"foo": "bar"},
|
|
201
|
-
max_capacity=100_000,
|
|
202
|
-
delay_seconds=30,
|
|
203
|
-
message_attributes={"service_name": "TestClient"},
|
|
204
|
-
)
|
|
205
|
-
|
|
206
|
-
if not Result["posted"]:
|
|
207
|
-
print("Queue is over capacity:", Result)
|
|
216
|
+
- posted: bool
|
|
217
|
+
- visible_count: int
|
|
218
|
+
- in_flight_count: int
|
|
219
|
+
- delayed_count: int
|
|
220
|
+
- oldest_age_seconds: int
|
|
221
|
+
- max_visible_capacity: int
|
|
222
|
+
- max_total_capacity: int | None
|
|
208
223
|
"""
|
|
209
|
-
(
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
224
|
+
metrics = self.get_queue_metrics()
|
|
225
|
+
visible = metrics["visible"]
|
|
226
|
+
in_flight = metrics["in_flight"]
|
|
227
|
+
delayed = metrics["delayed"]
|
|
228
|
+
oldest_age_seconds = metrics["oldest_age_seconds"]
|
|
229
|
+
|
|
230
|
+
total_active = visible + in_flight
|
|
231
|
+
|
|
232
|
+
over_visible = visible >= max_visible_capacity
|
|
233
|
+
over_total = (
|
|
234
|
+
max_total_capacity is not None and total_active >= max_total_capacity
|
|
235
|
+
)
|
|
214
236
|
|
|
215
|
-
if
|
|
237
|
+
if over_visible or over_total:
|
|
216
238
|
self.logger.warning(
|
|
217
|
-
|
|
239
|
+
(
|
|
240
|
+
"queue_over_capacity, topic_name=%s, "
|
|
241
|
+
"visible=%s, in_flight=%s, delayed=%s, oldest_age_seconds=%s, "
|
|
242
|
+
"total_active=%s, max_visible_capacity=%s, max_total_capacity=%s"
|
|
243
|
+
),
|
|
218
244
|
self.topic_name,
|
|
219
|
-
|
|
220
|
-
|
|
245
|
+
visible,
|
|
246
|
+
in_flight,
|
|
247
|
+
delayed,
|
|
248
|
+
oldest_age_seconds,
|
|
249
|
+
total_active,
|
|
250
|
+
max_visible_capacity,
|
|
251
|
+
max_total_capacity,
|
|
221
252
|
)
|
|
222
253
|
return {
|
|
223
254
|
"posted": False,
|
|
224
|
-
"visible_count":
|
|
225
|
-
"
|
|
255
|
+
"visible_count": visible,
|
|
256
|
+
"in_flight_count": in_flight,
|
|
257
|
+
"delayed_count": delayed,
|
|
258
|
+
"oldest_age_seconds": oldest_age_seconds,
|
|
259
|
+
"max_visible_capacity": max_visible_capacity,
|
|
260
|
+
"max_total_capacity": max_total_capacity,
|
|
226
261
|
}
|
|
227
262
|
|
|
228
263
|
self.publish(
|
|
@@ -233,10 +268,12 @@ class SQSClient(BaseSQSClient):
|
|
|
233
268
|
|
|
234
269
|
return {
|
|
235
270
|
"posted": True,
|
|
236
|
-
"visible_count":
|
|
237
|
-
"in_flight_count":
|
|
238
|
-
"delayed_count":
|
|
239
|
-
"
|
|
271
|
+
"visible_count": visible,
|
|
272
|
+
"in_flight_count": in_flight,
|
|
273
|
+
"delayed_count": delayed,
|
|
274
|
+
"oldest_age_seconds": oldest_age_seconds,
|
|
275
|
+
"max_visible_capacity": max_visible_capacity,
|
|
276
|
+
"max_total_capacity": max_total_capacity,
|
|
240
277
|
}
|
|
241
278
|
|
|
242
279
|
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{reach_commons-0.18.26 → reach_commons-0.18.27}/reach_commons/mongo/customer_persistence_async.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|