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.
- cartapy-0.1.0/.github/copilot-instructions.md +35 -0
- cartapy-0.1.0/.github/workflows/publish.yaml +274 -0
- cartapy-0.1.0/.gitignore +72 -0
- cartapy-0.1.0/Cargo.lock +975 -0
- cartapy-0.1.0/Cargo.toml +16 -0
- cartapy-0.1.0/PKG-INFO +29 -0
- cartapy-0.1.0/README.md +16 -0
- cartapy-0.1.0/carta/__init__.py +299 -0
- cartapy-0.1.0/carta/_rust_wrapper.py +31 -0
- cartapy-0.1.0/carta/_rust_wrapper.pyi +22 -0
- cartapy-0.1.0/pyproject.toml +55 -0
- cartapy-0.1.0/src/lib.rs +52 -0
- cartapy-0.1.0/tests/test_conversion.py +47 -0
- cartapy-0.1.0/utils/generate_init.py +138 -0
- cartapy-0.1.0/uv.lock +459 -0
|
@@ -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 }}
|
cartapy-0.1.0/.gitignore
ADDED
|
@@ -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
|