prosody-events 0.1.0__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.
Files changed (44) hide show
  1. prosody_events-0.1.0/.github/workflows/general.yaml +135 -0
  2. prosody_events-0.1.0/.github/workflows/pr.yaml +23 -0
  3. prosody_events-0.1.0/.github/workflows/quality.yaml +55 -0
  4. prosody_events-0.1.0/.github/workflows/release.yaml +260 -0
  5. prosody_events-0.1.0/.gitignore +75 -0
  6. prosody_events-0.1.0/.release-please-manifest.json +3 -0
  7. prosody_events-0.1.0/.taplo.toml +4 -0
  8. prosody_events-0.1.0/CHANGELOG.md +92 -0
  9. prosody_events-0.1.0/CLAUDE.md +58 -0
  10. prosody_events-0.1.0/Cargo.lock +3396 -0
  11. prosody_events-0.1.0/Cargo.toml +85 -0
  12. prosody_events-0.1.0/LICENSE +21 -0
  13. prosody_events-0.1.0/Makefile +70 -0
  14. prosody_events-0.1.0/PKG-INFO +988 -0
  15. prosody_events-0.1.0/Readme.md +946 -0
  16. prosody_events-0.1.0/docker-compose.yaml +73 -0
  17. prosody_events-0.1.0/examples/requirements.txt +4 -0
  18. prosody_events-0.1.0/examples/tracing.py +112 -0
  19. prosody_events-0.1.0/grafana-datasources.yaml +30 -0
  20. prosody_events-0.1.0/prometheus.yaml +11 -0
  21. prosody_events-0.1.0/pyproject.toml +59 -0
  22. prosody_events-0.1.0/pytest.ini +13 -0
  23. prosody_events-0.1.0/python/prosody/__init__.py +11 -0
  24. prosody_events-0.1.0/python/prosody/context.pyi +78 -0
  25. prosody_events-0.1.0/python/prosody/errors.py +110 -0
  26. prosody_events-0.1.0/python/prosody/handler.py +166 -0
  27. prosody_events-0.1.0/python/prosody/message.py +41 -0
  28. prosody_events-0.1.0/python/prosody/prosody.pyi +348 -0
  29. prosody_events-0.1.0/python/prosody/py.typed +0 -0
  30. prosody_events-0.1.0/python/prosody/timer.py +18 -0
  31. prosody_events-0.1.0/release-please-config.json +8 -0
  32. prosody_events-0.1.0/src/admin/config.rs +128 -0
  33. prosody_events-0.1.0/src/admin/mod.rs +136 -0
  34. prosody_events-0.1.0/src/client/config.rs +607 -0
  35. prosody_events-0.1.0/src/client/format.rs +40 -0
  36. prosody_events-0.1.0/src/client/mod.rs +335 -0
  37. prosody_events-0.1.0/src/context.rs +275 -0
  38. prosody_events-0.1.0/src/handler.rs +567 -0
  39. prosody_events-0.1.0/src/lib.rs +70 -0
  40. prosody_events-0.1.0/src/logging.rs +298 -0
  41. prosody_events-0.1.0/src/util.rs +95 -0
  42. prosody_events-0.1.0/tests/test_prosody.py +901 -0
  43. prosody_events-0.1.0/tests/test_tracing_integration.py +330 -0
  44. prosody_events-0.1.0/tox.ini +11 -0
