nui-lambda-shared-utils 1.0.0__tar.gz → 1.0.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.
- nui_lambda_shared_utils-1.0.2/.github/workflows/ci.yml +108 -0
- nui_lambda_shared_utils-1.0.2/.github/workflows/publish.yml +136 -0
- nui_lambda_shared_utils-1.0.2/.github/workflows/test.yml +44 -0
- nui_lambda_shared_utils-1.0.2/CLAUDE.md +218 -0
- nui_lambda_shared_utils-1.0.2/CONTRIBUTING.md +281 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/PKG-INFO +33 -1
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/README.md +32 -0
- nui_lambda_shared_utils-1.0.2/docs/slack_config.yaml.template +22 -0
- nui_lambda_shared_utils-1.0.2/mypy.ini +23 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/__init__.py +41 -16
- nui_lambda_shared_utils-1.0.2/nui_lambda_shared_utils/base_client.py +254 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/config.py +29 -20
- nui_lambda_shared_utils-1.0.2/nui_lambda_shared_utils/db_client.py +710 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/error_handler.py +3 -3
- nui_lambda_shared_utils-1.0.2/nui_lambda_shared_utils/es_client.py +360 -0
- nui_lambda_shared_utils-1.0.2/nui_lambda_shared_utils/slack_client.py +611 -0
- nui_lambda_shared_utils-1.0.2/nui_lambda_shared_utils/utils.py +291 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils.egg-info/SOURCES.txt +16 -1
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/pyproject.toml +13 -3
- nui_lambda_shared_utils-1.0.2/pytest.ini +16 -0
- nui_lambda_shared_utils-1.0.2/requirements-test.txt +25 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/setup.py +2 -1
- nui_lambda_shared_utils-1.0.2/tests/test_aws_utils.py +327 -0
- nui_lambda_shared_utils-1.0.2/tests/test_base_client.py +811 -0
- nui_lambda_shared_utils-1.0.2/tests/test_config.py +276 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_db_client.py +12 -12
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_es_client.py +28 -19
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_secrets_helper.py +1 -1
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_slack_client.py +310 -83
- nui_lambda_shared_utils-1.0.2/tests/test_utils.py +541 -0
- nui_lambda_shared_utils-1.0.0/nui_lambda_shared_utils/db_client.py +0 -521
- nui_lambda_shared_utils-1.0.0/nui_lambda_shared_utils/es_client.py +0 -153
- nui_lambda_shared_utils-1.0.0/nui_lambda_shared_utils/slack_client.py +0 -413
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/LICENSE +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/MANIFEST.in +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/docs/README.md +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/docs/configuration.md +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/docs/index.md +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/docs/installation.md +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/docs/quickstart.md +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/cloudwatch_metrics.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/es_query_builder.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/secrets_helper.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/slack_formatter.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/slack_setup/__init__.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/slack_setup/channel_creator.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/slack_setup/channel_definitions.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/slack_setup/setup_helpers.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/slack_setup_cli.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/nui_lambda_shared_utils/timezone.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/setup.cfg +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/__init__.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_cloudwatch_metrics.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_error_handler.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_es_query_builder.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_slack_formatter.py +0 -0
- {nui_lambda_shared_utils-1.0.0 → nui_lambda_shared_utils-1.0.2}/tests/test_timezone.py +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master, develop ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, master, develop ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test Python ${{ matrix.python-version }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ['3.9', '3.10', '3.11', '3.12']
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v4
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
|
|
25
|
+
- name: Cache pip dependencies
|
|
26
|
+
uses: actions/cache@v3
|
|
27
|
+
with:
|
|
28
|
+
path: ~/.cache/pip
|
|
29
|
+
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml', '**/setup.py') }}
|
|
30
|
+
restore-keys: |
|
|
31
|
+
${{ runner.os }}-pip-
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: |
|
|
35
|
+
python -m pip install --upgrade pip
|
|
36
|
+
echo "Installing test requirements..."
|
|
37
|
+
pip install -r requirements-test.txt
|
|
38
|
+
echo "Installing package..."
|
|
39
|
+
pip install -e .
|
|
40
|
+
echo "Verifying key dependencies:"
|
|
41
|
+
python -c "import elasticsearch; print('✓ elasticsearch')" || echo "✗ elasticsearch missing"
|
|
42
|
+
python -c "import slack_sdk; print('✓ slack_sdk')" || echo "✗ slack_sdk missing"
|
|
43
|
+
python -c "import pymysql; print('✓ pymysql')" || echo "✗ pymysql missing"
|
|
44
|
+
|
|
45
|
+
- name: Auto-format with black
|
|
46
|
+
run: |
|
|
47
|
+
black nui_lambda_shared_utils tests
|
|
48
|
+
if ! git diff --quiet; then
|
|
49
|
+
echo "::warning::Code was auto-formatted by Black"
|
|
50
|
+
git config --local user.email "action@github.com"
|
|
51
|
+
git config --local user.name "GitHub Action"
|
|
52
|
+
git add -A
|
|
53
|
+
git commit -m "Auto-format code with Black [skip ci]" || echo "No changes to commit"
|
|
54
|
+
else
|
|
55
|
+
echo "✅ Code is already properly formatted"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
- name: Type check with mypy
|
|
59
|
+
run: |
|
|
60
|
+
mypy nui_lambda_shared_utils --ignore-missing-imports
|
|
61
|
+
continue-on-error: true # Don't fail CI on type errors yet
|
|
62
|
+
|
|
63
|
+
- name: Test with pytest
|
|
64
|
+
run: |
|
|
65
|
+
pytest --cov=nui_lambda_shared_utils --cov-report=xml --cov-report=term-missing -v
|
|
66
|
+
|
|
67
|
+
- name: Upload coverage to Codecov
|
|
68
|
+
uses: codecov/codecov-action@v3
|
|
69
|
+
with:
|
|
70
|
+
file: ./coverage.xml
|
|
71
|
+
flags: unittests
|
|
72
|
+
name: codecov-umbrella
|
|
73
|
+
fail_ci_if_error: false
|
|
74
|
+
|
|
75
|
+
build:
|
|
76
|
+
name: Build Package
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
needs: test
|
|
79
|
+
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@v4
|
|
82
|
+
|
|
83
|
+
- name: Set up Python
|
|
84
|
+
uses: actions/setup-python@v4
|
|
85
|
+
with:
|
|
86
|
+
python-version: '3.11'
|
|
87
|
+
|
|
88
|
+
- name: Install build dependencies
|
|
89
|
+
run: |
|
|
90
|
+
python -m pip install --upgrade pip
|
|
91
|
+
pip install build twine
|
|
92
|
+
|
|
93
|
+
- name: Build package
|
|
94
|
+
run: python -m build
|
|
95
|
+
|
|
96
|
+
- name: Check package integrity
|
|
97
|
+
run: |
|
|
98
|
+
twine check dist/*
|
|
99
|
+
echo "Package contents:"
|
|
100
|
+
python -m tarfile -l dist/*.tar.gz | head -20
|
|
101
|
+
echo "Wheel contents:"
|
|
102
|
+
python -m zipfile -l dist/*.whl | head -20
|
|
103
|
+
|
|
104
|
+
- name: Test installation
|
|
105
|
+
run: |
|
|
106
|
+
pip install dist/*.whl
|
|
107
|
+
python -c "import nui_lambda_shared_utils; print('✅ Package imports successfully')"
|
|
108
|
+
python -c "from nui_lambda_shared_utils import Config, get_secret; print('✅ Core imports work')"
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
name: Build and Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*' # Trigger on version tags like v1.0.0
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
workflow_dispatch: # Allow manual triggering
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
name: Run Tests
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
strategy:
|
|
16
|
+
matrix:
|
|
17
|
+
python-version: ['3.9', '3.10', '3.11', '3.12']
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
23
|
+
uses: actions/setup-python@v4
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
echo "Installing test requirements..."
|
|
31
|
+
pip install -r requirements-test.txt
|
|
32
|
+
echo "Installing package..."
|
|
33
|
+
pip install -e .
|
|
34
|
+
echo "Verifying key dependencies:"
|
|
35
|
+
python -c "import elasticsearch; print('✓ elasticsearch')" || echo "✗ elasticsearch missing"
|
|
36
|
+
python -c "import slack_sdk; print('✓ slack_sdk')" || echo "✗ slack_sdk missing"
|
|
37
|
+
python -c "import pymysql; print('✓ pymysql')" || echo "✗ pymysql missing"
|
|
38
|
+
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: |
|
|
41
|
+
pytest --cov=nui_lambda_shared_utils --cov-report=xml --cov-report=term-missing
|
|
42
|
+
|
|
43
|
+
- name: Upload coverage to Codecov
|
|
44
|
+
uses: codecov/codecov-action@v3
|
|
45
|
+
with:
|
|
46
|
+
file: ./coverage.xml
|
|
47
|
+
fail_ci_if_error: false
|
|
48
|
+
|
|
49
|
+
build:
|
|
50
|
+
name: Build Distribution
|
|
51
|
+
runs-on: ubuntu-latest
|
|
52
|
+
needs: test
|
|
53
|
+
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v4
|
|
56
|
+
with:
|
|
57
|
+
fetch-depth: 0 # Full history for version calculation
|
|
58
|
+
|
|
59
|
+
- name: Set up Python
|
|
60
|
+
uses: actions/setup-python@v4
|
|
61
|
+
with:
|
|
62
|
+
python-version: '3.11'
|
|
63
|
+
|
|
64
|
+
- name: Install build dependencies
|
|
65
|
+
run: |
|
|
66
|
+
python -m pip install --upgrade pip
|
|
67
|
+
pip install build twine
|
|
68
|
+
|
|
69
|
+
- name: Build package
|
|
70
|
+
run: python -m build
|
|
71
|
+
|
|
72
|
+
- name: Check package
|
|
73
|
+
run: |
|
|
74
|
+
twine check dist/*
|
|
75
|
+
python -m tarfile -l dist/*.tar.gz
|
|
76
|
+
|
|
77
|
+
- name: Upload artifacts
|
|
78
|
+
uses: actions/upload-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
name: dist
|
|
81
|
+
path: dist/
|
|
82
|
+
|
|
83
|
+
publish:
|
|
84
|
+
name: Publish to PyPI
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
needs: [test, build]
|
|
87
|
+
# Only publish on tagged releases
|
|
88
|
+
if: github.event_name == 'release' || startsWith(github.ref, 'refs/tags/')
|
|
89
|
+
environment:
|
|
90
|
+
name: pypi
|
|
91
|
+
url: https://pypi.org/project/nui-lambda-shared-utils/
|
|
92
|
+
|
|
93
|
+
permissions:
|
|
94
|
+
id-token: write # For trusted publishing
|
|
95
|
+
contents: read
|
|
96
|
+
|
|
97
|
+
steps:
|
|
98
|
+
- name: Download artifacts
|
|
99
|
+
uses: actions/download-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: dist
|
|
102
|
+
path: dist/
|
|
103
|
+
|
|
104
|
+
- name: Publish to PyPI
|
|
105
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
106
|
+
with:
|
|
107
|
+
verbose: true
|
|
108
|
+
print-hash: true
|
|
109
|
+
|
|
110
|
+
publish-test:
|
|
111
|
+
name: Publish to TestPyPI
|
|
112
|
+
runs-on: ubuntu-latest
|
|
113
|
+
needs: [test, build]
|
|
114
|
+
# Publish to TestPyPI on manual trigger or development branches
|
|
115
|
+
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/'))
|
|
116
|
+
environment:
|
|
117
|
+
name: testpypi
|
|
118
|
+
url: https://test.pypi.org/project/nui-lambda-shared-utils/
|
|
119
|
+
|
|
120
|
+
permissions:
|
|
121
|
+
id-token: write
|
|
122
|
+
contents: read
|
|
123
|
+
|
|
124
|
+
steps:
|
|
125
|
+
- name: Download artifacts
|
|
126
|
+
uses: actions/download-artifact@v4
|
|
127
|
+
with:
|
|
128
|
+
name: dist
|
|
129
|
+
path: dist/
|
|
130
|
+
|
|
131
|
+
- name: Publish to TestPyPI
|
|
132
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
133
|
+
with:
|
|
134
|
+
repository-url: https://test.pypi.org/legacy/
|
|
135
|
+
verbose: true
|
|
136
|
+
print-hash: true
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ main, master ]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ['3.9', '3.10', '3.11']
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v3
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v4
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install dependencies
|
|
25
|
+
run: |
|
|
26
|
+
python -m pip install --upgrade pip
|
|
27
|
+
pip install -r requirements-test.txt
|
|
28
|
+
pip install -e .
|
|
29
|
+
|
|
30
|
+
- name: Check formatting with black
|
|
31
|
+
run: |
|
|
32
|
+
black --check --diff nui_lambda_shared_utils tests || {
|
|
33
|
+
echo "::warning::Code formatting issues found - run 'black nui_lambda_shared_utils tests' locally"
|
|
34
|
+
echo "Continuing build despite formatting issues..."
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# TODO: Re-enable mypy after fixing type annotations
|
|
38
|
+
# - name: Type check with mypy
|
|
39
|
+
# run: |
|
|
40
|
+
# mypy lambda_shared_utils/ --config-file mypy.ini
|
|
41
|
+
|
|
42
|
+
- name: Test with pytest
|
|
43
|
+
run: |
|
|
44
|
+
pytest --cov=nui_lambda_shared_utils --cov-report=xml
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
This is `nui-lambda-shared-utils`, a Python package providing enterprise-grade utilities for AWS Lambda functions. It offers standardized integrations for Slack, Elasticsearch, database operations, CloudWatch metrics, and error handling patterns commonly used across NUI platform Lambda services.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
### Core Module Structure
|
|
12
|
+
- **Configuration System** (`config.py`) - Environment-aware configuration with AWS Secrets Manager integration
|
|
13
|
+
- **Secrets Management** (`secrets_helper.py`) - Centralized credential handling with caching
|
|
14
|
+
- **Slack Integration** (`slack_client.py`, `slack_formatter.py`) - Rich messaging, threading, and file uploads
|
|
15
|
+
- **Elasticsearch** (`es_client.py`, `es_query_builder.py`) - Query builders and health monitoring
|
|
16
|
+
- **Database** (`db_client.py`) - Connection pooling with retry logic
|
|
17
|
+
- **Metrics** (`cloudwatch_metrics.py`) - Batched CloudWatch publishing with decorators
|
|
18
|
+
- **Error Handling** (`error_handler.py`) - Retry patterns with exponential backoff
|
|
19
|
+
- **Timezone Utils** (`timezone.py`) - New Zealand timezone handling
|
|
20
|
+
|
|
21
|
+
### Optional Dependencies
|
|
22
|
+
The package uses optional extras to minimize Lambda bundle size:
|
|
23
|
+
- `elasticsearch` - Elasticsearch client and query builders
|
|
24
|
+
- `database` - MySQL/PostgreSQL drivers
|
|
25
|
+
- `slack` - Slack SDK
|
|
26
|
+
- `all` - All integrations
|
|
27
|
+
- `dev` - Development and testing tools
|
|
28
|
+
|
|
29
|
+
### Slack Setup Module
|
|
30
|
+
The `slack_setup/` submodule provides automated Slack workspace configuration:
|
|
31
|
+
- **Channel Creation** - Programmatic channel and permission setup
|
|
32
|
+
- **Template System** - YAML-based channel definitions
|
|
33
|
+
- **CLI Tool** - `nui-slack-setup` command for deployment
|
|
34
|
+
|
|
35
|
+
## Development Commands
|
|
36
|
+
|
|
37
|
+
### Environment Setup
|
|
38
|
+
```bash
|
|
39
|
+
# Install package in development mode with all dependencies
|
|
40
|
+
pip install -e .[dev]
|
|
41
|
+
|
|
42
|
+
# Install with specific integrations only
|
|
43
|
+
pip install -e .[slack,elasticsearch]
|
|
44
|
+
|
|
45
|
+
# Set up virtual environment
|
|
46
|
+
python -m venv venv
|
|
47
|
+
source venv/bin/activate # Linux/Mac
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Testing
|
|
51
|
+
```bash
|
|
52
|
+
# Run all tests
|
|
53
|
+
pytest
|
|
54
|
+
|
|
55
|
+
# Run with coverage reporting
|
|
56
|
+
pytest --cov=nui_lambda_shared_utils --cov-report=html
|
|
57
|
+
|
|
58
|
+
# Run only unit tests (skip integration tests requiring AWS)
|
|
59
|
+
pytest -m "not integration"
|
|
60
|
+
|
|
61
|
+
# Run specific test categories
|
|
62
|
+
pytest -m unit # Unit tests only
|
|
63
|
+
pytest -m integration # Integration tests only
|
|
64
|
+
pytest -m slow # Slow tests only
|
|
65
|
+
|
|
66
|
+
# Run single test file
|
|
67
|
+
pytest tests/test_slack_client.py -v
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Code Quality
|
|
71
|
+
```bash
|
|
72
|
+
# Format code with Black (line length: 120)
|
|
73
|
+
black nui_lambda_shared_utils/ tests/
|
|
74
|
+
|
|
75
|
+
# Check formatting without changes
|
|
76
|
+
black --check nui_lambda_shared_utils/
|
|
77
|
+
|
|
78
|
+
# Type checking with MyPy
|
|
79
|
+
mypy nui_lambda_shared_utils/ --config-file mypy.ini
|
|
80
|
+
|
|
81
|
+
# Run linting (currently configured to use Black)
|
|
82
|
+
black --check nui_lambda_shared_utils/
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Package Building and Publishing
|
|
86
|
+
```bash
|
|
87
|
+
# Build package
|
|
88
|
+
python -m build
|
|
89
|
+
|
|
90
|
+
# Install build tools
|
|
91
|
+
pip install build twine
|
|
92
|
+
|
|
93
|
+
# Publish to PyPI (requires credentials)
|
|
94
|
+
python -m twine upload dist/*
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Configuration Patterns
|
|
98
|
+
|
|
99
|
+
### Environment Variables
|
|
100
|
+
The package expects these environment variables for runtime configuration:
|
|
101
|
+
- `ES_HOST` - Elasticsearch endpoint
|
|
102
|
+
- `ES_CREDENTIALS_SECRET` - AWS secret name for ES credentials
|
|
103
|
+
- `DB_CREDENTIALS_SECRET` - AWS secret name for database credentials
|
|
104
|
+
- `SLACK_CREDENTIALS_SECRET` - AWS secret name for Slack token
|
|
105
|
+
- `AWS_REGION` - AWS region for services
|
|
106
|
+
|
|
107
|
+
### AWS Secrets Format
|
|
108
|
+
Secrets should follow standardized JSON structures:
|
|
109
|
+
```json
|
|
110
|
+
// Elasticsearch
|
|
111
|
+
{"host": "elastic:9200", "username": "user", "password": "pass"}
|
|
112
|
+
|
|
113
|
+
// Database
|
|
114
|
+
{"host": "db-host", "port": 3306, "username": "user", "password": "pass", "database": "db"}
|
|
115
|
+
|
|
116
|
+
// Slack
|
|
117
|
+
{"bot_token": "xoxb-...", "webhook_url": "https://hooks.slack.com/..."}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Programmatic Configuration
|
|
121
|
+
```python
|
|
122
|
+
import nui_lambda_shared_utils as nui
|
|
123
|
+
|
|
124
|
+
# Configure specific settings
|
|
125
|
+
nui.configure(
|
|
126
|
+
es_host="localhost:9200",
|
|
127
|
+
slack_credentials_secret="dev/slack-token"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# Or use Config object
|
|
131
|
+
config = nui.Config(es_host="prod:9200")
|
|
132
|
+
nui.set_config(config)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Common Usage Patterns
|
|
136
|
+
|
|
137
|
+
### Error Handling with Decorators
|
|
138
|
+
```python
|
|
139
|
+
from nui_lambda_shared_utils import with_retry, handle_lambda_error
|
|
140
|
+
|
|
141
|
+
@handle_lambda_error
|
|
142
|
+
@with_retry(max_attempts=3)
|
|
143
|
+
def lambda_handler(event, context):
|
|
144
|
+
# Lambda logic with automatic error handling and retries
|
|
145
|
+
pass
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Metrics Publishing
|
|
149
|
+
```python
|
|
150
|
+
from nui_lambda_shared_utils import MetricsPublisher, track_lambda_performance
|
|
151
|
+
|
|
152
|
+
metrics = MetricsPublisher(namespace="MyService")
|
|
153
|
+
|
|
154
|
+
@track_lambda_performance(metrics)
|
|
155
|
+
def lambda_handler(event, context):
|
|
156
|
+
# Automatically tracked performance metrics
|
|
157
|
+
metrics.put_metric("ProcessedItems", len(items), "Count")
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Slack Integration
|
|
161
|
+
```python
|
|
162
|
+
from nui_lambda_shared_utils import SlackClient, SlackBlockBuilder
|
|
163
|
+
|
|
164
|
+
slack = SlackClient()
|
|
165
|
+
builder = SlackBlockBuilder()
|
|
166
|
+
|
|
167
|
+
blocks = (builder
|
|
168
|
+
.add_header("Alert", emoji="warning")
|
|
169
|
+
.add_section("Status", "Error detected")
|
|
170
|
+
.build()
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
slack.send_message(channel="#alerts", blocks=blocks)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Testing Strategy
|
|
177
|
+
|
|
178
|
+
### Test Categories (pytest markers)
|
|
179
|
+
- `@pytest.mark.unit` - Fast unit tests with mocking
|
|
180
|
+
- `@pytest.mark.integration` - Tests requiring AWS services
|
|
181
|
+
- `@pytest.mark.slow` - Long-running tests
|
|
182
|
+
|
|
183
|
+
### AWS Testing
|
|
184
|
+
Integration tests use `moto` for AWS service mocking. Some tests require real AWS credentials for full integration testing.
|
|
185
|
+
|
|
186
|
+
### Test Structure
|
|
187
|
+
```
|
|
188
|
+
tests/
|
|
189
|
+
├── test_<module>.py # Main module tests
|
|
190
|
+
├── conftest.py # Shared fixtures
|
|
191
|
+
└── fixtures/ # Test data files
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Package Distribution
|
|
195
|
+
|
|
196
|
+
### Version Management
|
|
197
|
+
Version is defined in both `setup.py` and `pyproject.toml` and should be kept in sync. The package follows semantic versioning.
|
|
198
|
+
|
|
199
|
+
### PyPI Publishing
|
|
200
|
+
The package is published to PyPI as `nui-lambda-shared-utils` with GitHub Actions automation for releases.
|
|
201
|
+
|
|
202
|
+
### CLI Tools
|
|
203
|
+
The package provides `nui-slack-setup` CLI tool for Slack workspace configuration.
|
|
204
|
+
|
|
205
|
+
## AWS Lambda Integration
|
|
206
|
+
|
|
207
|
+
### Bundle Size Optimization
|
|
208
|
+
- Use specific extras (`[slack]`, `[elasticsearch]`) rather than `[all]`
|
|
209
|
+
- Optional imports prevent failure if dependencies aren't installed
|
|
210
|
+
- Core utilities work without optional dependencies
|
|
211
|
+
|
|
212
|
+
### Lambda Layer Usage
|
|
213
|
+
The package is designed to work well in Lambda layers for sharing across multiple functions.
|
|
214
|
+
|
|
215
|
+
### Environment Integration
|
|
216
|
+
- Automatic AWS region detection
|
|
217
|
+
- Secrets Manager integration with credential caching
|
|
218
|
+
- CloudWatch metrics with proper dimensions
|