nui-python-shared-utils 2.3__py3-none-any.whl → 2.4.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nui-python-shared-utils
3
- Version: 2.3
3
+ Version: 2.4.1
4
4
  Summary: Shared Python utilities for AWS Lambda, CLI tools, and agents with Slack, Elasticsearch, and monitoring integrations
5
5
  Home-page: https://github.com/nuimarkets/nui-python-shared-utils
6
6
  Author: NUI Markets
@@ -36,7 +36,6 @@ Classifier: Intended Audience :: Developers
36
36
  Classifier: License :: OSI Approved :: MIT License
37
37
  Classifier: Operating System :: OS Independent
38
38
  Classifier: Programming Language :: Python :: 3
39
- Classifier: Programming Language :: Python :: 3.9
40
39
  Classifier: Programming Language :: Python :: 3.10
41
40
  Classifier: Programming Language :: Python :: 3.11
42
41
  Classifier: Programming Language :: Python :: 3.12
@@ -45,7 +44,7 @@ Classifier: Topic :: System :: Monitoring
45
44
  Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
46
45
  Classifier: Environment :: Console
47
46
  Classifier: Framework :: AWS CDK
48
- Requires-Python: >=3.9
47
+ Requires-Python: >=3.10
49
48
  Description-Content-Type: text/markdown
50
49
  License-File: LICENSE
51
50
  Requires-Dist: boto3>=1.20.0
@@ -102,7 +101,7 @@ Dynamic: requires-python
102
101
  # NUI Python Shared Utilities
103
102
 
