receitapdf 0.1.1__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 (59) hide show
  1. receitapdf-0.1.1/.github/workflows/ci.yml +47 -0
  2. receitapdf-0.1.1/.github/workflows/publish-pypi.yml +85 -0
  3. receitapdf-0.1.1/.gitignore +5 -0
  4. receitapdf-0.1.1/AGENTS.md +34 -0
  5. receitapdf-0.1.1/CLAUDE.md +1 -0
  6. receitapdf-0.1.1/Cargo.lock +987 -0
  7. receitapdf-0.1.1/Cargo.toml +29 -0
  8. receitapdf-0.1.1/LICENSE +21 -0
  9. receitapdf-0.1.1/LICENSE-DejaVu.txt +4 -0
  10. receitapdf-0.1.1/PKG-INFO +127 -0
  11. receitapdf-0.1.1/README.md +110 -0
  12. receitapdf-0.1.1/assets/anvisa-v2/notificacao-a-veterinaria.pdf +0 -0
  13. receitapdf-0.1.1/assets/anvisa-v2/notificacao-a.pdf +0 -0
  14. receitapdf-0.1.1/assets/anvisa-v2/notificacao-b-veterinaria.pdf +0 -0
  15. receitapdf-0.1.1/assets/anvisa-v2/notificacao-b.pdf +0 -0
  16. receitapdf-0.1.1/assets/anvisa-v2/notificacao-b2.pdf +0 -0
  17. receitapdf-0.1.1/assets/anvisa-v2/receita-controle-especial.pdf +0 -0
  18. receitapdf-0.1.1/assets/anvisa-v2/retinoides.pdf +0 -0
  19. receitapdf-0.1.1/assets/anvisa-v2/talidomida.pdf +0 -0
  20. receitapdf-0.1.1/assets/fonts/DejaVuSans.ttf +0 -0
  21. receitapdf-0.1.1/examples/notificacao-a.json +28 -0
  22. receitapdf-0.1.1/examples/visual-review/contato.png +0 -0
  23. receitapdf-0.1.1/examples/visual-review/notificacao_a.json +28 -0
  24. receitapdf-0.1.1/examples/visual-review/notificacao_a_veterinaria.json +31 -0
  25. receitapdf-0.1.1/examples/visual-review/notificacao_b.json +28 -0
  26. receitapdf-0.1.1/examples/visual-review/notificacao_b2.json +28 -0
  27. receitapdf-0.1.1/examples/visual-review/notificacao_b_veterinaria.json +31 -0
  28. receitapdf-0.1.1/examples/visual-review/png/notificacao_a.png +0 -0
  29. receitapdf-0.1.1/examples/visual-review/png/notificacao_a_veterinaria.png +0 -0
  30. receitapdf-0.1.1/examples/visual-review/png/notificacao_b.png +0 -0
  31. receitapdf-0.1.1/examples/visual-review/png/notificacao_b2.png +0 -0
  32. receitapdf-0.1.1/examples/visual-review/png/notificacao_b_veterinaria.png +0 -0
  33. receitapdf-0.1.1/examples/visual-review/png/receita_controle_especial.png +0 -0
  34. receitapdf-0.1.1/examples/visual-review/png/retinoides.png +0 -0
  35. receitapdf-0.1.1/examples/visual-review/png/talidomida.png +0 -0
  36. receitapdf-0.1.1/examples/visual-review/receita_controle_especial.json +28 -0
  37. receitapdf-0.1.1/examples/visual-review/retinoides.json +30 -0
  38. receitapdf-0.1.1/examples/visual-review/talidomida.json +44 -0
  39. receitapdf-0.1.1/mise.toml +2 -0
  40. receitapdf-0.1.1/pyproject.toml +24 -0
  41. receitapdf-0.1.1/python/receitapdf/__init__.py +57 -0
  42. receitapdf-0.1.1/python/receitapdf/__init__.pyi +17 -0
  43. receitapdf-0.1.1/python/receitapdf/_types.py +72 -0
  44. receitapdf-0.1.1/python/receitapdf/py.typed +1 -0
  45. receitapdf-0.1.1/src/error.rs +23 -0
  46. receitapdf-0.1.1/src/layout/common.rs +452 -0
  47. receitapdf-0.1.1/src/layout/mod.rs +50 -0
  48. receitapdf-0.1.1/src/layout/rce.rs +10 -0
  49. receitapdf-0.1.1/src/layout/retinoides.rs +52 -0
  50. receitapdf-0.1.1/src/layout/talidomida.rs +188 -0
  51. receitapdf-0.1.1/src/layout/veterinaria.rs +16 -0
  52. receitapdf-0.1.1/src/lib.rs +153 -0
  53. receitapdf-0.1.1/src/main.rs +33 -0
  54. receitapdf-0.1.1/src/model.rs +135 -0
  55. receitapdf-0.1.1/src/python.rs +42 -0
  56. receitapdf-0.1.1/src/qr.rs +86 -0
  57. receitapdf-0.1.1/src/render.rs +156 -0
  58. receitapdf-0.1.1/src/validate.rs +140 -0
  59. receitapdf-0.1.1/tests/python/test_receitapdf.py +53 -0
