A small, typed Python library and command-line tool for parsing text-based Form 7 shipping PDFs and adding order labels to their pages.
Important
This is an unofficial project. It is not affiliated with, endorsed by, or supported by Russian Post. No official logos, forms, or production documents are included.
- Extracts recipient name, phone, address, and a 14-digit tracking number.
- Processes multi-page PDFs and returns stable JSON.
- Adds sanitized order labels without using private
pypdfAPIs. - Writes JSON and PDFs atomically with owner-only
0600permissions on POSIX and best-effort private permissions on Windows. - Applies default limits of 100 MiB and 500 pages.
- Keeps full page text out of results unless explicitly requested.
- Performs no network requests, analytics, or telemetry.
- Only PDFs with an extractable text layer are supported.
- Scanned documents require OCR before they can be parsed; OCR is not included.
- Parsing is heuristic because PDF text layout can vary between generators.
- Only 14-digit tracking numbers are accepted.
- Rotated pages containing interactive annotations must be flattened before adding labels.
Download the wheel from the latest release, then install it:
python -m pip install ./form7_pdf_parser-*.whlFor development:
gh repo clone alyldas/form7-pdf-parser
cd form7-pdf-parser
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"Parse a PDF into JSON:
form7-pdf parse --input form7.pdf --output result.jsonFull extracted page text is omitted by default because it can contain personal data. Opt in only when the output is stored securely:
form7-pdf parse \
--input form7.pdf \
--output result.json \
--include-raw-textAdd labels using an overlay file:
{
"overlays": [
{ "page_number": 1, "order_label": "Order #6904" }
]
}form7-pdf annotate \
--input form7.pdf \
--overlay overlays.json \
--output annotated.pdfLabels retain ASCII letters, digits, spaces, #, -, _, and /. Other characters are
removed, empty normalized labels are ignored, and normalized labels longer than 64 characters
are rejected. Labels shrink down to 8 pt when needed to fit the visible page area; labels that
still do not fit are rejected instead of being clipped.
Successful commands return 0, processing failures return 1, and invalid command-line
arguments return 2. Errors are written to standard error.
Both commands accept --max-pages and --max-file-size-mib to override their defensive
limits. Run form7-pdf --version for the installed version and form7-pdf COMMAND --help for
the complete command-specific options.
from form7_pdf_parser import Overlay, annotate_pdf, parse_pdf
result = parse_pdf("form7.pdf")
for page in result.pages:
print(page.page_number, page.tracking_number, page.is_valid)
if not page.is_valid:
print([issue.value for issue in page.validation_issues])
annotate_pdf(
"form7.pdf",
"annotated.pdf",
[Overlay(page_number=1, order_label="Order #6904")],
)Invalid Python results expose typed validation_issues values such as
missing_tracking_number and missing_recipient. They are intentionally omitted from the
stable JSON contract below; JSON consumers can continue to rely on is_valid.
The JSON contract is intentionally small and stable:
{
"page_count": 1,
"pages": [
{
"page_number": 1,
"recipient_name": "...",
"recipient_phone": "...",
"recipient_address": "...",
"tracking_number": "...",
"raw_text": null,
"is_valid": true
}
]
}The package also exports the lower-level parse_page, parse_tracking_number, and
parse_recipient_name_address_phone helpers for advanced integrations. These functions are
best-effort text heuristics; prefer parse_pdf when processing complete documents.
Shipping documents can contain names, addresses, phone numbers, payment amounts, and active tracking numbers. Do not attach production PDFs or parser output to public issues. Use a minimal synthetic reproduction instead.
The library uses defensive defaults, but it is not a malware scanner or a hardened document sandbox. Process untrusted PDFs in an isolated worker with operating-system resource limits. See SECURITY.md for vulnerability reporting.
ruff format --check .
ruff check .
mypy
pytest
python -m build
twine check dist/*All committed PDF fixtures are generated from clearly fictional data. See tests/fixtures/README.md.
Contributions are welcome. Read CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SUPPORT.md before opening an issue or pull request.
Released under the MIT License.