104
103
  [![PyPI version](https://badge.fury.io/py/nui-python-shared-utils.svg)](https://badge.fury.io/py/nui-python-shared-utils)
105
- [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
104
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
106
105
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
107
106
 
108
107
  Production-ready shared Python utilities for AWS Lambda functions, CLI tools, and agents. Provides standardized integrations for Slack, Elasticsearch, database, and monitoring. Built and battle-tested on the NUI platform with sensible defaults configurable for any environment.
@@ -1,4 +1,4 @@
1
- nui_python_shared_utils-2.3.dist-info/licenses/LICENSE,sha256=vGe2mC5yLUb8toYlY3T36ZwCB5zQUW5hlCtEMiqokhM,1071
1
+ nui_python_shared_utils-2.4.1.dist-info/licenses/LICENSE,sha256=vGe2mC5yLUb8toYlY3T36ZwCB5zQUW5hlCtEMiqokhM,1071
2
2
  nui_shared_utils/__init__.py,sha256=wbm10x7THNbrCBGClWiWSVkTNxcBKcHZ-HjYpRQBFrk,13354
3
3
  nui_shared_utils/base_client.py,sha256=I1lKQGhrKyvujV2zps0TrtEdPDqMCwRQaIh6ceGONXQ,11016
4
4
  nui_shared_utils/cli.py,sha256=JJpSoQWKvAz4b8cO30yFNi5vY9jmqrCHzbFpvrVTkbU,8747
@@ -12,23 +12,23 @@ nui_shared_utils/jwt_auth.py,sha256=2Ag1zZKxd2R8QBz3aQA4h8OtKHQvUVKrjUp6lXpJxJU,
12
12
  nui_shared_utils/lambda_helpers.py,sha256=psHVotpmOfnmyQCoOt4MSIEj7VwWcy6gZM3vYSZwjOk,3041
13
13
  nui_shared_utils/llm.py,sha256=adNUO8Qbeb3__GvpROxWSUERkpiazKiGJFE5xzU5eZ0,8351
14
14
  nui_shared_utils/log_processors.py,sha256=x5gz1LEkbmoMCZ3ZB6q-mbn26dSzwh1trz4wSkBGxqk,5538
15
- nui_shared_utils/powertools_helpers.py,sha256=R4awhoo0w0niL662DMZvNa5sDjjP8Vh6m0pSpnOD1aU,12286
15
+ nui_shared_utils/powertools_helpers.py,sha256=DGM6L0nBkhRpcQvj58s15jVfB3IH_4274aAoyW2Xi1o,13030
16
16
  nui_shared_utils/secrets_helper.py,sha256=_jQkMWzjayZ8vvyHG2yuuxur-SQYUUONfcsZ0MF8qOw,7025
17
17
  nui_shared_utils/slack_client.py,sha256=jvkLeBMA8WHOqdRzCEpG42FfBlMeWue8bZ1g1ZxF-UI,40304
18
18
  nui_shared_utils/slack_formatter.py,sha256=QT9VXApE0q09n_PmEVvaLCSfLW24vmowlCXF3Dzimfk,10850
19
19
  nui_shared_utils/snowflake_client.py,sha256=e3jH6_2mMqbtP1TE8-mUFFYrfGW9eqUPT5tlcgeCqx8,16181
20
- nui_shared_utils/timezone.py,sha256=gTiSK5NUG0Z8UY_AsB4ktIzLrZ0wwTXtdTUH-Npdvik,3837
20
+ nui_shared_utils/timezone.py,sha256=m-Ilx9FI2Bwv-GZOZy71N_S94g26UK68jP8QEEKNw74,3867
21
21
  nui_shared_utils/utils.py,sha256=gOpw80tZGC24QsyesR8EySRODY-TFXG8cXUvggPBsRI,8184
22
22
  nui_shared_utils/logging/__init__.py,sha256=gVC853q3ja4RhcBVbf5jKO10lFX4upfsTvkKZx4wu54,1805
23
- nui_shared_utils/logging/binding.py,sha256=I5VNmtf4U2yt54aS4F0Djw4u22mfjwCpWvORUnJNkPU,13577
23
+ nui_shared_utils/logging/binding.py,sha256=FJhC2RjzhTczWz43Bk1HiQGsorSVFVHvmNmPhbwlW78,13495
24
24
  nui_shared_utils/logging/fields.py,sha256=7jhBdyEXAJod61aKPCk68idECTAV-_BNjiABp9IRFZo,11194
25
25
  nui_shared_utils/logging/redaction.py,sha256=t-EtNhR1nK6IOae70GnieHxn_36_jYuuta32T1dMlP8,6928
26
26
  nui_shared_utils/slack_setup/__init__.py,sha256=OElyS3xk4F_YKH5uUUTDpN0ah1dOO3e52muIPjAMPW8,320
27
27
  nui_shared_utils/slack_setup/channel_creator.py,sha256=0gyCBIS0EC96SVn1Z2dD4Fpzk0xNdHSWyiCxoUQIUe8,10667
28
28
  nui_shared_utils/slack_setup/channel_definitions.py,sha256=atfz5ZhpqefOeLh1gShbWd-TLzgjPmhv95bfuTdmZog,5676
29
29
  nui_shared_utils/slack_setup/setup_helpers.py,sha256=pzzXMs12GI9sdZttWeYzgLPgC0xqPz7ZLHM1GUPNNXc,7219
30
- nui_python_shared_utils-2.3.dist-info/METADATA,sha256=Ma366Cqx3pp_PW7xaSA-n1UmeniBgjvShEwb96vdOgc,22688
31
- nui_python_shared_utils-2.3.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
32
- nui_python_shared_utils-2.3.dist-info/entry_points.txt,sha256=TrJ3Z4kz3oXfy6InXn20jHu7rnTwo-4EA0KRFX3fkL0,66
33
- nui_python_shared_utils-2.3.dist-info/top_level.txt,sha256=YMRu5cnn3hxHoYq9wNvaI9atVHnTNVdswO5_cQSfnJI,17
34
- nui_python_shared_utils-2.3.dist-info/RECORD,,
30
+ nui_python_shared_utils-2.4.1.dist-info/METADATA,sha256=YIXzCX1TeKM2_D2zeukX6RcBLtszwORIH2_hc8O5gUM,22643
31
+ nui_python_shared_utils-2.4.1.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
32
+ nui_python_shared_utils-2.4.1.dist-info/entry_points.txt,sha256=TrJ3Z4kz3oXfy6InXn20jHu7rnTwo-4EA0KRFX3fkL0,66
33
+ nui_python_shared_utils-2.4.1.dist-info/top_level.txt,sha256=YMRu5cnn3hxHoYq9wNvaI9atVHnTNVdswO5_cQSfnJI,17
34
+ nui_python_shared_utils-2.4.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (84.0.0)
2
+ Generator: setuptools (84.2.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -306,7 +306,6 @@ def log_exception(binder: Any, exc: BaseException, message: str) -> None:
306
306
  extra={
307
307
  F.ERROR_TYPE: type(exc).__name__,
308
308
  F.ERROR_MESSAGE: str(exc),
309
- # 3-arg form for Python 3.9 compatibility (single-arg added in 3.10).
310
309
  F.ERROR_STACK: "".join(traceback.format_exception(type(exc), exc, exc.__traceback__)),
311
310
  },
312
311
  )
@@ -162,6 +162,7 @@ def powertools_handler(
162
162
  slack_alert_channel: Optional[str] = None,
163
163
  slack_account_names: Optional[Dict[str, str]] = None,
164
164
  slack_account_names_config: Optional[str] = None,
165
+ reraise_exceptions: bool = False,
165
166
  ):
166
167
  """
167
168
  Decorator for Lambda handlers with logging, metrics, and error handling.
@@ -175,6 +176,7 @@ def powertools_handler(
175
176
  - Optional metrics.log_metrics integration (if metrics_namespace provided)
176
177
  - Structured exception logging with traceback
177
178
  - Optional Slack alerts on failures (if slack_alert_channel provided)
179
+ - Optional exception re-raising for event sources that use Lambda failure semantics
178
180
  - Graceful degradation if Slack client unavailable
179
181
  - Proper Lambda error response formatting
180
182
 
@@ -190,6 +192,11 @@ def powertools_handler(
190
192
  Values loaded from this file are used as defaults, but any keys
191
193
  provided in ``slack_account_names`` take precedence and override
192
194
  the YAML-loaded values.
195
+ reraise_exceptions: Re-raise handler exceptions after logging and Slack
196
+ alerting. Enable this for event sources such as Kinesis, DynamoDB
197
+ Streams, SNS, S3, and EventBridge that rely on a raised exception to
198
+ record a failed invocation and apply their retry or failure handling.
199
+ Defaults to False to preserve the existing 500 response behavior.
193
200
 
194
201
  Returns:
195
202
  Decorator function for Lambda handlers
@@ -214,13 +221,14 @@ def powertools_handler(
214
221
  for API Gateway, ``{"batchItemFailures": [...]}`` for an SQS mapping with
215
222
  ``ReportBatchItemFailures``.
216
223
 
217
- On exception, returns ``{"statusCode": 500, "body": "Internal Server Error"}``,
218
- except for SQS events, where the exception is re-raised after logging and
219
- alerting. A returned value tells the SQS mapping the batch succeeded (with
220
- ``ReportBatchItemFailures``, a response without ``batchItemFailures`` means
221
- every record did), so the 500 dict would delete the batch. Re-raising leaves
222
- it on the queue for redelivery, and in the DLQ after ``maxReceiveCount``
223
- when the queue has a redrive policy.
224
+ On exception, returns ``{"statusCode": 500, "body": "Internal Server Error"}``
225
+ by default. Set ``reraise_exceptions=True`` to re-raise after logging and
226
+ alerting when the event source relies on Lambda failure semantics. SQS events
227
+ are always re-raised, regardless of this option: a returned value tells the
228
+ SQS mapping the batch succeeded (with ``ReportBatchItemFailures``, a response
229
+ without ``batchItemFailures`` means every record did), so the 500 dict would
230
+ delete the batch. Re-raising leaves it on the queue for redelivery, and in the
231
+ DLQ after ``maxReceiveCount`` when the queue has a redrive policy.
224
232
  """
225
233
 
226
234
  def decorator(func: Callable) -> Callable:
@@ -297,8 +305,9 @@ def powertools_handler(
297
305
  except Exception as slack_error:
298
306
  logger.warning("Failed to send Slack alert: %s", slack_error)
299
307
 
300
- # Re-raise for SQS so the batch stays on the queue; see the Note above.
301
- if is_sqs:
308
+ # Re-raise for SQS so the batch stays on the queue, or when the caller
309
+ # opts into Lambda failure semantics; see the Note above.
310
+ if is_sqs or reraise_exceptions:
302
311
  raise
303
312
 
304
313
  # Return proper Lambda error response
@@ -13,8 +13,8 @@ from zoneinfo import ZoneInfo
13
13
  # Supported timezones
14
14
  NZ_TZ = ZoneInfo("Pacific/Auckland") # Primary timezone
15
15
  AUS_TZ = ZoneInfo("Australia/Sydney")
16
- US_EAST_TZ = ZoneInfo("US/Eastern")
17
- US_WEST_TZ = ZoneInfo("US/Pacific")
16
+ US_EAST_TZ = ZoneInfo("America/New_York")
17
+ US_WEST_TZ = ZoneInfo("America/Los_Angeles")
18
18
  EUR_TZ = ZoneInfo("Europe/London")
19
19
 
20
20
 
@@ -115,7 +115,7 @@ def get_timezone_options() -> List[Tuple[str, str]]:
115
115
  return [
116
116
  ("nz", "New Zealand (Pacific/Auckland)"),
117
117
  ("aus", "Australia (Australia/Sydney)"),
118
- ("us_east", "US Eastern (US/Eastern)"),
119
- ("us_west", "US Pacific (US/Pacific)"),
118
+ ("us_east", "US Eastern (America/New_York)"),
119
+ ("us_west", "US Pacific (America/Los_Angeles)"),
120
120
  ("eur", "Europe (Europe/London)"),
121
121
  ]