pgoutput-decoder 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 (39) hide show
  1. pgoutput_decoder-0.1.0/.github/dependabot.yml +28 -0
  2. pgoutput_decoder-0.1.0/.github/workflows/build.yml +49 -0
  3. pgoutput_decoder-0.1.0/.github/workflows/ci.yml +205 -0
  4. pgoutput_decoder-0.1.0/.github/workflows/release.yml +161 -0
  5. pgoutput_decoder-0.1.0/.gitignore +29 -0
  6. pgoutput_decoder-0.1.0/.pre-commit-config.yaml +37 -0
  7. pgoutput_decoder-0.1.0/AGENTS.md +125 -0
  8. pgoutput_decoder-0.1.0/Cargo.lock +1470 -0
  9. pgoutput_decoder-0.1.0/Cargo.toml +38 -0
  10. pgoutput_decoder-0.1.0/DESIGN.md +20 -0
  11. pgoutput_decoder-0.1.0/PKG-INFO +1139 -0
  12. pgoutput_decoder-0.1.0/README.md +1118 -0
  13. pgoutput_decoder-0.1.0/RELEASE.md +319 -0
  14. pgoutput_decoder-0.1.0/example_debezium.py +96 -0
  15. pgoutput_decoder-0.1.0/examples/README.md +323 -0
  16. pgoutput_decoder-0.1.0/examples/background_thread.py +456 -0
  17. pgoutput_decoder-0.1.0/examples/basic_cdc.py +57 -0
  18. pgoutput_decoder-0.1.0/examples/celery_integration.py +401 -0
  19. pgoutput_decoder-0.1.0/examples/setup_postgres.sql +148 -0
  20. pgoutput_decoder-0.1.0/examples/sync_wrapper.py +230 -0
  21. pgoutput_decoder-0.1.0/examples/test_replication.rs +237 -0
  22. pgoutput_decoder-0.1.0/justfile +275 -0
  23. pgoutput_decoder-0.1.0/pyproject.toml +57 -0
  24. pgoutput_decoder-0.1.0/python/pgoutput_decoder/__init__.py +112 -0
  25. pgoutput_decoder-0.1.0/python/pgoutput_decoder/exceptions.py +25 -0
  26. pgoutput_decoder-0.1.0/src/lib.rs +31 -0
  27. pgoutput_decoder-0.1.0/src/pgoutput/decoder.rs +272 -0
  28. pgoutput_decoder-0.1.0/src/pgoutput/messages.rs +272 -0
  29. pgoutput_decoder-0.1.0/src/pgoutput/mod.rs +7 -0
  30. pgoutput_decoder-0.1.0/src/pgoutput/types.rs +200 -0
  31. pgoutput_decoder-0.1.0/src/replication.rs +479 -0
  32. pgoutput_decoder-0.1.0/src/utils.rs +65 -0
  33. pgoutput_decoder-0.1.0/tests/README.md +287 -0
  34. pgoutput_decoder-0.1.0/tests/TEST_COVERAGE.md +150 -0
  35. pgoutput_decoder-0.1.0/tests/conftest.py +128 -0
  36. pgoutput_decoder-0.1.0/tests/test_acknowledgement.py +417 -0
  37. pgoutput_decoder-0.1.0/tests/test_ecommerce_comprehensive.py +852 -0
  38. pgoutput_decoder-0.1.0/tests/test_json_serialization.py +550 -0
  39. pgoutput_decoder-0.1.0/tests/test_types.py +64 -0
