nui-lambda-shared-utils 1.2.0__tar.gz → 1.2.1__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.
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/PKG-INFO +1 -1
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/__init__.py +3 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/jwt_auth.py +60 -1
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_jwt_auth.py +112 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/.editorconfig +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/.github/workflows/ci.yml +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/.github/workflows/publish.yml +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/.github/workflows/test.yml +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/.markdownlint-cli2.yaml +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/CLAUDE.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/CONTRIBUTING.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/LICENSE +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/MANIFEST.in +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/README.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/README.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/development/testing.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/getting-started/configuration.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/getting-started/installation.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/getting-started/quickstart.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/cli-tools.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/elasticsearch-integration.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/jwt-authentication.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/lambda-utilities.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/log-processing.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/powertools-integration.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/shared-types.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/slack-integration.md +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/mypy.ini +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/base_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/cli.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/cloudwatch_metrics.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/config.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/db_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/error_handler.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/es_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/es_query_builder.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/lambda_helpers.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/log_processors.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/powertools_helpers.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/secrets_helper.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/slack_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/slack_formatter.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/slack_setup/__init__.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/slack_setup/channel_creator.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/slack_setup/channel_definitions.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/slack_setup/setup_helpers.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/timezone.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/utils.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils.egg-info/SOURCES.txt +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/pyproject.toml +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/pytest.ini +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/requirements-test.txt +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/setup.cfg +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/setup.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/__init__.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_aws_utils.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_base_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_cloudwatch_metrics.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_config.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_db_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_error_handler.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_es_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_es_query_builder.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_lambda_helpers.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_log_processors.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_powertools_helpers.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_secrets_helper.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_slack_client.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_slack_formatter.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_timezone.py +0 -0
- {nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nui-lambda-shared-utils
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Enterprise-grade utilities for AWS Lambda functions with Slack, Elasticsearch, and monitoring integrations
|
|
5
5
|
Home-page: https://github.com/nuimarkets/nui-lambda-shared-utils
|
|
6
6
|
Author: NUI Markets
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/__init__.py
RENAMED
|
@@ -137,6 +137,7 @@ try:
|
|
|
137
137
|
from .jwt_auth import (
|
|
138
138
|
validate_jwt,
|
|
139
139
|
require_auth,
|
|
140
|
+
check_auth,
|
|
140
141
|
get_jwt_public_key,
|
|
141
142
|
JWTValidationError,
|
|
142
143
|
AuthenticationError,
|
|
@@ -144,6 +145,7 @@ try:
|
|
|
144
145
|
except ImportError:
|
|
145
146
|
validate_jwt = None # type: ignore
|
|
146
147
|
require_auth = None # type: ignore
|
|
148
|
+
check_auth = None # type: ignore
|
|
147
149
|
get_jwt_public_key = None # type: ignore
|
|
148
150
|
JWTValidationError = None # type: ignore
|
|
149
151
|
AuthenticationError = None # type: ignore
|
|
@@ -243,6 +245,7 @@ __all__ = [
|
|
|
243
245
|
# JWT authentication
|
|
244
246
|
"validate_jwt",
|
|
245
247
|
"require_auth",
|
|
248
|
+
"check_auth",
|
|
246
249
|
"get_jwt_public_key",
|
|
247
250
|
"JWTValidationError",
|
|
248
251
|
"AuthenticationError",
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/jwt_auth.py
RENAMED
|
@@ -9,10 +9,12 @@ Install: pip install nui-lambda-shared-utils[jwt]
|
|
|
9
9
|
|
|
10
10
|
import os
|
|
11
11
|
import json
|
|
12
|
+
import re
|
|
12
13
|
import base64
|
|
13
14
|
import time
|
|
14
15
|
import logging
|
|
15
|
-
from typing import TYPE_CHECKING, Optional
|
|
16
|
+
from typing import TYPE_CHECKING, AbstractSet, Any, Dict, Optional, Tuple
|
|
17
|
+
from urllib.parse import unquote
|
|
16
18
|
|
|
17
19
|
from .secrets_helper import get_secret
|
|
18
20
|
|
|
@@ -216,3 +218,60 @@ def require_auth(event: dict, secret_name: Optional[str] = None) -> dict:
|
|
|
216
218
|
return validate_jwt(token, public_key)
|
|
217
219
|
except JWTValidationError as e:
|
|
218
220
|
raise AuthenticationError(f"Authentication failed: {e}") from e
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
def _normalize_path(path: str) -> str:
|
|
224
|
+
"""Normalize a URL path for safe comparison.
|
|
225
|
+
|
|
226
|
+
URL-decodes, collapses duplicate slashes, ensures a single leading slash,
|
|
227
|
+
and strips any trailing slash (except for root "/").
|
|
228
|
+
"""
|
|
229
|
+
path = unquote(path)
|
|
230
|
+
path = re.sub(r"/+", "/", path)
|
|
231
|
+
return "/" + path.strip("/") if path.strip("/") else "/"
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def check_auth(
|
|
235
|
+
event: dict,
|
|
236
|
+
public_paths: AbstractSet[str] = frozenset(),
|
|
237
|
+
secret_name: Optional[str] = None,
|
|
238
|
+
) -> Tuple[Optional[Dict[str, Any]], Optional[Dict[str, Any]]]:
|
|
239
|
+
"""Check JWT authentication on an API Gateway event, skipping public paths.
|
|
240
|
+
|
|
241
|
+
Combines path normalization, public-path bypass, JWT validation,
|
|
242
|
+
and a standard JSON:API 401 error response in one call.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
event: API Gateway Lambda proxy integration event.
|
|
246
|
+
public_paths: Set of normalized paths that skip auth (e.g. {"/health"}).
|
|
247
|
+
secret_name: Optional Secrets Manager secret name for the public key.
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
(claims, None) on success — claims is the decoded JWT dict,
|
|
251
|
+
or None if the path is public.
|
|
252
|
+
(None, response) on auth failure — response is a 401 dict
|
|
253
|
+
ready to return from your Lambda handler.
|
|
254
|
+
"""
|
|
255
|
+
raw_path = event.get("path") or event.get("rawPath") or ""
|
|
256
|
+
if _normalize_path(raw_path) in public_paths:
|
|
257
|
+
return None, None
|
|
258
|
+
|
|
259
|
+
try:
|
|
260
|
+
claims = require_auth(event, secret_name=secret_name)
|
|
261
|
+
return claims, None
|
|
262
|
+
except AuthenticationError as e:
|
|
263
|
+
log.warning("Authentication failed: %s", e)
|
|
264
|
+
return None, {
|
|
265
|
+
"statusCode": 401,
|
|
266
|
+
"headers": {
|
|
267
|
+
"Content-Type": "application/json",
|
|
268
|
+
"Access-Control-Allow-Origin": "*",
|
|
269
|
+
},
|
|
270
|
+
"body": json.dumps({
|
|
271
|
+
"errors": [{
|
|
272
|
+
"status": "401",
|
|
273
|
+
"title": "Unauthorized",
|
|
274
|
+
"detail": "Authentication required",
|
|
275
|
+
}]
|
|
276
|
+
}),
|
|
277
|
+
}
|
|
@@ -15,10 +15,12 @@ import rsa as rsa_lib
|
|
|
15
15
|
from nui_lambda_shared_utils.jwt_auth import (
|
|
16
16
|
validate_jwt,
|
|
17
17
|
require_auth,
|
|
18
|
+
check_auth,
|
|
18
19
|
get_jwt_public_key,
|
|
19
20
|
JWTValidationError,
|
|
20
21
|
AuthenticationError,
|
|
21
22
|
_base64url_decode,
|
|
23
|
+
_normalize_path,
|
|
22
24
|
)
|
|
23
25
|
|
|
24
26
|
|
|
@@ -274,3 +276,113 @@ class TestGetJwtPublicKey:
|
|
|
274
276
|
|
|
275
277
|
with pytest.raises(JWTValidationError, match="Field 'TOKEN_PUBLIC_KEY' not found"):
|
|
276
278
|
get_jwt_public_key(secret_name="test/jwt-key")
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# ---------------------------------------------------------------------------
|
|
282
|
+
# _normalize_path tests
|
|
283
|
+
# ---------------------------------------------------------------------------
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@pytest.mark.unit
|
|
287
|
+
class TestNormalizePath:
|
|
288
|
+
def test_simple_path(self):
|
|
289
|
+
assert _normalize_path("/health") == "/health"
|
|
290
|
+
|
|
291
|
+
def test_strips_trailing_slash(self):
|
|
292
|
+
assert _normalize_path("/health/") == "/health"
|
|
293
|
+
|
|
294
|
+
def test_ensures_leading_slash(self):
|
|
295
|
+
assert _normalize_path("health") == "/health"
|
|
296
|
+
|
|
297
|
+
def test_collapses_duplicate_slashes(self):
|
|
298
|
+
assert _normalize_path("//health///check//") == "/health/check"
|
|
299
|
+
|
|
300
|
+
def test_url_decodes(self):
|
|
301
|
+
assert _normalize_path("/he%61lth") == "/health"
|
|
302
|
+
|
|
303
|
+
def test_root_path(self):
|
|
304
|
+
assert _normalize_path("/") == "/"
|
|
305
|
+
|
|
306
|
+
def test_empty_string(self):
|
|
307
|
+
assert _normalize_path("") == "/"
|
|
308
|
+
|
|
309
|
+
def test_full_api_gateway_path(self):
|
|
310
|
+
assert _normalize_path("/v4/fields/static-lists") == "/v4/fields/static-lists"
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
# ---------------------------------------------------------------------------
|
|
314
|
+
# check_auth tests
|
|
315
|
+
# ---------------------------------------------------------------------------
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
@pytest.mark.unit
|
|
319
|
+
class TestCheckAuth:
|
|
320
|
+
def test_public_path_skips_auth(self):
|
|
321
|
+
"""Public paths return (None, None) without checking JWT."""
|
|
322
|
+
event = {"path": "/health", "headers": {}}
|
|
323
|
+
claims, error = check_auth(event, public_paths={"/health"})
|
|
324
|
+
assert claims is None
|
|
325
|
+
assert error is None
|
|
326
|
+
|
|
327
|
+
def test_public_path_with_trailing_slash(self):
|
|
328
|
+
"""Public path matching normalizes trailing slashes."""
|
|
329
|
+
event = {"path": "/health/", "headers": {}}
|
|
330
|
+
claims, error = check_auth(event, public_paths={"/health"})
|
|
331
|
+
assert claims is None
|
|
332
|
+
assert error is None
|
|
333
|
+
|
|
334
|
+
def test_non_public_path_without_token_returns_401(self):
|
|
335
|
+
"""Missing auth on protected path returns 401 response."""
|
|
336
|
+
event = {"path": "/static-lists", "headers": {}}
|
|
337
|
+
claims, error = check_auth(event, public_paths={"/health"})
|
|
338
|
+
assert claims is None
|
|
339
|
+
assert error is not None
|
|
340
|
+
assert error["statusCode"] == 401
|
|
341
|
+
body = json.loads(error["body"])
|
|
342
|
+
assert body["errors"][0]["status"] == "401"
|
|
343
|
+
assert body["errors"][0]["detail"] == "Authentication required"
|
|
344
|
+
|
|
345
|
+
@pytest.mark.usefixtures("mock_jwt_secret")
|
|
346
|
+
def test_valid_auth_returns_claims(self, rsa_keypair):
|
|
347
|
+
"""Valid JWT returns (claims, None)."""
|
|
348
|
+
private_key, _, _ = rsa_keypair
|
|
349
|
+
token = _sign_jwt(private_key, {"sub": "user1", "exp": time.time() + 3600})
|
|
350
|
+
event = {"path": "/static-lists", "headers": {"Authorization": f"Bearer {token}"}}
|
|
351
|
+
|
|
352
|
+
with patch.dict("os.environ", {"JWT_PUBLIC_KEY_SECRET": "test/jwt-key"}):
|
|
353
|
+
claims, error = check_auth(event, public_paths={"/health"})
|
|
354
|
+
|
|
355
|
+
assert error is None
|
|
356
|
+
assert claims["sub"] == "user1"
|
|
357
|
+
|
|
358
|
+
@pytest.mark.usefixtures("mock_jwt_secret")
|
|
359
|
+
def test_invalid_token_returns_401(self):
|
|
360
|
+
"""Invalid JWT returns 401 response, not an exception."""
|
|
361
|
+
event = {"path": "/static-lists", "headers": {"Authorization": "Bearer bad.token.here"}}
|
|
362
|
+
|
|
363
|
+
with patch.dict("os.environ", {"JWT_PUBLIC_KEY_SECRET": "test/jwt-key"}):
|
|
364
|
+
claims, error = check_auth(event, public_paths={"/health"})
|
|
365
|
+
|
|
366
|
+
assert claims is None
|
|
367
|
+
assert error["statusCode"] == 401
|
|
368
|
+
|
|
369
|
+
def test_path_traversal_does_not_bypass_auth(self):
|
|
370
|
+
"""Crafted paths like /anything/health don't bypass auth."""
|
|
371
|
+
event = {"path": "/anything/health", "headers": {}}
|
|
372
|
+
_, error = check_auth(event, public_paths={"/health"})
|
|
373
|
+
assert error is not None
|
|
374
|
+
assert error["statusCode"] == 401
|
|
375
|
+
|
|
376
|
+
def test_uses_rawPath_fallback(self):
|
|
377
|
+
"""Falls back to rawPath when path is missing (API Gateway v2)."""
|
|
378
|
+
event = {"rawPath": "/health", "headers": {}}
|
|
379
|
+
claims, error = check_auth(event, public_paths={"/health"})
|
|
380
|
+
assert claims is None
|
|
381
|
+
assert error is None
|
|
382
|
+
|
|
383
|
+
def test_empty_public_paths_requires_auth_on_all(self):
|
|
384
|
+
"""Empty public_paths means all paths require auth."""
|
|
385
|
+
event = {"path": "/health", "headers": {}}
|
|
386
|
+
_, error = check_auth(event)
|
|
387
|
+
assert error is not None
|
|
388
|
+
assert error["statusCode"] == 401
|
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/.github/workflows/publish.yml
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
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/getting-started/installation.md
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/getting-started/quickstart.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/jwt-authentication.md
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/lambda-utilities.md
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/log-processing.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/docs/guides/slack-integration.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/cli.py
RENAMED
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/config.py
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/db_client.py
RENAMED
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/es_client.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
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/timezone.py
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/nui_lambda_shared_utils/utils.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
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_cloudwatch_metrics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_es_query_builder.py
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_lambda_helpers.py
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_log_processors.py
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_powertools_helpers.py
RENAMED
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_secrets_helper.py
RENAMED
|
File without changes
|
|
File without changes
|
{nui_lambda_shared_utils-1.2.0 → nui_lambda_shared_utils-1.2.1}/tests/test_slack_formatter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|