@@ -0,0 +1,135 @@
1
+ name: Check
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ pull_request:
7
+ branches:
8
+ - main
9
+ env:
10
+ CARGO_TERM_COLOR: always
11
+ CARGO_INCREMENTAL: 0
12
+ CARGO_PROFILE_TEST_DEBUG: 0
13
+ permissions:
14
+ contents: write
15
+ pages: write
16
+ id-token: write
17
+ jobs:
18
+ test:
19
+ name: Tests
20
+ runs-on: ubuntu-latest
21
+ services:
22
+ kafka:
23
+ image: apache/kafka:latest
24
+ ports:
25
+ - "9094:9094"
26
+ env:
27
+ KAFKA_NODE_ID: 0
28
+ KAFKA_PROCESS_ROLES: controller,broker
29
+ KAFKA_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093
30
+ KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
31
+ KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094
32
+ KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
33
+ KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
34
+ KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
35
+ KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
36
+ KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
37
+ KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
38
+ options: >-
39
+ --health-cmd "/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list"
40
+ --health-interval 15s
41
+ --health-timeout 10s
42
+ --health-retries 15
43
+ cassandra:
44
+ image: cassandra:latest
45
+ ports:
46
+ - "9042:9042"
47
+ options: >-
48
+ --health-cmd "cqlsh -e 'SELECT cluster_name FROM system.local;'"
49
+ --health-interval 15s
50
+ --health-timeout 10s
51
+ --health-retries 15
52
+ steps:
53
+ - uses: actions/checkout@v3
54
+
55
+ - uses: actions/setup-python@v5
56
+ with:
57
+ python-version: '3.12'
58
+ cache: 'pip'
59
+ - uses: dtolnay/rust-toolchain@stable
60
+ - uses: Swatinem/rust-cache@v2
61
+ - name: Install build dependencies
62
+ if: runner.os == 'Linux'
63
+ uses: awalsh128/cache-apt-pkgs-action@latest
64
+ with:
65
+ packages: cmake libcurl4-openssl-dev
66
+ version: 1.0
67
+ - name: Install Maturin from crates.io
68
+ uses: baptiste0928/cargo-install@v3
69
+ with:
70
+ crate: maturin
71
+ - name: Build and run tests
72
+ run: |
73
+ python -m venv venv
74
+ source venv/bin/activate
75
+ maturin develop --extras dev
76
+ pytest -v
77
+ env:
78
+ PROSODY_BOOTSTRAP_SERVERS: localhost:9094
79
+ PROSODY_CASSANDRA_NODES: localhost:9042
80
+
81
+ fmt:
82
+ name: Format
83
+ runs-on: ubuntu-latest
84
+ steps:
85
+ - uses: actions/checkout@v3
86
+ - uses: dtolnay/rust-toolchain@stable
87
+ with:
88
+ components: rustfmt
89
+ - name: Install taplo from crates.io
90
+ uses: baptiste0928/cargo-install@v3
91
+ with:
92
+ crate: taplo-cli
93
+ - uses: Swatinem/rust-cache@v2
94
+ - name: Enforce Rust formatting
95
+ run: cargo fmt --check
96
+ - name: Enforce TOML formatting
97
+ run: taplo validate
98
+
99
+ dependencies:
100
+ name: Dependencies
101
+ runs-on: ubuntu-latest
102
+ steps:
103
+ - uses: actions/checkout@v3
104
+
105
+ - uses: dtolnay/rust-toolchain@nightly
106
+ - uses: Swatinem/rust-cache@v2
107
+ - name: Install build dependencies
108
+ if: runner.os == 'Linux'
109
+ uses: awalsh128/cache-apt-pkgs-action@latest
110
+ with:
111
+ packages: cmake libcurl4-openssl-dev
112
+ version: 1.0
113
+ - name: Install udeps from crates.io
114
+ uses: baptiste0928/cargo-install@v3
115
+ with:
116
+ crate: cargo-udeps
117
+ - name: Run cargo udeps
118
+ run: cargo +nightly udeps
119
+
120
+ docs:
121
+ name: Documentation
122
+ runs-on: ubuntu-latest
123
+ steps:
124
+ - uses: actions/checkout@v3
125
+
126
+ - uses: dtolnay/rust-toolchain@stable
127
+ - uses: Swatinem/rust-cache@v2
128
+ - name: Install build dependencies
129
+ if: runner.os == 'Linux'
130
+ uses: awalsh128/cache-apt-pkgs-action@latest
131
+ with:
132
+ packages: cmake libcurl4-openssl-dev
133
+ version: 1.0
134
+ - name: Check documentation
135
+ run: RUSTDOCFLAGS="-D warnings" cargo doc
@@ -0,0 +1,23 @@
1
+ name: "PR"
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ types:
8
+ - opened
9
+ - edited
10
+ - synchronize
11
+ - reopened
12
+
13
+ permissions:
14
+ pull-requests: read
15
+
16
+ jobs:
17
+ main:
18
+ name: Title
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - uses: amannn/action-semantic-pull-request@v5
22
+ env:
23
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,55 @@
1
+ name: Quality
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ pull_request:
7
+ branches:
8
+ - main
9
+ # Rerun periodically to pick up new advisories
10
+ schedule:
11
+ - cron: '0 0 * * *'
12
+ # Run manually
13
+ workflow_dispatch:
14
+ env:
15
+ CARGO_TERM_COLOR: always
16
+ CARGO_INCREMENTAL: 0
17
+ CARGO_PROFILE_TEST_DEBUG: 0
18
+ jobs:
19
+ clippy:
20
+ name: Clippy
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - uses: actions/checkout@v3
24
+
25
+ - uses: dtolnay/rust-toolchain@stable
26
+ with:
27
+ components: clippy
28
+ - name: Install clippy-sarif from crates.io
29
+ uses: baptiste0928/cargo-install@v3
30
+ with:
31
+ crate: clippy-sarif
32
+ - name: Install sarif-fmt from crates.io
33
+ uses: baptiste0928/cargo-install@v3
34
+ with:
35
+ crate: sarif-fmt
36
+ - uses: Swatinem/rust-cache@v2
37
+ - name: Install build dependencies
38
+ if: runner.os == 'Linux'
39
+ uses: awalsh128/cache-apt-pkgs-action@latest
40
+ with:
41
+ packages: cmake libcurl4-openssl-dev
42
+ version: 1.0
43
+ - name: Linting
44
+ run:
45
+ cargo clippy --all-features -- -D warnings
46
+ # cargo clippy --all-features --message-format=json -- -D warnings
47
+ # | clippy-sarif
48
+ # | tee results.sarif
49
+ # | sarif-fmt
50
+ # continue-on-error: true
51
+ # - name: Upload analysis results to GitHub
52
+ # uses: github/codeql-action/upload-sarif@v3
53
+ # with:
54
+ # sarif_file: results.sarif
55
+ # wait-for-processing: true
@@ -0,0 +1,260 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ workflow_dispatch:
8
+ inputs:
9
+ release_as:
10
+ description: 'Force release version (e.g. 2.2.0-alpha.1)'
11
+ required: false
12
+ type: string
13
+
14
+ permissions:
15
+ contents: write
16
+ pull-requests: write
17
+
18
+ env:
19
+ CARGO_TERM_COLOR: always
20
+ CARGO_INCREMENTAL: 0
21
+ CARGO_PROFILE_TEST_DEBUG: 0
22
+
23
+ jobs:
24
+ release-please:
25
+ name: Release Please
26
+ runs-on: ubuntu-latest
27
+ outputs:
28
+ release_created: ${{ steps.release.outputs.release_created }}
29
+ tag_name: ${{ steps.release.outputs.tag_name }}
30
+ steps:
31
+ - uses: actions/checkout@v6
32
+ - name: Release Please Action
33
+ id: release
34
+ uses: googleapis/release-please-action@v4
35
+ with:
36
+ token: ${{ secrets.GH_PAT }}
37
+ config-file: release-please-config.json
38
+ manifest-file: .release-please-manifest.json
39
+ release-as: ${{ github.event.inputs.release_as }}
40
+
41
+ linux:
42
+ needs: release-please
43
+ if: ${{ needs.release-please.outputs.release_created }}
44
+ runs-on: ${{ matrix.platform.runner }}
45
+ permissions:
46
+ contents: read
47
+ id-token: write
48
+ attestations: write
49
+ strategy:
50
+ fail-fast: false
51
+ matrix:
52
+ platform:
53
+ - runner: ubuntu-latest
54
+ target: x86_64
55
+ - runner: ubuntu-latest
56
+ target: aarch64
57
+ steps:
58
+ - uses: actions/checkout@v6
59
+ - uses: actions/setup-python@v6
60
+ with:
61
+ python-version: 3.x
62
+
63
+ - name: Build wheels
64
+ uses: PyO3/maturin-action@v1
65
+ with:
66
+ target: ${{ matrix.platform.target }}
67
+ args: --release --out dist --find-interpreter
68
+ sccache: 'true'
69
+ manylinux: ${{ matrix.platform.target == 'aarch64' && '2_24' || 'auto' }}
70
+ before-script-linux: |
71
+ if command -v apk > /dev/null; then
72
+ apk add --no-cache cmake make curl-dev
73
+ elif command -v yum > /dev/null; then
74
+ yum install -y cmake libcurl-devel
75
+ elif command -v apt-get > /dev/null; then
76
+ apt-get update
77
+ apt-get install -y cmake libcurl4-openssl-dev
78
+ # Headers land under a multiarch dir (e.g. x86_64-linux-gnu or
79
+ # aarch64-linux-gnu depending on the runner). Symlink into the
80
+ # cross-compiler's sysroot where GCC actually searches.
81
+ curl_include=$(dirname "$(find /usr/include -name 'curl.h' | head -1)")
82
+ ln -sf "$curl_include" \
83
+ /usr/aarch64-unknown-linux-gnu/aarch64-unknown-linux-gnu/sysroot/usr/include/curl
84
+ fi
85
+
86
+ - name: Attest wheels
87
+ uses: actions/attest-build-provenance@v4
88
+ with:
89
+ subject-path: dist/*
90
+ - name: Upload wheels
91
+ uses: actions/upload-artifact@v7
92
+ with:
93
+ name: wheels-linux-${{ matrix.platform.target }}
94
+ path: dist
95
+
96
+ musllinux:
97
+ needs: release-please
98
+ if: ${{ needs.release-please.outputs.release_created }}
99
+ runs-on: ${{ matrix.platform.runner }}
100
+ permissions:
101
+ contents: read
102
+ id-token: write
103
+ attestations: write
104
+ strategy:
105
+ fail-fast: false
106
+ matrix:
107
+ platform:
108
+ - runner: ubuntu-latest
109
+ target: x86_64
110
+ - runner: ubuntu-latest
111
+ target: aarch64
112
+ steps:
113
+ - uses: actions/checkout@v6
114
+ - uses: actions/setup-python@v6
115
+ with:
116
+ python-version: 3.x
117
+
118
+ - name: Build wheels
119
+ uses: PyO3/maturin-action@v1
120
+ with:
121
+ target: ${{ matrix.platform.target }}
122
+ args: --release --out dist --find-interpreter
123
+ sccache: 'true'
124
+ manylinux: musllinux_1_2
125
+ before-script-linux: |
126
+ if command -v apk > /dev/null; then
127
+ apk add --no-cache cmake make curl-dev
128
+ elif command -v yum > /dev/null; then
129
+ yum install -y cmake libcurl-devel
130
+ elif command -v apt-get > /dev/null; then
131
+ apt-get update && apt-get install -y cmake libcurl4-openssl-dev
132
+ # Headers land under a multiarch dir (arch-dependent). Symlink into
133
+ # each musl cross-compiler's include dir (already exists in the image).
134
+ curl_include=$(dirname "$(find /usr/include -name 'curl.h' | head -1)")
135
+ for target_dir in /usr/local/musl/*-unknown-linux-musl/; do
136
+ ln -sf "$curl_include" "${target_dir}include/curl"
137
+ done
138
+ fi
139
+
140
+ - name: Attest wheels
141
+ uses: actions/attest-build-provenance@v4
142
+ with:
143
+ subject-path: dist/*
144
+ - name: Upload wheels
145
+ uses: actions/upload-artifact@v7
146
+ with:
147
+ name: wheels-musllinux-${{ matrix.platform.target }}
148
+ path: dist
149
+
150
+ windows:
151
+ needs: release-please
152
+ if: ${{ needs.release-please.outputs.release_created }}
153
+ runs-on: ${{ matrix.platform.runner }}
154
+ permissions:
155
+ contents: read
156
+ id-token: write
157
+ attestations: write
158
+ strategy:
159
+ matrix:
160
+ platform:
161
+ - runner: windows-latest
162
+ target: x64
163
+ steps:
164
+ - uses: actions/checkout@v6
165
+ - uses: actions/setup-python@v6
166
+ with:
167
+ python-version: 3.x
168
+ architecture: ${{ matrix.platform.target }}
169
+
170
+ - name: Build wheels
171
+ uses: PyO3/maturin-action@v1
172
+ with:
173
+ target: ${{ matrix.platform.target }}
174
+ args: --release --out dist --find-interpreter
175
+ sccache: 'true'
176
+ - name: Attest wheels
177
+ uses: actions/attest-build-provenance@v4
178
+ with:
179
+ subject-path: dist/*
180
+ - name: Upload wheels
181
+ uses: actions/upload-artifact@v7
182
+ with:
183
+ name: wheels-windows-${{ matrix.platform.target }}
184
+ path: dist
185
+
186
+ macos:
187
+ needs: release-please
188
+ if: ${{ needs.release-please.outputs.release_created }}
189
+ runs-on: ${{ matrix.platform.runner }}
190
+ permissions:
191
+ contents: read
192
+ id-token: write
193
+ attestations: write
194
+ strategy:
195
+ matrix:
196
+ platform:
197
+ - runner: macos-14
198
+ target: aarch64
199
+ steps:
200
+ - uses: actions/checkout@v6
201
+ - uses: actions/setup-python@v6
202
+ with:
203
+ python-version: 3.x
204
+ - uses: dtolnay/rust-toolchain@stable
205
+
206
+ - name: Build wheels
207
+ uses: PyO3/maturin-action@v1
208
+ with:
209
+ target: ${{ matrix.platform.target }}
210
+ args: --release --out dist --find-interpreter
211
+ sccache: 'true'
212
+ - name: Attest wheels
213
+ uses: actions/attest-build-provenance@v4
214
+ with:
215
+ subject-path: dist/*
216
+ - name: Upload wheels
217
+ uses: actions/upload-artifact@v7
218
+ with:
219
+ name: wheels-macos-${{ matrix.platform.target }}
220
+ path: dist
221
+
222
+ sdist:
223
+ needs: release-please
224
+ if: ${{ needs.release-please.outputs.release_created }}
225
+ runs-on: ubuntu-latest
226
+ permissions:
227
+ contents: read
228
+ id-token: write
229
+ attestations: write
230
+ steps:
231
+ - uses: actions/checkout@v6
232
+
233
+ - name: Build sdist
234
+ uses: PyO3/maturin-action@v1
235
+ with:
236
+ command: sdist
237
+ args: --out dist
238
+ - name: Attest sdist
239
+ uses: actions/attest-build-provenance@v4
240
+ with:
241
+ subject-path: dist/*
242
+ - name: Upload sdist
243
+ uses: actions/upload-artifact@v7
244
+ with:
245
+ name: wheels-sdist
246
+ path: dist
247
+
248
+ release:
249
+ name: Release
250
+ environment: release
251
+ runs-on: ubuntu-latest
252
+ needs: [ release-please, linux, musllinux, windows, macos, sdist ]
253
+ if: ${{ needs.release-please.outputs.release_created }}
254
+ permissions:
255
+ id-token: write
256
+ steps:
257
+ - uses: actions/download-artifact@v8
258
+ - uses: astral-sh/setup-uv@v8.0.0
259
+ - name: Publish to PyPI
260
+ run: uv publish --trusted-publishing always wheels-*/*
@@ -0,0 +1,75 @@
1
+ /target
2
+
3
+ # Byte-compiled / optimized / DLL files
4
+ __pycache__/
5
+ .pytest_cache/
6
+ *.py[cod]
7
+
8
+ # C extensions
9
+ *.so
10
+
11
+ # Distribution / packaging
12
+ .Python
13
+ .venv/
14
+ env/
15
+ bin/
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ include/
26
+ man/
27
+ venv/
28
+ *.egg-info/
29
+ .installed.cfg
30
+ *.egg
31
+
32
+ # Installer logs
33
+ pip-log.txt
34
+ pip-delete-this-directory.txt
35
+ pip-selfcheck.json
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .coverage
41
+ .cache
42
+ nosetests.xml
43
+ coverage.xml
44
+
45
+ # Translations
46
+ *.mo
47
+
48
+ # Mr Developer
49
+ .mr.developer.cfg
50
+ .project
51
+ .pydevproject
52
+
53
+ # Rope
54
+ .ropeproject
55
+
56
+ # Django stuff:
57
+ *.log
58
+ *.pot
59
+
60
+ .DS_Store
61
+
62
+ # Sphinx documentation
63
+ docs/_build/
64
+
65
+ # PyCharm
66
+ .idea/
67
+
68
+ # VSCode
69
+ .vscode/
70
+
71
+ # Pyenv
72
+ .python-version
73
+ !/pyvenv.cfg
74
+ pyvenv.cfg
75
+ .claude
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.1.0"
3
+ }
@@ -0,0 +1,4 @@
1
+ [formatting]
2
+ indent_string = " "
3
+ reorder_arrays = true
4
+ reorder_keys = true
@@ -0,0 +1,92 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 (2026-04-13)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * add QoS middleware and rename shutdown to cancel ([#95](https://github.com/prosody-events/prosody-py/issues/95))
9
+ * add timer scheduling support with Cassandra persistence ([#81](https://github.com/prosody-events/prosody-py/issues/81))
10
+
11
+ ### Features
12
+
13
+ * add event filtering, source tracking, and fix backpressure deadlock ([#56](https://github.com/prosody-events/prosody-py/issues/56)) ([9d6f3ad](https://github.com/prosody-events/prosody-py/commit/9d6f3adcefe4492b3946ae98d3de8e241e222018))
14
+ * add Kafka telemetry emitter ([#123](https://github.com/prosody-events/prosody-py/issues/123)) ([64517fc](https://github.com/prosody-events/prosody-py/commit/64517fcd3dca7386c0e6b49f0e17cb74ea7a3b58))
15
+ * Add message deduplication support ([#53](https://github.com/prosody-events/prosody-py/issues/53)) ([62d568d](https://github.com/prosody-events/prosody-py/commit/62d568d56839cced483a6930a3f44a0cfd7a6f68))
16
+ * add QoS middleware and rename shutdown to cancel ([#95](https://github.com/prosody-events/prosody-py/issues/95)) ([3b0d2db](https://github.com/prosody-events/prosody-py/commit/3b0d2db8a0657219d024cd270fbd3a4699a24814))
17
+ * add timer scheduling support with Cassandra persistence ([#81](https://github.com/prosody-events/prosody-py/issues/81)) ([282f278](https://github.com/prosody-events/prosody-py/commit/282f2788d79456fe4f96a94b14ae4eb8e912116e))
18
+ * asyncio.CancelledError propagation no longer required ([#33](https://github.com/prosody-events/prosody-py/issues/33)) ([444f174](https://github.com/prosody-events/prosody-py/commit/444f174a727f4f0abfd56780f3038cec70e8ea40))
19
+ * basic message consumption ([65f97d8](https://github.com/prosody-events/prosody-py/commit/65f97d89bdb0d7657852c3429be31e7ecc025f91))
20
+ * best-effort mode ([#48](https://github.com/prosody-events/prosody-py/issues/48)) ([f17dc8d](https://github.com/prosody-events/prosody-py/commit/f17dc8dfb5bb8e58e922444a698d3047d36a9ec1))
21
+ * capture send spans ([27b3041](https://github.com/prosody-events/prosody-py/commit/27b30412c1cbec952472ecb875712ded7795607a))
22
+ * configuration error surfacing, per-type timer semaphores, timer read performance ([#128](https://github.com/prosody-events/prosody-py/issues/128)) ([470859b](https://github.com/prosody-events/prosody-py/commit/470859bbccb2efe434143ee48f588f904b72c37e))
23
+ * **consumer:** add health check probes and stall detection ([#42](https://github.com/prosody-events/prosody-py/issues/42)) ([4a8dbc6](https://github.com/prosody-events/prosody-py/commit/4a8dbc66bc0f01001bacf145d77f4ed3709d3568))
24
+ * **consumer:** add shutdown timeout parameter ([#65](https://github.com/prosody-events/prosody-py/issues/65)) ([a73c452](https://github.com/prosody-events/prosody-py/commit/a73c45214f09d72f1ad9718035d02e5f409ee3f7))
25
+ * **consumer:** Implement graceful shutdown and error handling ([#12](https://github.com/prosody-events/prosody-py/issues/12)) ([83916a2](https://github.com/prosody-events/prosody-py/commit/83916a262942bb9c6734ddb53eb8cff6eb0a1702))
26
+ * **consumer:** improve graceful shutdown ([#15](https://github.com/prosody-events/prosody-py/issues/15)) ([a633b23](https://github.com/prosody-events/prosody-py/commit/a633b2358f3e736c7196967e2a409f3b2957424a))
27
+ * expose admin client ([#93](https://github.com/prosody-events/prosody-py/issues/93)) ([9bb65f7](https://github.com/prosody-events/prosody-py/commit/9bb65f7ee5f8c62d5e2d87bc5a7d50feaa51ab9d))
28
+ * expose source system and remove deprecated methods ([#90](https://github.com/prosody-events/prosody-py/issues/90)) ([3fb3c2a](https://github.com/prosody-events/prosody-py/commit/3fb3c2ab170f9abbf61214e4fd712ae6f9e6c566))
29
+ * initial commit ([3f476b3](https://github.com/prosody-events/prosody-py/commit/3f476b36a37861c6f5011d803f05d2b4fa445d7c))
30
+ * non-blocking timer retry ([#113](https://github.com/prosody-events/prosody-py/issues/113)) ([c3a3ccb](https://github.com/prosody-events/prosody-py/commit/c3a3ccbc8a8b5e3b2f4538f15333682816ab08b9))
31
+ * permanent error support ([#31](https://github.com/prosody-events/prosody-py/issues/31)) ([f739b0e](https://github.com/prosody-events/prosody-py/commit/f739b0e773254c92afbe3bf38b35283ed42d4595))
32
+ * persistent deduplication with global cache and Cassandra backend ([#130](https://github.com/prosody-events/prosody-py/issues/130)) ([46cc1b7](https://github.com/prosody-events/prosody-py/commit/46cc1b73afb1728ead676805868f44ee2615263e))
33
+ * protect client methods against post-fork usage ([#133](https://github.com/prosody-events/prosody-py/issues/133)) ([edbdc08](https://github.com/prosody-events/prosody-py/commit/edbdc08614b07073a2d0c07c6591f302df372b68))
34
+ * Sentry error monitoring for handler dispatch ([#132](https://github.com/prosody-events/prosody-py/issues/132)) ([f172da7](https://github.com/prosody-events/prosody-py/commit/f172da76e4086ce27828b6efe38b6821e3034e18))
35
+ * shutdown grace period and configurable span relation ([#134](https://github.com/prosody-events/prosody-py/issues/134)) ([e6766dc](https://github.com/prosody-events/prosody-py/commit/e6766dc15d7690bf19e2b2c5a065ad78a2332b61))
36
+ * support high-level modes ([00630a8](https://github.com/prosody-events/prosody-py/commit/00630a8ca450de2b72fbc999731c2643d38a0d7a))
37
+ * support regex topic subscriptions ([#87](https://github.com/prosody-events/prosody-py/issues/87)) ([2ba0d6c](https://github.com/prosody-events/prosody-py/commit/2ba0d6c24a493bb38215e5bf82a6ddc4c68b4173))
38
+
39
+
40
+ ### Bug Fixes
41
+
42
+ * add migration locks and jitter to timer slab loads ([#85](https://github.com/prosody-events/prosody-py/issues/85)) ([d4693c9](https://github.com/prosody-events/prosody-py/commit/d4693c9433bf49e6cc751945b5bb813ae46afb3f))
43
+ * always check for shutdown before retrying ([#63](https://github.com/prosody-events/prosody-py/issues/63)) ([5106440](https://github.com/prosody-events/prosody-py/commit/510644047a5184f2f45cb61a0124e63b50c98caf))
44
+ * attach traceback to error span ([#51](https://github.com/prosody-events/prosody-py/issues/51)) ([de4ca93](https://github.com/prosody-events/prosody-py/commit/de4ca93f4118e5369f46e7052a071427f832712d))
45
+ * bump dep for Windows rdkafka build support ([c0597ae](https://github.com/prosody-events/prosody-py/commit/c0597ae46e0ad5fa4953903a43262cdee4867463))
46
+ * bump prosody to pick up OTEL fixes ([#83](https://github.com/prosody-events/prosody-py/issues/83)) ([4c5fe25](https://github.com/prosody-events/prosody-py/commit/4c5fe25e61bb1284c1b99e4cde4639e3999a0f15))
47
+ * bundle zlib statically ([#101](https://github.com/prosody-events/prosody-py/issues/101)) ([7f23f01](https://github.com/prosody-events/prosody-py/commit/7f23f0150b2efed309547c7e0a19a408f339a330))
48
+ * cache parent context instead of span in Kafka loader ([b8142f7](https://github.com/prosody-events/prosody-py/commit/b8142f7090a59c4fba4228fb430d512f4a42e945))
49
+ * **consumer:** don’t commit empty topic lists ([#73](https://github.com/prosody-events/prosody-py/issues/73)) ([7a44f93](https://github.com/prosody-events/prosody-py/commit/7a44f931f3d2bbbaa2391ae057ddff790eee58be))
50
+ * **consumer:** don't commit final offsets during a rebalance ([#71](https://github.com/prosody-events/prosody-py/issues/71)) ([f7bfbee](https://github.com/prosody-events/prosody-py/commit/f7bfbee207b6776b78b3cf409b3faccbbdc7fc4e))
51
+ * **consumer:** prevent commits during rebalancing, add concurrency limit, fix watermark tracking ([#69](https://github.com/prosody-events/prosody-py/issues/69)) ([d8c1ff8](https://github.com/prosody-events/prosody-py/commit/d8c1ff84abbaa57435b2add15bab3a2fb68d3941))
52
+ * **consumer:** use librdkafka to commit and add additional liveness checks ([#75](https://github.com/prosody-events/prosody-py/issues/75)) ([00d1983](https://github.com/prosody-events/prosody-py/commit/00d1983489a9248c53454275022ba6b21ebb0ee2))
53
+ * context propagation ([90ffde9](https://github.com/prosody-events/prosody-py/commit/90ffde9a299209ac7632b4595a3cd57f112da1ba))
54
+ * downgrade span parent extraction failures to debug level ([#105](https://github.com/prosody-events/prosody-py/issues/105)) ([cce6610](https://github.com/prosody-events/prosody-py/commit/cce6610f31df1f7914c8d6adcbf5282d5ba5e77b))
55
+ * ensure handler coroutine is run in the asyncio event loop ([d55a3ac](https://github.com/prosody-events/prosody-py/commit/d55a3acdd9e050ac33f5aa6ad218bd8a183b6dfa))
56
+ * ensure latest Rust is installed on MacOS builds ([#58](https://github.com/prosody-events/prosody-py/issues/58)) ([0404988](https://github.com/prosody-events/prosody-py/commit/0404988435c184d50e12eeff7aa573a4c27c8f0d))
57
+ * fix mocking, ci, and bump deps ([#46](https://github.com/prosody-events/prosody-py/issues/46)) ([1c49bfe](https://github.com/prosody-events/prosody-py/commit/1c49bfee6f35067794a9b820acd1b8f569a60c6a))
58
+ * graceful slab_loader shutdown, remove timer backpressure gaps, and new API surface ([#117](https://github.com/prosody-events/prosody-py/issues/117)) ([5abec25](https://github.com/prosody-events/prosody-py/commit/5abec251d32d4e25464f42a9114389a0cd55de6f))
59
+ * group id and source system env var fallback ([#61](https://github.com/prosody-events/prosody-py/issues/61)) ([ef3d72c](https://github.com/prosody-events/prosody-py/commit/ef3d72c12dd4e23691c841665f67795aecd5fa0c))
60
+ * make handler available to gc ([6421b7d](https://github.com/prosody-events/prosody-py/commit/6421b7d36f200af0eea095ed57d2ae76975595dc))
61
+ * only log events, not spans ([#116](https://github.com/prosody-events/prosody-py/issues/116)) ([61fa1fb](https://github.com/prosody-events/prosody-py/commit/61fa1fbc2f0e6245150ff4aa80bfc5d93dadb11d))
62
+ * package name ([#4](https://github.com/prosody-events/prosody-py/issues/4)) ([ab2f375](https://github.com/prosody-events/prosody-py/commit/ab2f375baba28361104330fbfa88863b24e5a505))
63
+ * prevent false OffsetDeleted errors from concurrent loader requests ([#121](https://github.com/prosody-events/prosody-py/issues/121)) ([5bba955](https://github.com/prosody-events/prosody-py/commit/5bba9550655240c618787579103cff32b96dedfa))
64
+ * propagate span traces through context methods ([#92](https://github.com/prosody-events/prosody-py/issues/92)) ([dcb63fe](https://github.com/prosody-events/prosody-py/commit/dcb63fe589fcf3e7eacd0bdf784552de10772fc3))
65
+ * remove deprecated x86 macOS builds from release workflow ([#99](https://github.com/prosody-events/prosody-py/issues/99)) ([6622539](https://github.com/prosody-events/prosody-py/commit/6622539c69c4ecdb6d65f3c095dbfffbb617d639))
66
+ * remove max_enqueued_per_key from type signatures ([#118](https://github.com/prosody-events/prosody-py/issues/118)) ([9163c23](https://github.com/prosody-events/prosody-py/commit/9163c23e6ff262707e21866e1e634ca8a6810e9f))
67
+ * replace pyo3-log with non-blocking Python logging layer ([#98](https://github.com/prosody-events/prosody-py/issues/98)) ([11f8215](https://github.com/prosody-events/prosody-py/commit/11f821542312e86ee83148ceb3aea61d251b0cc0))
68
+ * respect stall threshold ([#67](https://github.com/prosody-events/prosody-py/issues/67)) ([a9060a3](https://github.com/prosody-events/prosody-py/commit/a9060a3dbbaeb95a05c0004193d09feaa07ab70e))
69
+ * short circuit failures and properly configure producer mode ([#28](https://github.com/prosody-events/prosody-py/issues/28)) ([2744603](https://github.com/prosody-events/prosody-py/commit/27446036459cc22e45fdd20d3476aa9cda46c9bf))
70
+ * telemetry event_time uses millisecond precision with Z suffix ([#126](https://github.com/prosody-events/prosody-py/issues/126)) ([947b541](https://github.com/prosody-events/prosody-py/commit/947b54133cabdf16f15ebeb91c551855cc2b2920))
71
+ * trigger other workflows on release branch ([#6](https://github.com/prosody-events/prosody-py/issues/6)) ([70a17c3](https://github.com/prosody-events/prosody-py/commit/70a17c38fce477f464d16c4106430dca85a54daa))
72
+ * update prosody to fix cross-topic key collisions ([#103](https://github.com/prosody-events/prosody-py/issues/103)) ([c85d91d](https://github.com/prosody-events/prosody-py/commit/c85d91dd0202462fca124138fc61fb08688197e4))
73
+ * update prosody to fix partition resume after rebalance ([#110](https://github.com/prosody-events/prosody-py/issues/110)) ([3a7f97c](https://github.com/prosody-events/prosody-py/commit/3a7f97ccc2e209d5aabe49189d1f42cf7e3f04ac))
74
+ * update prosody to fix timeout-induced partition stalls ([#108](https://github.com/prosody-events/prosody-py/issues/108)) ([845ae1a](https://github.com/prosody-events/prosody-py/commit/845ae1a63d4b4524c02cf31a30936c69c5a92d77))
75
+ * upgrade macos CI runner ([befb975](https://github.com/prosody-events/prosody-py/commit/befb9757550be8cfe20604cb2548d18580b1bf06))
76
+ * use thread-safe channels in timer tests ([#97](https://github.com/prosody-events/prosody-py/issues/97)) ([f7b60d7](https://github.com/prosody-events/prosody-py/commit/f7b60d7cd2ce83bc576353ab2abed78ad5b95a88))
77
+
78
+
79
+ ### Performance Improvements
80
+
81
+ * bound message buffering ([35278ba](https://github.com/prosody-events/prosody-py/commit/35278bab0f4a43323006bf08d34d98911edff1bb))
82
+ * **consumer:** reduce cloning and message data movement ([#20](https://github.com/prosody-events/prosody-py/issues/20)) ([1dbbc46](https://github.com/prosody-events/prosody-py/commit/1dbbc4698c8ecb21f48cf3ac844ce40f2536d7e8))
83
+ * don’t allocate and convert the datetime unless needed ([1bbe5b9](https://github.com/prosody-events/prosody-py/commit/1bbe5b96a599f177df6b4911980dd19a569dfbfb))
84
+ * **json:** upgrade Prosody ([#30](https://github.com/prosody-events/prosody-py/issues/30)) ([60d7432](https://github.com/prosody-events/prosody-py/commit/60d7432574e5391da70a698f63969ad4f99520c7))
85
+ * use args instead of kwargs ([f72d513](https://github.com/prosody-events/prosody-py/commit/f72d513003616dd3c87720d81ec462178281f630))
86
+ * use jemalloc allocator ([#114](https://github.com/prosody-events/prosody-py/issues/114)) ([68f77d5](https://github.com/prosody-events/prosody-py/commit/68f77d5c86700388f3b467e20c8e37b4042ae3a3))
87
+
88
+
89
+ ### Miscellaneous Chores
90
+
91
+ * release 0.0.1 ([fa8c40f](https://github.com/prosody-events/prosody-py/commit/fa8c40fcc89173ebdfcc95d9532582149db19062))
92
+ * release 0.1.0 ([a75476c](https://github.com/prosody-events/prosody-py/commit/a75476c2f025a86d247f8840c02145f3dacaf339))