cartapy 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.
@@ -0,0 +1,35 @@
1
+ # cartaPy - Developer & AI Agent Guide
2
+
3
+ ## Overview
4
+ `cartaPy` is a Python extension package that wraps the Rust [`carta`](https://crates.io/crates/carta) document conversion crate via PyO3.
5
+
6
+ ## Essential Commands
7
+
8
+ - **Run tests:** `uv run pytest`
9
+ - **Run linter:** `uv run ruff check .`
10
+ - **Regenerate Python API:** `uv run python utils/generate_init.py`
11
+ - **Build Rust extension locally:** `uv run maturin develop` or `cargo build`
12
+
13
+ ## Architecture & Code Generation
14
+
15
+ 1. **Rust Extension (`src/lib.rs`):**
16
+ - Implements PyO3 functions `convert_text(from_fmt, to_fmt, input_text)` and `convert(from_fmt, to_fmt, input_text)`.
17
+ - `convert_text` returns `str`; `convert` handles both `str` and `bytes` outputs (returns `PyBytes` for binary output formats).
18
+ - Compiled module name must be `_rust_wrapper` (configured in `Cargo.toml`).
19
+
20
+ 2. **Code Generator (`utils/generate_init.py`):**
21
+ - **Do NOT edit `carta/__init__.py` directly.** It is programmatically generated by `generate_init.py`.
22
+ - `generate_init.py` defines format sets (`input_formats`, `output_formats`, `binary_output_formats`, `format_mapping_extras`).
23
+ - Run `uv run python utils/generate_init.py` whenever format sets or mapping logic are modified.
24
+
25
+ 3. **Runtime Proxy (`carta/_rust_wrapper.py` & `.pyi`):**
26
+ - `carta/_rust_wrapper.py` dynamically loads the compiled `_rust_wrapper` extension module.
27
+ - `carta/_rust_wrapper.pyi` provides type stubs for `convert_text` and `convert`.
28
+
29
+ 4. **Rust Feature Gates (`Cargo.toml`):**
30
+ - Formats supported by `carta` must have their respective features enabled in `Cargo.toml` (e.g. `read-csv`, `write-csv`).
31
+
32
+ ## Development Conventions & Pitfalls
33
+
34
+ - **Format Synchronization:** If new formats or aliases are added or updated in the `carta` Rust crate, update `utils/generate_init.py` and run `uv run python utils/generate_init.py` followed by `uv run pytest`.
35
+ - **Text vs Bytes:** Ensure output formats that produce binary files (`docx`, `epub`, `epub2`, `epub3`, `odt`) are listed in `binary_output_formats` so they call `_convert_bytes()` / `_rust_wrapper.convert()`. All text-producing formats should use `_convert_text()` / `_rust_wrapper.convert_text()`.
@@ -0,0 +1,274 @@
1
+ name: publish
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v[0-9]+.[0-9]+.[0-9]+'
7
+ branches:
8
+ - dev
9
+ - develop
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ test:
16
+ name: Test
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v6
20
+ - uses: actions/setup-python@v6
21
+ with:
22
+ python-version: '3.11'
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v7
25
+ - name: Run tests
26
+ run: uv run python -m pytest tests/
27
+
28
+ linux:
29
+ runs-on: ${{ matrix.platform.runner }}
30
+ needs: test
31
+ strategy:
32
+ matrix:
33
+ platform:
34
+ - runner: ubuntu-22.04
35
+ target: x86_64
36
+ - runner: ubuntu-22.04
37
+ target: x86
38
+ - runner: ubuntu-22.04
39
+ target: aarch64
40
+ - runner: ubuntu-22.04
41
+ target: armv7
42
+ # - runner: ubuntu-22.04
43
+ # target: s390x
44
+ # - runner: ubuntu-22.04
45
+ # target: ppc64le
46
+ steps:
47
+ - uses: actions/checkout@v6
48
+ - uses: actions/setup-python@v6
49
+ with:
50
+ python-version: 3.x
51
+ - name: Build wheels
52
+ uses: PyO3/maturin-action@v1
53
+ env:
54
+ CFLAGS_aarch64-unknown-linux-gnu: "-march=armv8-a -D__ARM_ARCH=8"
55
+ CFLAGS_aarch64_unknown_linux_gnu: "-march=armv8-a -D__ARM_ARCH=8"
56
+ CFLAGS_aarch64-unknown-linux-musl: "-march=armv8-a -D__ARM_ARCH=8"
57
+ CFLAGS_aarch64_unknown_linux_musl: "-march=armv8-a -D__ARM_ARCH=8"
58
+ with:
59
+ target: ${{ matrix.platform.target }}
60
+ args: --release --out dist --find-interpreter
61
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
62
+ manylinux: auto
63
+ - name: Upload wheels
64
+ uses: actions/upload-artifact@v5
65
+ with:
66
+ name: wheels-linux-${{ matrix.platform.target }}
67
+ path: dist
68
+
69
+ test_install:
70
+ name: Test Install
71
+ runs-on: ubuntu-latest
72
+ needs: linux
73
+ steps:
74
+ - uses: actions/setup-python@v6
75
+ with:
76
+ python-version: '3.11'
77
+
78
+ - name: Download wheel
79
+ uses: actions/download-artifact@v4
80
+ with:
81
+ pattern: wheels-linux-*
82
+ path: dist/
83
+ merge-multiple: true
84
+
85
+ - name: Install local wheel
86
+ run: pip install --no-index --find-links=dist/ cartapy
87
+
88
+ - name: Import and smoke test
89
+ run: |
90
+ python -c '
91
+ from carta import convert
92
+
93
+ html = "<p><em>Hello</em> world!</p>"
94
+ markdown = "*Hello* world!"
95
+
96
+ expected_md = convert(html).from_html.to_markdown
97
+ expected_html = convert(markdown).from_markdown.to_html
98
+
99
+ assert expected_md == markdown, f"Expected: {markdown}, but got: {expected_md}"
100
+ assert expected_html == html, f"Expected: {html}, but got: {expected_html}"
101
+ '
102
+
103
+ musllinux:
104
+ runs-on: ${{ matrix.platform.runner }}
105
+ needs: test_install
106
+ strategy:
107
+ matrix:
108
+ platform:
109
+ - runner: ubuntu-22.04
110
+ target: x86_64
111
+ - runner: ubuntu-22.04
112
+ target: x86
113
+ - runner: ubuntu-22.04
114
+ target: aarch64
115
+ - runner: ubuntu-22.04
116
+ target: armv7
117
+ steps:
118
+ - uses: actions/checkout@v6
119
+ - uses: actions/setup-python@v6
120
+ with:
121
+ python-version: 3.x
122
+ - name: Build wheels
123
+ uses: PyO3/maturin-action@v1
124
+ env:
125
+ CFLAGS_aarch64-unknown-linux-gnu: "-march=armv8-a -D__ARM_ARCH=8"
126
+ CFLAGS_aarch64_unknown_linux_gnu: "-march=armv8-a -D__ARM_ARCH=8"
127
+ CFLAGS_aarch64-unknown-linux-musl: "-march=armv8-a -D__ARM_ARCH=8"
128
+ CFLAGS_aarch64_unknown_linux_musl: "-march=armv8-a -D__ARM_ARCH=8"
129
+ with:
130
+ target: ${{ matrix.platform.target }}
131
+ args: --release --out dist --find-interpreter
132
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
133
+ manylinux: musllinux_1_2
134
+ - name: Upload wheels
135
+ uses: actions/upload-artifact@v5
136
+ with:
137
+ name: wheels-musllinux-${{ matrix.platform.target }}
138
+ path: dist
139
+
140
+ windows:
141
+ runs-on: ${{ matrix.platform.runner }}
142
+ needs: test_install
143
+ strategy:
144
+ matrix:
145
+ platform:
146
+ - runner: windows-latest
147
+ target: x64
148
+ python_arch: x64
149
+ - runner: windows-latest
150
+ target: x86
151
+ python_arch: x86
152
+ - runner: windows-11-arm
153
+ target: aarch64
154
+ python_arch: arm64
155
+ steps:
156
+ - uses: actions/checkout@v6
157
+ - uses: actions/setup-python@v6
158
+ with:
159
+ python-version: '3.13'
160
+ architecture: ${{ matrix.platform.python_arch }}
161
+ - name: Build wheels
162
+ uses: PyO3/maturin-action@v1
163
+ with:
164
+ target: ${{ matrix.platform.target }}
165
+ args: --release --out dist --find-interpreter
166
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
167
+ - name: Upload wheels
168
+ uses: actions/upload-artifact@v5
169
+ with:
170
+ name: wheels-windows-${{ matrix.platform.target }}
171
+ path: dist
172
+
173
+ macos:
174
+ runs-on: ${{ matrix.platform.runner }}
175
+ needs: test_install
176
+ strategy:
177
+ matrix:
178
+ platform:
179
+ - runner: macos-15-intel
180
+ target: x86_64
181
+ - runner: macos-latest
182
+ target: aarch64
183
+ steps:
184
+ - uses: actions/checkout@v6
185
+ - uses: actions/setup-python@v6
186
+ with:
187
+ python-version: 3.x
188
+ - name: Build wheels
189
+ uses: PyO3/maturin-action@v1
190
+ with:
191
+ target: ${{ matrix.platform.target }}
192
+ args: --release --out dist --find-interpreter
193
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
194
+ - name: Upload wheels
195
+ uses: actions/upload-artifact@v5
196
+ with:
197
+ name: wheels-macos-${{ matrix.platform.target }}
198
+ path: dist
199
+
200
+ android:
201
+ runs-on: ubuntu-latest
202
+ needs: test_install
203
+ strategy:
204
+ matrix:
205
+ platform:
206
+ - aarch64-linux-android
207
+ - x86_64-linux-android
208
+ # - armv7-linux-androideabi
209
+ steps:
210
+ - uses: actions/checkout@v6
211
+ - uses: actions/setup-python@v6
212
+ with:
213
+ python-version: 3.x
214
+ - name: Build wheels
215
+ uses: PyO3/maturin-action@v1
216
+ env:
217
+ CFLAGS_aarch64-linux-android: "-march=armv8-a -D__ARM_ARCH=8"
218
+ CFLAGS_aarch64_linux_android: "-march=armv8-a -D__ARM_ARCH=8"
219
+ with:
220
+ target: ${{ matrix.platform }}
221
+ args: --release --out dist -i python3.12
222
+ sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
223
+ - name: Upload wheels
224
+ uses: actions/upload-artifact@v5
225
+ with:
226
+ name: wheels-android-${{ matrix.platform }}
227
+ path: dist
228
+
229
+ sdist:
230
+ runs-on: ubuntu-latest
231
+ needs: test_install
232
+ steps:
233
+ - uses: actions/checkout@v6
234
+ - name: Build sdist
235
+ uses: PyO3/maturin-action@v1
236
+ with:
237
+ command: sdist
238
+ args: --out dist
239
+ - name: Upload sdist
240
+ uses: actions/upload-artifact@v5
241
+ with:
242
+ name: wheels-sdist
243
+ path: dist
244
+
245
+ release:
246
+ name: Release
247
+ runs-on: ubuntu-latest
248
+ needs: [linux, musllinux, windows, macos, android, sdist]
249
+ if: startsWith(github.ref, 'refs/tags/v')
250
+ permissions:
251
+ id-token: write
252
+ contents: write
253
+ attestations: write
254
+
255
+ steps:
256
+ - name: Download wheels
257
+ uses: actions/download-artifact@v5
258
+ with:
259
+ pattern: wheels-*
260
+ path: dist
261
+ merge-multiple: true
262
+
263
+ - name: Generate artifact attestation
264
+ uses: actions/attest-build-provenance@v3
265
+ with:
266
+ subject-path: 'dist/*'
267
+
268
+ - name: Install uv
269
+ uses: astral-sh/setup-uv@v7
270
+
271
+ - name: Publish to PyPI
272
+ run: uv publish dist/*
273
+ env:
274
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,72 @@
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