@@ -0,0 +1,47 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build-and-test:
13
+ runs-on: ubuntu-24.04
14
+ steps:
15
+ - uses: actions/checkout@v6
16
+
17
+ - uses: actions-rust-lang/setup-rust-toolchain@v1
18
+ with:
19
+ toolchain: stable
20
+
21
+ - uses: actions/setup-python@v6
22
+ with:
23
+ python-version: "3.13"
24
+
25
+ - name: Check Rust formatting
26
+ run: cargo fmt --all -- --check
27
+
28
+ - name: Build Rust CLI and library
29
+ run: cargo build --release --locked
30
+
31
+ - name: Test Rust library
32
+ run: cargo test --locked
33
+
34
+ - name: Test Rust library with Python bindings enabled
35
+ run: cargo test --locked --features python
36
+
37
+ - uses: PyO3/maturin-action@v1
38
+ with:
39
+ command: build
40
+ maturin-version: v1.15.0
41
+ manylinux: 2_28
42
+ args: --release --locked --compatibility pypi --interpreter python3.13 --out dist
43
+
44
+ - name: Test built Python wheel
45
+ run: |
46
+ python -m pip install --no-deps --force-reinstall dist/*.whl
47
+ python -m unittest discover -s tests/python -v
@@ -0,0 +1,85 @@
1
+ name: Publish Python package
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ build:
13
+ if: github.event_name == 'release' || github.ref == 'refs/heads/master'
14
+ runs-on: ubuntu-24.04
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+ with:
18
+ ref: ${{ github.event.release.tag_name || github.sha }}
19
+
20
+ - uses: actions-rust-lang/setup-rust-toolchain@v1
21
+ with:
22
+ toolchain: stable
23
+
24
+ - uses: actions/setup-python@v6
25
+ with:
26
+ python-version: "3.13"
27
+
28
+ - name: Check release tag matches package version
29
+ if: github.event_name == 'release'
30
+ env:
31
+ RELEASE_TAG: ${{ github.event.release.tag_name }}
32
+ run: |
33
+ python - <<'PY'
34
+ import os
35
+ import pathlib
36
+ import tomllib
37
+
38
+ version = tomllib.loads(pathlib.Path("pyproject.toml").read_text())["project"]["version"]
39
+ expected = f"v{version}"
40
+ actual = os.environ["RELEASE_TAG"]
41
+ if actual != expected:
42
+ raise SystemExit(f"release tag {actual!r} must match package version tag {expected!r}")
43
+ PY
44
+
45
+ - name: Test Rust library and Python feature
46
+ run: |
47
+ cargo test --locked
48
+ cargo test --locked --features python
49
+
50
+ - uses: PyO3/maturin-action@v1
51
+ with:
52
+ command: build
53
+ maturin-version: v1.15.0
54
+ manylinux: 2_28
55
+ args: --release --locked --compatibility pypi --interpreter python3.13 --sdist --out dist
56
+
57
+ - name: Test built wheel
58
+ run: |
59
+ python -m pip install --no-deps --force-reinstall dist/*.whl
60
+ python -m unittest discover -s tests/python -v
61
+
62
+ - uses: actions/upload-artifact@v6
63
+ with:
64
+ name: pypi-distributions
65
+ path: dist/*
66
+ if-no-files-found: error
67
+ retention-days: 7
68
+
69
+ publish:
70
+ if: github.event_name == 'release' || github.ref == 'refs/heads/master'
71
+ needs: build
72
+ runs-on: ubuntu-24.04
73
+ environment:
74
+ name: pypi
75
+ url: https://pypi.org/p/receitapdf
76
+ permissions:
77
+ id-token: write
78
+ steps:
79
+ - uses: actions/download-artifact@v6
80
+ with:
81
+ name: pypi-distributions
82
+ path: dist
83
+
84
+ - name: Publish distributions to PyPI
85
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,5 @@
1
+ /target
2
+ /out
3
+ *.pdf
4
+ !examples/*.pdf
5
+ !assets/anvisa-v2/*.pdf
@@ -0,0 +1,34 @@
1
+ # receitapdf
2
+
3
+ Biblioteca Rust + CLI + extensão Python (PyO3/maturin) que recebe uma prescrição já estruturada e devolve os bytes do PDF de um dos oito modelos **eletrônicos** de receituário da Anvisa. Visão geral e uso: [README.md](README.md).
4
+
5
+ ## Escopo
6
+
7
+ O componente valida, gera o QR e renderiza. Número SNCR, decisão clínica e assinatura eletrônica chegam prontos ou ficam com a integração chamadora; mantenha-os fora deste crate.
8
+
9
+ ## Decisões de layout
10
+
11
+ - Os PDFs oficiais em `assets/anvisa-v2/` não têm AcroForm. A renderização usa cada um como fundo vetorial: `printpdf` cria a camada de texto/QR e `lopdf` a incorpora ao modelo. `printpdf` não edita PDF existente.
12
+ - Fonte da verdade do layout: os PDFs de `assets/anvisa-v2/` (modelos eletrônicos, não os físicos). Coordenadas por modelo ficam em `src/layout/`.
13
+ - QR só nas Notificações: `https://sncr.anvisa.gov.br/receita/consultar?numero={numero}`, número no formato `0000.0-00.0000000`. A RCE fica sem QR porque a Anvisa não publica conteúdo para ela; conteúdo de QR para outros documentos exige fonte oficial.
14
+ - Texto que não cabe no campo gera `Erro`, nunca truncamento ou sobreposição.
15
+ - `printpdf`, `lopdf` e `pyo3` estão fixados com `=` no `Cargo.toml`: a composição depende dessas APIs exatas. Atualize-os só junto com a renderização e os testes.
16
+
17
+ ## Convenções
18
+
19
+ - Domínio, API pública, mensagens de erro e docs em português (`Receita`, `gerar_pdf`, `Erro`).
20
+ - A API Python espelha a Rust. Ao alterar `Receita` ou a API pública, atualize juntos `src/python.rs`, `python/receitapdf/__init__.pyi`, `python/receitapdf/_types.py` e o README.
21
+ - Dados de exemplo em `examples/` são totalmente fictícios. Ao adicionar um campo, atualize os JSONs de `examples/visual-review/`, que também alimentam os testes Python.
22
+
23
+ ## Verificação
24
+
25
+ Rust via `mise` (`mise exec rust -- <cmd>`). Uma mudança está pronta quando passa o mesmo que `.github/workflows/ci.yml`:
26
+
27
+ ```sh
28
+ cargo fmt --all -- --check
29
+ cargo test --locked
30
+ cargo test --locked --features python
31
+ maturin build --release && pip install --force-reinstall target/wheels/*.whl && python -m unittest discover -s tests/python
32
+ ```
33
+
34
+ Mudanças visuais: gere os PDFs de `examples/visual-review/`, compare com o original em `assets/anvisa-v2/` e regenere os PNGs em `examples/visual-review/png/` (144 dpi) e `contato.png`.
@@ -0,0 +1 @@
1
+ @AGENTS.md