batchcorder 0.1.0__tar.gz → 0.1.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.
- batchcorder-0.1.2/.github/release-drafter.yml +78 -0
- batchcorder-0.1.2/.github/workflows/ci-test.yaml +188 -0
- batchcorder-0.1.2/.github/workflows/release-drafter.yml +24 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.gitignore +2 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.pre-commit-config.yaml +2 -2
- batchcorder-0.1.2/CLAUDE.md +326 -0
- batchcorder-0.1.2/CONTRIBUTING.md +326 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/Cargo.lock +95 -840
- {batchcorder-0.1.0 → batchcorder-0.1.2}/Cargo.toml +6 -10
- {batchcorder-0.1.0 → batchcorder-0.1.2}/PKG-INFO +41 -25
- {batchcorder-0.1.0 → batchcorder-0.1.2}/README.md +37 -22
- batchcorder-0.1.2/conftest.py +8 -0
- batchcorder-0.1.2/docs/quarto/_quarto.yml +13 -0
- batchcorder-0.1.2/docs/quarto/how-to/cache-config.qmd +87 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/docs/quarto/how-to/duckdb.qmd +4 -8
- batchcorder-0.1.2/docs/quarto/how-to/eviction.qmd +84 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/docs/quarto/reference/api-overview.qmd +3 -2
- {batchcorder-0.1.0 → batchcorder-0.1.2}/docs/quarto/tutorials/getting-started.qmd +11 -10
- batchcorder-0.1.2/docs/requirements.txt +481 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/docs/source/index.rst +2 -2
- {batchcorder-0.1.0 → batchcorder-0.1.2}/pyproject.toml +33 -7
- {batchcorder-0.1.0 → batchcorder-0.1.2}/python/batchcorder/__init__.py +92 -52
- {batchcorder-0.1.0 → batchcorder-0.1.2}/python/batchcorder/_batchcorder.pyi +15 -15
- batchcorder-0.1.2/rust-toolchain.toml +3 -0
- batchcorder-0.1.2/scripts/build-release.sh +40 -0
- batchcorder-0.1.2/src/cached_dataset.rs +902 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/src/lib.rs +4 -6
- {batchcorder-0.1.0 → batchcorder-0.1.2}/tests/test_as_record_batch_reader.py +12 -31
- {batchcorder-0.1.0 → batchcorder-0.1.2}/tests/test_cast.py +2 -2
- {batchcorder-0.1.0 → batchcorder-0.1.2}/tests/test_duckdb.py +6 -7
- {batchcorder-0.1.0 → batchcorder-0.1.2}/tests/test_errors.py +13 -13
- batchcorder-0.1.2/tests/test_performance.py +333 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/tests/test_stream_cache.py +194 -14
- batchcorder-0.1.2/uv.lock +3384 -0
- batchcorder-0.1.0/.github/workflows/ci-test.yaml +0 -74
- batchcorder-0.1.0/_typos.toml +0 -5
- batchcorder-0.1.0/docs/quarto/_quarto.yml +0 -13
- batchcorder-0.1.0/docs/quarto/how-to/cache-config.qmd +0 -111
- batchcorder-0.1.0/docs/quarto/how-to/eviction.qmd +0 -105
- batchcorder-0.1.0/docs/requirements.txt +0 -110
- batchcorder-0.1.0/src/cached_dataset.rs +0 -739
- batchcorder-0.1.0/uv.lock +0 -1643
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.github/workflows/build-wheels.yaml +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.github/workflows/ci-lint.yaml +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.github/workflows/ci-pre-release.yaml +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.github/workflows/ci-release.yaml +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.readthedocs.yaml +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/.yamllint.yaml +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/LICENSE +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/Makefile +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/docs/quarto/.gitignore +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/docs/source/api.rst +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/docs/source/conf.py +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/python/batchcorder/py.typed +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/scripts/build-docs.sh +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/src/bin/stub_gen.rs +0 -0
- {batchcorder-0.1.0 → batchcorder-0.1.2}/tests/test_docstrings.py +0 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
exclude-labels:
|
|
2
|
+
- ignore
|
|
3
|
+
- release
|
|
4
|
+
- dependencies
|
|
5
|
+
name-template: 'batchcorder unreleased'
|
|
6
|
+
version-template: unreleased
|
|
7
|
+
|
|
8
|
+
change-template: '- $TITLE (#$NUMBER)'
|
|
9
|
+
|
|
10
|
+
autolabeler:
|
|
11
|
+
- label: 'release'
|
|
12
|
+
title:
|
|
13
|
+
- '/^release:/i'
|
|
14
|
+
- label: 'dependencies'
|
|
15
|
+
title:
|
|
16
|
+
- '/^chore\(deps\):/i'
|
|
17
|
+
- '/^fix\(deps\):/i'
|
|
18
|
+
- label: 'perf'
|
|
19
|
+
title:
|
|
20
|
+
- '/^perf(\(.*\))?:/i'
|
|
21
|
+
- label: 'feature'
|
|
22
|
+
title:
|
|
23
|
+
- '/^feat(\(.*\))?:/i'
|
|
24
|
+
- label: 'fix'
|
|
25
|
+
title:
|
|
26
|
+
- '/^fix(\(.*\))?:/i'
|
|
27
|
+
- label: 'docs'
|
|
28
|
+
title:
|
|
29
|
+
- '/^docs(\(.*\))?:/i'
|
|
30
|
+
- '/^chore\(docs\):/i'
|
|
31
|
+
- label: 'ci'
|
|
32
|
+
title:
|
|
33
|
+
- '/^ci(\(.*\))?:/i'
|
|
34
|
+
- '/^chore\(ci\):/i'
|
|
35
|
+
- label: 'chore'
|
|
36
|
+
title:
|
|
37
|
+
- '/^chore(\(.*\))?:/i'
|
|
38
|
+
- label: 'internal'
|
|
39
|
+
title:
|
|
40
|
+
- '/^ref(\(.*\))?:/i'
|
|
41
|
+
- '/^refactor(\(.*\))?:/i'
|
|
42
|
+
- '/^spike(\(.*\))?:/i'
|
|
43
|
+
|
|
44
|
+
categories:
|
|
45
|
+
- title: 🚀 Performance improvements
|
|
46
|
+
labels:
|
|
47
|
+
- performance
|
|
48
|
+
- perf
|
|
49
|
+
- title: ✨ Enhancements
|
|
50
|
+
labels:
|
|
51
|
+
- feature
|
|
52
|
+
- enhancement
|
|
53
|
+
- title: 🐞 Bug fixes
|
|
54
|
+
labels:
|
|
55
|
+
- fix
|
|
56
|
+
- bugfix
|
|
57
|
+
- bug
|
|
58
|
+
- title: 📖 Documentation
|
|
59
|
+
labels:
|
|
60
|
+
- documentation
|
|
61
|
+
- docs
|
|
62
|
+
- title: 📦 Build system
|
|
63
|
+
labels:
|
|
64
|
+
- build
|
|
65
|
+
- ci
|
|
66
|
+
- chore
|
|
67
|
+
- title: 🛠️ Other improvements
|
|
68
|
+
labels:
|
|
69
|
+
- internal
|
|
70
|
+
- maintenance
|
|
71
|
+
|
|
72
|
+
template: |
|
|
73
|
+
## Changes
|
|
74
|
+
|
|
75
|
+
$CHANGES
|
|
76
|
+
|
|
77
|
+
Thank you to all our contributors for making this release possible!
|
|
78
|
+
$CONTRIBUTORS
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
name: ci-test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths-ignore:
|
|
6
|
+
- "docs/**"
|
|
7
|
+
- "**/*.md"
|
|
8
|
+
- "*.md"
|
|
9
|
+
- ".envrc"
|
|
10
|
+
branches:
|
|
11
|
+
- main
|
|
12
|
+
tags:
|
|
13
|
+
- '*'
|
|
14
|
+
pull_request:
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
linux:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
env:
|
|
24
|
+
UV_NO_SYNC: "1"
|
|
25
|
+
strategy:
|
|
26
|
+
matrix:
|
|
27
|
+
# requires-python = ">=3.10"; test the floor and the latest stable.
|
|
28
|
+
python-version: ["3.10", "3.13"]
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
|
|
32
|
+
- name: Update Rust stable
|
|
33
|
+
run: rustup update stable && rustup component add llvm-tools-preview
|
|
34
|
+
|
|
35
|
+
- uses: actions/setup-python@v5
|
|
36
|
+
with:
|
|
37
|
+
python-version: ${{ matrix.python-version }}
|
|
38
|
+
|
|
39
|
+
- uses: astral-sh/setup-uv@v5
|
|
40
|
+
with:
|
|
41
|
+
enable-cache: true
|
|
42
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
43
|
+
|
|
44
|
+
- name: Install cargo-llvm-cov
|
|
45
|
+
uses: taiki-e/install-action@v2
|
|
46
|
+
with:
|
|
47
|
+
tool: cargo-llvm-cov
|
|
48
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
49
|
+
|
|
50
|
+
- name: Cargo cache
|
|
51
|
+
uses: actions/cache@v4
|
|
52
|
+
with:
|
|
53
|
+
path: |
|
|
54
|
+
~/.cargo/registry/index/
|
|
55
|
+
~/.cargo/registry/cache/
|
|
56
|
+
~/.cargo/git/db/
|
|
57
|
+
./target/
|
|
58
|
+
# abi3-py310 produces a single binary regardless of Python version,
|
|
59
|
+
# so the cache key does not include python-version.
|
|
60
|
+
key: cargo-test-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
|
|
61
|
+
restore-keys: cargo-test-
|
|
62
|
+
|
|
63
|
+
# --no-install-project: maturin develop handles the batchcorder install.
|
|
64
|
+
- name: Install Python dependencies
|
|
65
|
+
run: uv sync --locked --group dev --no-install-project
|
|
66
|
+
|
|
67
|
+
- name: Build and test with coverage
|
|
68
|
+
env:
|
|
69
|
+
CARGO_INCREMENTAL: "1"
|
|
70
|
+
run: |
|
|
71
|
+
eval "$(cargo llvm-cov show-env --export-prefix)"
|
|
72
|
+
cargo llvm-cov clean --workspace
|
|
73
|
+
cargo test
|
|
74
|
+
uv run maturin develop --uv
|
|
75
|
+
uv run pytest --import-mode=importlib --cov --cov-report=xml
|
|
76
|
+
cargo llvm-cov report --lcov --output-path coverage.lcov
|
|
77
|
+
|
|
78
|
+
- name: Upload coverage to Codecov
|
|
79
|
+
uses: codecov/codecov-action@v5.4.0
|
|
80
|
+
with:
|
|
81
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
82
|
+
files: coverage.xml,coverage.lcov
|
|
83
|
+
|
|
84
|
+
windows:
|
|
85
|
+
runs-on: windows-latest
|
|
86
|
+
env:
|
|
87
|
+
UV_NO_SYNC: "1"
|
|
88
|
+
strategy:
|
|
89
|
+
matrix:
|
|
90
|
+
python-version: ["3.13"]
|
|
91
|
+
steps:
|
|
92
|
+
- uses: actions/checkout@v4
|
|
93
|
+
|
|
94
|
+
- name: Update Rust stable
|
|
95
|
+
run: rustup update stable && rustup component add llvm-tools-preview
|
|
96
|
+
|
|
97
|
+
- uses: actions/setup-python@v5
|
|
98
|
+
with:
|
|
99
|
+
python-version: ${{ matrix.python-version }}
|
|
100
|
+
|
|
101
|
+
- uses: astral-sh/setup-uv@v5
|
|
102
|
+
with:
|
|
103
|
+
enable-cache: true
|
|
104
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
105
|
+
|
|
106
|
+
- name: Install cargo-llvm-cov
|
|
107
|
+
uses: taiki-e/install-action@v2
|
|
108
|
+
with:
|
|
109
|
+
tool: cargo-llvm-cov
|
|
110
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
111
|
+
|
|
112
|
+
- name: Cargo cache
|
|
113
|
+
uses: actions/cache@v4
|
|
114
|
+
with:
|
|
115
|
+
path: |
|
|
116
|
+
~/.cargo/registry/index/
|
|
117
|
+
~/.cargo/registry/cache/
|
|
118
|
+
~/.cargo/git/db/
|
|
119
|
+
./target/
|
|
120
|
+
key: cargo-test-windows-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
|
|
121
|
+
restore-keys: cargo-test-windows-
|
|
122
|
+
|
|
123
|
+
- name: Install Python dependencies
|
|
124
|
+
run: uv sync --locked --group dev --no-install-project
|
|
125
|
+
|
|
126
|
+
- name: Build and test with coverage
|
|
127
|
+
shell: bash
|
|
128
|
+
env:
|
|
129
|
+
CARGO_INCREMENTAL: "1"
|
|
130
|
+
run: |
|
|
131
|
+
eval "$(cargo llvm-cov show-env --export-prefix)"
|
|
132
|
+
cargo llvm-cov clean --workspace
|
|
133
|
+
cargo test
|
|
134
|
+
uv run maturin develop --uv
|
|
135
|
+
uv run pytest --import-mode=importlib --cov --cov-report=xml
|
|
136
|
+
cargo llvm-cov report --lcov --output-path coverage.lcov
|
|
137
|
+
|
|
138
|
+
- name: Upload coverage to Codecov
|
|
139
|
+
uses: codecov/codecov-action@v5.4.0
|
|
140
|
+
with:
|
|
141
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
142
|
+
files: coverage.xml,coverage.lcov
|
|
143
|
+
|
|
144
|
+
macos:
|
|
145
|
+
runs-on: macos-latest
|
|
146
|
+
env:
|
|
147
|
+
UV_NO_SYNC: "1"
|
|
148
|
+
strategy:
|
|
149
|
+
matrix:
|
|
150
|
+
python-version: ["3.10", "3.13"]
|
|
151
|
+
steps:
|
|
152
|
+
- uses: actions/checkout@v4
|
|
153
|
+
|
|
154
|
+
- name: Update Rust stable
|
|
155
|
+
run: rustup update stable
|
|
156
|
+
|
|
157
|
+
- uses: actions/setup-python@v5
|
|
158
|
+
with:
|
|
159
|
+
python-version: ${{ matrix.python-version }}
|
|
160
|
+
|
|
161
|
+
- uses: astral-sh/setup-uv@v5
|
|
162
|
+
with:
|
|
163
|
+
enable-cache: true
|
|
164
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
165
|
+
|
|
166
|
+
- name: Cargo cache
|
|
167
|
+
uses: actions/cache@v4
|
|
168
|
+
with:
|
|
169
|
+
path: |
|
|
170
|
+
~/.cargo/registry/index/
|
|
171
|
+
~/.cargo/registry/cache/
|
|
172
|
+
~/.cargo/git/db/
|
|
173
|
+
./target/
|
|
174
|
+
key: cargo-test-macos-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
|
|
175
|
+
restore-keys: cargo-test-macos-
|
|
176
|
+
|
|
177
|
+
- name: Install Python dependencies
|
|
178
|
+
run: uv sync --locked --group dev --no-install-project
|
|
179
|
+
|
|
180
|
+
- name: Build extension
|
|
181
|
+
uses: PyO3/maturin-action@v1
|
|
182
|
+
with:
|
|
183
|
+
command: develop
|
|
184
|
+
args: --release --strip --uv
|
|
185
|
+
sccache: 'true'
|
|
186
|
+
|
|
187
|
+
- name: Run tests
|
|
188
|
+
run: uv run pytest --import-mode=importlib
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: release-drafter
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
types: [opened, reopened, synchronize, labeled, unlabeled]
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
update-release-draft:
|
|
15
|
+
permissions:
|
|
16
|
+
contents: write # to create/update draft release
|
|
17
|
+
pull-requests: write # to add labels to PRs
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: release-drafter/release-drafter@v6
|
|
21
|
+
with:
|
|
22
|
+
config-name: release-drafter.yml
|
|
23
|
+
env:
|
|
24
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -66,7 +66,7 @@ repos:
|
|
|
66
66
|
rev: v0.11.0.1
|
|
67
67
|
hooks:
|
|
68
68
|
- id: shellcheck
|
|
69
|
-
args: ["scripts/build-docs.sh"]
|
|
69
|
+
args: ["scripts/build-docs.sh", "scripts/build-release.sh"]
|
|
70
70
|
|
|
71
71
|
- repo: local
|
|
72
72
|
hooks:
|
|
@@ -110,7 +110,7 @@ repos:
|
|
|
110
110
|
- id: mypy-stubtest
|
|
111
111
|
name: mypy stubtest
|
|
112
112
|
description: Validate _batchcorder.pyi matches the compiled extension at runtime.
|
|
113
|
-
entry: .venv/bin/python -m mypy.stubtest batchcorder._batchcorder
|
|
113
|
+
entry: .venv/bin/python -m mypy.stubtest --mypy-config-file pyproject.toml batchcorder._batchcorder
|
|
114
114
|
language: system
|
|
115
115
|
pass_filenames: false
|
|
116
116
|
types_or: [python, pyi]
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
# batchcorder Repository
|
|
2
|
+
|
|
3
|
+
This repository contains batchcorder, a Rust-backed Python library for caching Arrow record-batch streams so they can be replayed multiple times from a source that can only be read once.
|
|
4
|
+
|
|
5
|
+
## 📦 Architecture
|
|
6
|
+
|
|
7
|
+
The project consists of:
|
|
8
|
+
|
|
9
|
+
- **Python API** (`python/`): Python interface and bindings
|
|
10
|
+
- **Rust Core** (`src/`): Core implementation in Rust using PyO3 for Python bindings
|
|
11
|
+
- **Tests** (`tests/`): Test suite for verifying functionality
|
|
12
|
+
- **Documentation** (`docs/`): Project documentation
|
|
13
|
+
|
|
14
|
+
The Rust core implements the `StreamCache` functionality using:
|
|
15
|
+
- Arrow C Stream interface for compatibility
|
|
16
|
+
- Arrow IPC stream format for on-disk serialisation
|
|
17
|
+
- PyO3 for Python interoperability
|
|
18
|
+
|
|
19
|
+
## 🚀 Getting Started
|
|
20
|
+
|
|
21
|
+
### Prerequisites
|
|
22
|
+
|
|
23
|
+
- Python 3.11+
|
|
24
|
+
- Rust toolchain (stable)
|
|
25
|
+
- `uv` for dependency management
|
|
26
|
+
|
|
27
|
+
### Setup Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Install dependencies without building the extension
|
|
31
|
+
uv sync --no-install-project --dev
|
|
32
|
+
|
|
33
|
+
# For docs development, include docs group
|
|
34
|
+
uv sync --no-install-project --dev --group docs
|
|
35
|
+
|
|
36
|
+
# Build the extension
|
|
37
|
+
uv run maturin develop --uv
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Environment variables
|
|
41
|
+
|
|
42
|
+
Set `UV_NO_SYNC=1` in your shell so that `uv run` never re-syncs the
|
|
43
|
+
virtual environment on every invocation:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
export UV_NO_SYNC=1
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Add this to your shell profile (`.bashrc`, `.zshrc`, etc.) to make it
|
|
50
|
+
permanent for this project.
|
|
51
|
+
|
|
52
|
+
## 🧪 Testing
|
|
53
|
+
|
|
54
|
+
### Run Tests
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Run all tests
|
|
58
|
+
uv run pytest
|
|
59
|
+
|
|
60
|
+
# Run specific test files or modules
|
|
61
|
+
uv run pytest tests/test_module.py
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Testing Guidelines
|
|
65
|
+
|
|
66
|
+
- All changes must be tested
|
|
67
|
+
- Look to see if your tests could go in an existing file before adding a new file
|
|
68
|
+
- Get your tests to pass before committing
|
|
69
|
+
- Run `uv run pre-commit run --all-files` before pushing code
|
|
70
|
+
|
|
71
|
+
## 📝 Code Style
|
|
72
|
+
|
|
73
|
+
### Rust Guidelines
|
|
74
|
+
|
|
75
|
+
- Avoid patterns that require `panic!`, `unreachable!`, or `.unwrap()`
|
|
76
|
+
- Prefer let chains (`if let` combined with `&&`) over nested `if let` statements
|
|
77
|
+
- Use `#[expect()]` over `[allow()]` for suppressing Clippy lints
|
|
78
|
+
- Use comments purposefully to explain invariants and unusual decisions
|
|
79
|
+
|
|
80
|
+
### Python Guidelines
|
|
81
|
+
|
|
82
|
+
- Follow existing code style in neighboring files
|
|
83
|
+
- Use type hints where appropriate
|
|
84
|
+
- Keep functions small and focused
|
|
85
|
+
|
|
86
|
+
### Code Examples
|
|
87
|
+
|
|
88
|
+
```rust
|
|
89
|
+
// ✅ Good: Proper error handling with let chains
|
|
90
|
+
if let Some(value) = optional_value && value.is_valid() {
|
|
91
|
+
// Handle valid value
|
|
92
|
+
process_value(value);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// ❌ Bad: Nested if let statements
|
|
96
|
+
if let Some(value) = optional_value {
|
|
97
|
+
if value.is_valid() {
|
|
98
|
+
// Handle valid value
|
|
99
|
+
process_value(value);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
# ✅ Good: Type hints and clear function naming
|
|
106
|
+
def calculate_total(items: List[Item]) -> float:
|
|
107
|
+
"""Calculate the total price of items."""
|
|
108
|
+
return sum(item.price for item in items)
|
|
109
|
+
|
|
110
|
+
# ❌ Bad: No type hints, vague function name
|
|
111
|
+
def process(x):
|
|
112
|
+
# Process something
|
|
113
|
+
pass
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 📂 Project Structure
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
batchcorder/
|
|
120
|
+
├── python/ # Python API and bindings
|
|
121
|
+
├── src/ # Rust core implementation
|
|
122
|
+
├── tests/ # Test suite
|
|
123
|
+
├── docs/ # Documentation
|
|
124
|
+
├── CONTRIBUTING.md # Contribution guidelines (this file)
|
|
125
|
+
└── README.md # Human-readable overview
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 🔧 Development Workflow
|
|
129
|
+
|
|
130
|
+
1. **Create a feature branch**: `git checkout -b feature/your-feature`
|
|
131
|
+
2. **Make changes**: Follow code style guidelines
|
|
132
|
+
3. **Run tests**: `uv run pytest`
|
|
133
|
+
4. **Run pre-commit**: `uv run pre-commit run --all-files`
|
|
134
|
+
5. **Commit changes**: Use clear, descriptive commit messages
|
|
135
|
+
6. **Push and create PR**: Get code review before merging
|
|
136
|
+
|
|
137
|
+
## 🚢 Releasing
|
|
138
|
+
|
|
139
|
+
### Prerequisites
|
|
140
|
+
|
|
141
|
+
Install `cargo-edit` for version bumping:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
cargo install cargo-edit
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Release Process
|
|
148
|
+
|
|
149
|
+
Use the release script, passing the bump type as an argument:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
bash scripts/build-release.sh <major|minor|patch>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
This will:
|
|
156
|
+
1. Switch to upstream `main` and pull the latest changes
|
|
157
|
+
2. Bump the version in `Cargo.toml` using `cargo set-version --bump`
|
|
158
|
+
3. Create a `release-<version>` branch
|
|
159
|
+
4. Commit the version change
|
|
160
|
+
5. Push the branch to upstream
|
|
161
|
+
|
|
162
|
+
## 🛑 Boundaries
|
|
163
|
+
|
|
164
|
+
### Never Touch
|
|
165
|
+
|
|
166
|
+
- `.env*` files - Environment variables
|
|
167
|
+
- `target/` - Rust build artifacts
|
|
168
|
+
- `__pycache__/` - Python cache files
|
|
169
|
+
- `node_modules/` - Node.js dependencies (if any)
|
|
170
|
+
- `*.lock` files - Dependency lock files
|
|
171
|
+
|
|
172
|
+
### Always Do
|
|
173
|
+
|
|
174
|
+
- Write tests for new functionality
|
|
175
|
+
- Run existing tests before committing
|
|
176
|
+
- Follow code style guidelines
|
|
177
|
+
- Document public APIs
|
|
178
|
+
|
|
179
|
+
### Ask First
|
|
180
|
+
|
|
181
|
+
- Major architectural changes
|
|
182
|
+
- Breaking changes to public APIs
|
|
183
|
+
- Changes to CI/CD configuration
|
|
184
|
+
- Dependency updates
|
|
185
|
+
|
|
186
|
+
## 📖 Documentation
|
|
187
|
+
|
|
188
|
+
### Dependencies
|
|
189
|
+
|
|
190
|
+
Documentation requires:
|
|
191
|
+
- Quarto for rendering .qmd files to Markdown
|
|
192
|
+
- Sphinx for building HTML documentation
|
|
193
|
+
- Python dependencies listed in `docs/requirements.txt`
|
|
194
|
+
|
|
195
|
+
Install documentation dependencies:
|
|
196
|
+
```bash
|
|
197
|
+
uv sync --no-install-project --dev --group docs
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Building Documentation
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
# Render Quarto files to Markdown
|
|
204
|
+
make quarto
|
|
205
|
+
|
|
206
|
+
# Build Sphinx HTML documentation
|
|
207
|
+
make sphinx
|
|
208
|
+
|
|
209
|
+
# Build both (quarto + sphinx)
|
|
210
|
+
make docs
|
|
211
|
+
|
|
212
|
+
# Clean documentation build artifacts
|
|
213
|
+
make clean-docs
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Quarto Usage
|
|
217
|
+
|
|
218
|
+
- Quarto source files are in `docs/quarto/`
|
|
219
|
+
- Configuration in `docs/quarto/_quarto.yml`
|
|
220
|
+
- Code execution is disabled in Quarto (requires compiled Rust extension)
|
|
221
|
+
- Output directory: `docs/source/`
|
|
222
|
+
|
|
223
|
+
### Documentation Structure
|
|
224
|
+
|
|
225
|
+
```
|
|
226
|
+
docs/
|
|
227
|
+
├── quarto/ # Quarto source files (.qmd)
|
|
228
|
+
│ ├── how-to/ # How-to guides
|
|
229
|
+
│ ├── reference/ # Reference documentation
|
|
230
|
+
│ ├── tutorials/ # Tutorials
|
|
231
|
+
│ └── _quarto.yml # Quarto configuration
|
|
232
|
+
├── source/ # Generated Markdown files
|
|
233
|
+
├── build/ # Built HTML documentation
|
|
234
|
+
├── requirements.txt # Documentation dependencies
|
|
235
|
+
└── Makefile # Documentation build targets
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Documentation Guidelines
|
|
239
|
+
|
|
240
|
+
- Write for a developer audience
|
|
241
|
+
- Focus on clarity and practical examples
|
|
242
|
+
- Keep documentation up-to-date with code changes
|
|
243
|
+
- Use Markdown format for documentation files
|
|
244
|
+
- Follow the structure defined in Quarto configuration
|
|
245
|
+
|
|
246
|
+
## 🤖 Agent-Specific Instructions
|
|
247
|
+
|
|
248
|
+
### For Coding Agents
|
|
249
|
+
|
|
250
|
+
- You are a Rust/Python developer working on the batchcorder project
|
|
251
|
+
- Focus on the Rust core (`src/`) and Python bindings (`python/`)
|
|
252
|
+
- Follow the existing architecture and patterns
|
|
253
|
+
- Never modify files outside the project scope
|
|
254
|
+
|
|
255
|
+
### For Documentation Agents
|
|
256
|
+
|
|
257
|
+
- You are a technical writer for the batchcorder project
|
|
258
|
+
- Read code from `src/` and `python/` to understand functionality
|
|
259
|
+
- Write documentation in `docs/quarto/` using Quarto format
|
|
260
|
+
- Follow the documentation guidelines above
|
|
261
|
+
|
|
262
|
+
### For Testing Agents
|
|
263
|
+
|
|
264
|
+
- You are a QA engineer for the batchcorder project
|
|
265
|
+
- Write tests in the `tests/` directory
|
|
266
|
+
- Ensure tests cover edge cases and error conditions
|
|
267
|
+
- Never remove failing tests without authorization
|
|
268
|
+
|
|
269
|
+
## 🔄 Version Control
|
|
270
|
+
|
|
271
|
+
### Git Workflow
|
|
272
|
+
|
|
273
|
+
- Use feature branches for new functionality
|
|
274
|
+
- Use fix branches for bug fixes
|
|
275
|
+
- Create draft PRs for work-in-progress
|
|
276
|
+
- Require at least one approval before merging
|
|
277
|
+
- Squash merge for clean history
|
|
278
|
+
|
|
279
|
+
### Commit Message Format
|
|
280
|
+
|
|
281
|
+
```
|
|
282
|
+
<type>(<scope>): <subject>
|
|
283
|
+
<BLANK LINE>
|
|
284
|
+
<body>
|
|
285
|
+
<BLANK LINE>
|
|
286
|
+
<footer>
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Where:
|
|
290
|
+
- `type`: feat, fix, docs, style, refactor, perf, test, chore
|
|
291
|
+
- `scope`: module or component affected
|
|
292
|
+
- `subject`: brief description of changes
|
|
293
|
+
- `body`: detailed explanation (optional)
|
|
294
|
+
- `footer`: breaking changes or issue references (optional)
|
|
295
|
+
|
|
296
|
+
## 🔒 Security
|
|
297
|
+
|
|
298
|
+
### Security Guidelines
|
|
299
|
+
|
|
300
|
+
- Never commit secrets or API keys
|
|
301
|
+
- Keep dependencies up-to-date
|
|
302
|
+
- Follow Rust's security best practices
|
|
303
|
+
- Use secure coding practices in Python
|
|
304
|
+
|
|
305
|
+
## 📚 Resources
|
|
306
|
+
|
|
307
|
+
- [Arrow Documentation](https://arrow.apache.org/docs/)
|
|
308
|
+
- [PyO3 Documentation](https://pyo3.rs/)
|
|
309
|
+
- [Rust Documentation](https://doc.rust-lang.org/)
|
|
310
|
+
- [Python Documentation](https://docs.python.org/3/)
|
|
311
|
+
- [Quarto Documentation](https://quarto.org/docs/)
|
|
312
|
+
- [Sphinx Documentation](https://www.sphinx-doc.org/)
|
|
313
|
+
|
|
314
|
+
## 🤝 Contributing
|
|
315
|
+
|
|
316
|
+
We welcome contributions! Please:
|
|
317
|
+
|
|
318
|
+
1. Read the CONTRIBUTING.md file thoroughly
|
|
319
|
+
2. Follow the development guidelines
|
|
320
|
+
3. Write tests for your changes
|
|
321
|
+
4. Submit a pull request with clear description
|
|
322
|
+
5. Be responsive to feedback and reviews
|
|
323
|
+
|
|
324
|
+
## 📜 License
|
|
325
|
+
|
|
326
|
+
This project is licensed under the Apache License. See the LICENSE file for details.
|