@@ -0,0 +1,28 @@
1
+ version: 2
2
+ updates:
3
+ # GitHub Actions
4
+ - package-ecosystem: "github-actions"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "weekly"
8
+ labels:
9
+ - "dependencies"
10
+ - "github-actions"
11
+
12
+ # Cargo dependencies
13
+ - package-ecosystem: "cargo"
14
+ directory: "/"
15
+ schedule:
16
+ interval: "weekly"
17
+ labels:
18
+ - "dependencies"
19
+ - "rust"
20
+
21
+ # Python dependencies (pip)
22
+ - package-ecosystem: "pip"
23
+ directory: "/"
24
+ schedule:
25
+ interval: "weekly"
26
+ labels:
27
+ - "dependencies"
28
+ - "python"
@@ -0,0 +1,49 @@
1
+ name: Build
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main, develop ]
8
+
9
+ jobs:
10
+ build:
11
+ name: Build - Python ${{ matrix.python-version }} on ${{ matrix.os }}
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ matrix:
15
+ os: [ubuntu-latest, macos-latest, windows-latest]
16
+ python-version: ['3.12', '3.13']
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install uv
27
+ uses: astral-sh/setup-uv@v4
28
+ with:
29
+ version: "latest"
30
+
31
+ - name: Set up Rust
32
+ uses: dtolnay/rust-toolchain@stable
33
+
34
+ - name: Cache Rust dependencies
35
+ uses: Swatinem/rust-cache@v2
36
+
37
+ - name: Build wheels
38
+ uses: PyO3/maturin-action@v1
39
+ with:
40
+ args: --release --out dist --interpreter python${{ matrix.python-version }}
41
+ sccache: 'true'
42
+ manylinux: auto
43
+
44
+ - name: Upload wheels
45
+ uses: actions/upload-artifact@v4
46
+ with:
47
+ name: wheels-${{ matrix.os }}-py${{ matrix.python-version }}
48
+ path: dist
49
+ retention-days: 7
@@ -0,0 +1,205 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main, develop ]
8
+
9
+ env:
10
+ CARGO_TERM_COLOR: always
11
+
12
+ jobs:
13
+ lint:
14
+ name: Lint
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: '3.12'
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v4
26
+ with:
27
+ version: "latest"
28
+
29
+ - name: Set up Rust
30
+ uses: dtolnay/rust-toolchain@stable
31
+ with:
32
+ components: rustfmt, clippy
33
+
34
+ - name: Cache Rust dependencies
35
+ uses: Swatinem/rust-cache@v2
36
+
37
+ - name: Install maturin
38
+ run: uv tool install maturin
39
+
40
+ - name: Rust format check
41
+ run: cargo fmt --all -- --check
42
+
43
+ - name: Rust clippy
44
+ run: cargo clippy --all-targets --all-features -- -D warnings
45
+
46
+ - name: Python format check (ruff)
47
+ run: |
48
+ uv sync
49
+ uv run ruff check .
50
+ uv run ruff format --check .
51
+
52
+ test:
53
+ name: Test - Python ${{ matrix.python-version }} on ${{ matrix.os }}
54
+ runs-on: ${{ matrix.os }}
55
+ strategy:
56
+ fail-fast: false
57
+ matrix:
58
+ os: [ubuntu-latest, macos-latest, windows-latest]
59
+ python-version: ['3.12', '3.13']
60
+
61
+ steps:
62
+ - uses: actions/checkout@v4
63
+
64
+ - name: Set up Python ${{ matrix.python-version }}
65
+ uses: actions/setup-python@v5
66
+ with:
67
+ python-version: ${{ matrix.python-version }}
68
+
69
+ - name: Install uv
70
+ uses: astral-sh/setup-uv@v4
71
+ with:
72
+ version: "latest"
73
+
74
+ - name: Set up Rust
75
+ uses: dtolnay/rust-toolchain@stable
76
+
77
+ - name: Cache Rust dependencies
78
+ uses: Swatinem/rust-cache@v2
79
+
80
+ - name: Set up Docker (for Testcontainers)
81
+ if: runner.os == 'Linux'
82
+ uses: docker/setup-buildx-action@v3
83
+
84
+ - name: Install maturin
85
+ run: uv tool install maturin
86
+
87
+ - name: Install dependencies and build
88
+ run: |
89
+ uv sync
90
+ uv run maturin develop
91
+
92
+ - name: Run tests (Linux - with Docker)
93
+ if: runner.os == 'Linux'
94
+ run: uv run pytest tests/ -v --tb=short
95
+
96
+ - name: Run tests (macOS/Windows - skip Docker tests)
97
+ if: runner.os != 'Linux'
98
+ run: uv run pytest tests/ -v --tb=short -m "not docker"
99
+
100
+ coverage:
101
+ name: Code Coverage
102
+ runs-on: ubuntu-latest
103
+
104
+ steps:
105
+ - uses: actions/checkout@v4
106
+
107
+ - name: Set up Python
108
+ uses: actions/setup-python@v5
109
+ with:
110
+ python-version: '3.12'
111
+
112
+ - name: Install uv
113
+ uses: astral-sh/setup-uv@v4
114
+ with:
115
+ version: "latest"
116
+
117
+ - name: Set up Rust
118
+ uses: dtolnay/rust-toolchain@stable
119
+ with:
120
+ components: llvm-tools-preview
121
+
122
+ - name: Cache Rust dependencies
123
+ uses: Swatinem/rust-cache@v2
124
+
125
+ - name: Set up Docker
126
+ uses: docker/setup-buildx-action@v3
127
+
128
+ - name: Install maturin
129
+ run: uv tool install maturin
130
+
131
+ - name: Install cargo-llvm-cov
132
+ uses: taiki-e/install-action@cargo-llvm-cov
133
+
134
+ - name: Install dependencies and build
135
+ run: |
136
+ uv sync
137
+ rm -f *.profraw # Clean old coverage data
138
+
139
+ - name: Build with maturin (instrumented)
140
+ run: uv tool run maturin develop
141
+ env:
142
+ RUSTFLAGS: '-C instrument-coverage'
143
+ LLVM_PROFILE_FILE: 'coverage-%p-%m.profraw'
144
+
145
+ - name: Run Python tests with coverage
146
+ run: |
147
+ uv run pytest tests/ --cov=pgoutput_decoder --cov-report=xml:python-coverage.xml --cov-report=term
148
+ env:
149
+ LLVM_PROFILE_FILE: 'coverage-%p-%m.profraw'
150
+
151
+ - name: Generate Rust coverage report
152
+ run: |
153
+ # Check if profraw files exist
154
+ ls -la *.profraw || echo "Warning: No profraw files found in workspace"
155
+ # Find llvm tools from rustc sysroot
156
+ SYSROOT=$(rustc --print sysroot)
157
+ LLVM_PROFDATA=$(find "$SYSROOT" -name llvm-profdata | head -1)
158
+ LLVM_COV=$(find "$SYSROOT" -name llvm-cov | head -1)
159
+ echo "Using llvm-profdata: $LLVM_PROFDATA"
160
+ echo "Using llvm-cov: $LLVM_COV"
161
+ # Merge profraw files
162
+ "$LLVM_PROFDATA" merge -sparse *.profraw -o coverage.profdata
163
+ # Find the compiled Python extension in target/debug (where maturin builds it)
164
+ # Exclude deps/ directory which contains Rust build dependencies
165
+ echo "Searching for Python extension in target/debug..."
166
+ EXTENSION=$(find target/debug -maxdepth 1 -type f \( -name "*.so" -o -name "*.dylib" \) 2>/dev/null | head -1)
167
+ echo "Using extension: $EXTENSION"
168
+ if [ -z "$EXTENSION" ] || [ ! -f "$EXTENSION" ]; then
169
+ echo "Error: Could not find Python extension in target/debug"
170
+ echo "Contents of target/debug:"
171
+ ls -la target/debug/ 2>/dev/null || echo "target/debug not found"
172
+ echo "Searching for all .so/.dylib files:"
173
+ find target -name "*.so" -o -name "*.dylib" 2>/dev/null || echo "No shared libraries found"
174
+ exit 1
175
+ fi
176
+ # Generate lcov report
177
+ "$LLVM_COV" export --format=lcov \
178
+ --instr-profile=coverage.profdata \
179
+ --ignore-filename-regex='/.cargo/' \
180
+ --ignore-filename-regex='/rustc/' \
181
+ "$EXTENSION" > rust-coverage.lcov
182
+ # Show summary
183
+ "$LLVM_COV" report \
184
+ --instr-profile=coverage.profdata \
185
+ --ignore-filename-regex='/.cargo/' \
186
+ --ignore-filename-regex='/rustc/' \
187
+ "$EXTENSION"
188
+
189
+ - name: Upload Python coverage to Codecov
190
+ uses: codecov/codecov-action@v5
191
+ with:
192
+ token: ${{ secrets.CODECOV_TOKEN }}
193
+ files: ./python-coverage.xml
194
+ flags: python
195
+ name: python-coverage
196
+ fail_ci_if_error: false
197
+
198
+ - name: Upload Rust coverage to Codecov
199
+ uses: codecov/codecov-action@v5
200
+ with:
201
+ token: ${{ secrets.CODECOV_TOKEN }}
202
+ files: ./rust-coverage.lcov
203
+ flags: rust
204
+ name: rust-coverage
205
+ fail_ci_if_error: false
@@ -0,0 +1,161 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*.*.*'
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: write
11
+
12
+ jobs:
13
+ build-wheels:
14
+ name: Build wheels on ${{ matrix.os }}
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ matrix:
18
+ os: [ubuntu-latest, macos-latest, windows-latest]
19
+
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v5
25
+ with:
26
+ python-version: '3.12'
27
+
28
+ - name: Install uv
29
+ uses: astral-sh/setup-uv@v4
30
+ with:
31
+ version: "latest"
32
+
33
+ - name: Build wheels
34
+ uses: PyO3/maturin-action@v1
35
+ with:
36
+ args: --release --out dist --interpreter 3.12 3.13
37
+ sccache: 'true'
38
+ manylinux: auto
39
+
40
+ - name: Upload wheels
41
+ uses: actions/upload-artifact@v4
42
+ with:
43
+ name: wheels-${{ matrix.os }}
44
+ path: dist
45
+
46
+ build-sdist:
47
+ name: Build source distribution
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - name: Set up Python
53
+ uses: actions/setup-python@v5
54
+ with:
55
+ python-version: '3.12'
56
+
57
+ - name: Install uv
58
+ uses: astral-sh/setup-uv@v4
59
+ with:
60
+ version: "latest"
61
+
62
+ - name: Build sdist
63
+ uses: PyO3/maturin-action@v1
64
+ with:
65
+ command: sdist
66
+ args: --out dist
67
+
68
+ - name: Upload sdist
69
+ uses: actions/upload-artifact@v4
70
+ with:
71
+ name: sdist
72
+ path: dist
73
+
74
+ publish-test-pypi:
75
+ name: Publish to Test PyPI
76
+ needs: [build-wheels, build-sdist]
77
+ runs-on: ubuntu-latest
78
+ if: github.event_name == 'workflow_dispatch' || contains(github.ref, 'rc') || contains(github.ref, 'beta')
79
+
80
+ environment:
81
+ name: testpypi
82
+ url: https://test.pypi.org/p/pgoutput-decoder
83
+
84
+ permissions:
85
+ id-token: write # IMPORTANT: mandatory for trusted publishing
86
+
87
+ steps:
88
+ - uses: actions/download-artifact@v4
89
+ with:
90
+ pattern: wheels-*
91
+ path: dist
92
+ merge-multiple: true
93
+
94
+ - uses: actions/download-artifact@v4
95
+ with:
96
+ name: sdist
97
+ path: dist
98
+
99
+ - name: Publish to Test PyPI
100
+ uses: pypa/gh-action-pypi-publish@release/v1
101
+ with:
102
+ repository-url: https://test.pypi.org/legacy/
103
+ skip-existing: true
104
+
105
+ publish-pypi:
106
+ name: Publish to PyPI
107
+ needs: [build-wheels, build-sdist]
108
+ runs-on: ubuntu-latest
109
+ if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'rc') && !contains(github.ref, 'beta')
110
+
111
+ environment:
112
+ name: pypi
113
+ url: https://pypi.org/p/pgoutput-decoder
114
+
115
+ permissions:
116
+ id-token: write # IMPORTANT: mandatory for trusted publishing
117
+
118
+ steps:
119
+ - uses: actions/download-artifact@v4
120
+ with:
121
+ pattern: wheels-*
122
+ path: dist
123
+ merge-multiple: true
124
+
125
+ - uses: actions/download-artifact@v4
126
+ with:
127
+ name: sdist
128
+ path: dist
129
+
130
+ - name: Publish to PyPI
131
+ uses: pypa/gh-action-pypi-publish@release/v1
132
+ with:
133
+ skip-existing: true
134
+
135
+ create-github-release:
136
+ name: Create GitHub Release
137
+ needs: [publish-pypi]
138
+ runs-on: ubuntu-latest
139
+ if: startsWith(github.ref, 'refs/tags/v')
140
+
141
+ steps:
142
+ - uses: actions/checkout@v4
143
+
144
+ - uses: actions/download-artifact@v4
145
+ with:
146
+ pattern: wheels-*
147
+ path: dist
148
+ merge-multiple: true
149
+
150
+ - uses: actions/download-artifact@v4
151
+ with:
152
+ name: sdist
153
+ path: dist
154
+
155
+ - name: Create Release
156
+ uses: softprops/action-gh-release@v1
157
+ with:
158
+ files: dist/*
159
+ generate_release_notes: true
160
+ draft: false
161
+ prerelease: false
@@ -0,0 +1,29 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ dist/
6
+ wheels/
7
+ *.egg-info
8
+
9
+ # Virtual environments
10
+ .venv
11
+
12
+ # Coverage reports
13
+ htmlcov/
14
+ .coverage
15
+ coverage.xml
16
+ .pytest_cache/
17
+
18
+ # Rust-generated files
19
+ target/
20
+ Cargo.lock
21
+ *.so
22
+ *.pyd
23
+ *.dylib
24
+
25
+ # IDE
26
+ .idea/
27
+ .vscode/
28
+ *.swp
29
+ *.swo
@@ -0,0 +1,37 @@
1
+ repos:
2
+ # Rust formatting and linting
3
+ - repo: local
4
+ hooks:
5
+ - id: cargo-fmt
6
+ name: cargo fmt
7
+ entry: cargo fmt
8
+ language: system
9
+ types: [rust]
10
+ pass_filenames: false
11
+
12
+ - id: cargo-clippy
13
+ name: cargo clippy
14
+ entry: cargo clippy --all-targets --all-features -- -D warnings
15
+ language: system
16
+ types: [rust]
17
+ pass_filenames: false
18
+
19
+ # Python formatting and linting via ruff
20
+ - repo: https://github.com/astral-sh/ruff-pre-commit
21
+ rev: v0.8.4
22
+ hooks:
23
+ - id: ruff
24
+ args: [--fix]
25
+ - id: ruff-format
26
+
27
+ # General file checks
28
+ - repo: https://github.com/pre-commit/pre-commit-hooks
29
+ rev: v5.0.0
30
+ hooks:
31
+ - id: trailing-whitespace
32
+ - id: end-of-file-fixer
33
+ - id: check-yaml
34
+ - id: check-toml
35
+ - id: check-merge-conflict
36
+ - id: check-added-large-files
37
+ args: ['--maxkb=1000']
@@ -0,0 +1,125 @@
1
+ 🤖 Project Persona
2
+ You are an expert full-stack developer specializing in high-performance Python/Rust systems. You prioritize memory safety, type correctness, and efficient dependency management.
3
+
4
+ 🛠 Tech Stack
5
+ Package Manager: uv (use uv run, uv sync, uv add)
6
+
7
+ Linter/Formatter: ruff
8
+
9
+ Backend: Rust (using PyO3 for bindings)
10
+
11
+ Build System: maturin
12
+
13
+ Testing: pytest + Testcontainers (for E2E)
14
+
15
+ 📂 Project Structure
16
+ Plaintext
17
+ .
18
+ ├── Cargo.toml # Rust metadata & dependencies
19
+ ├── pyproject.toml # Python metadata, Ruff config, Maturin settings
20
+ ├── justfile # Task runner for common commands
21
+ ├── .pre-commit-config.yaml # Pre-commit hooks configuration
22
+ ├── src/ # Rust source code
23
+ │ └── lib.rs # PyO3 module definitions
24
+ ├── python/ # Python source code
25
+ │ └── my_project/ # Main Python package
26
+ │ ├── __init__.py
27
+ │ └── core.py
28
+ ├── tests/ # E2E and Unit tests
29
+ │ └── e2e/ # Testcontainers-based tests
30
+ ├── .vscode/settings.json # VS Code configuration
31
+ └── .python-version # Managed by uv
32
+ 🚀 Development Workflow
33
+ 1. Setup & Installation
34
+ Always use uv for environment management.
35
+
36
+ Sync environment: uv sync
37
+
38
+ Build Rust bindings (dev): uv run maturin develop (This installs the Rust module into the current venv).
39
+
40
+ Quick setup: just setup (requires just: brew install just)
41
+
42
+ 2. Linting & Formatting
43
+ We use ruff for everything Python and clippy for Rust.
44
+
45
+ **Recommended**: Use pre-commit hooks to catch issues before commit:
46
+
47
+ bash
48
+ # One-time setup
49
+ pip install pre-commit
50
+ pre-commit install
51
+
52
+ # Manual run
53
+ pre-commit run --all-files
54
+
55
+
56
+ **Manual checks:**
57
+
58
+ Python:
59
+ - Check: uv run ruff check .
60
+ - Format: uv run ruff format .
61
+
62
+ Rust:
63
+ - Format: cargo fmt
64
+ - Lint: cargo clippy --all-targets --all-features -- -D warnings
65
+
66
+ **Quick commands** (requires just):
67
+ - just check - Run all checks
68
+ - just lint - Run all linters
69
+ - just fmt - Format all code
70
+ - just pre-commit - Full pre-commit check
71
+
72
+ **Auto-watch mode** (requires cargo-watch):
73
+ bash
74
+ just watch # Auto-run clippy on file changes
75
+
76
+ Always run just check or pre-commit before pushing to avoid CI failures.
77
+
78
+
79
+ 3. Testing
80
+ Run all tests: uv run pytest
81
+
82
+ E2E Tests: Ensure Docker is running, as these use Testcontainers.
83
+
84
+ Note: Use the testcontainers[postgres] (or relevant module) in pyproject.toml.
85
+
86
+ Quick: just test (runs both Rust and Python tests)
87
+
88
+ 📝 Coding Standards
89
+ Rust Bindings: Prefer #[pyfunction] and #[pymodule]. Avoid manual type conversions; let PyO3 handle the heavy lifting where possible.
90
+
91
+ Python Types: Strict type hinting is mandatory. All function signatures must have type hints.
92
+
93
+ Testing Pattern:
94
+
95
+ Use @pytest.fixture for Testcontainers setup.
96
+
97
+ Keep E2E tests in tests/e2e/ to separate them from fast unit tests.
98
+
99
+ Performance: If a Python loop is identified as a bottleneck, move the logic to the Rust src/ directory.
100
+
101
+ ⚠️ Constraints
102
+ Never use pip or venv directly. Always go through uv.
103
+
104
+ Never commit the .venv directory or Rust target/ binaries.
105
+
106
+ Do not add heavy Python dependencies if the logic can be implemented efficiently in Rust.
107
+
108
+ 💡 Example: End-to-End Test with Testcontainers
109
+ When writing E2E tests, follow this pattern:
110
+
111
+ Python
112
+ import pytest
113
+ from testcontainers.postgres import PostgresContainer
114
+ from my_project import rust_backend # Your PyO3 module
115
+
116
+ @pytest.fixture(scope="module")
117
+ def db_container():
118
+ with PostgresContainer("postgres:18.1-alpine") as postgres:
119
+ yield postgres
120
+
121
+ def test_rust_db_integration(db_container):
122
+ conn_str = db_container.get_connection_url()
123
+ # Logic calling your Rust bindings to interact with the container
124
+ result = rust_backend.process_data_in_db(conn_str)
125
+ assert result is True