Skip to main content

AWB Extractor

Python SDK for extracting receiver, shipment, carrier, and e-commerce platform information from Vietnamese AWB/shipping label PDF files using Claude AI.

Features

  • Extract from PDF bytes, local PDF files, or PDF URLs
  • Batch extraction from multiple URLs
  • Optional PDF-to-JPEG optimization before sending to Claude
  • Cost estimation helper for PDF and optimized image modes
  • Optional default HTTP headers for protected AWB URLs
  • Typed AWBResult dataclass output
  • Custom exceptions for API key, PDF download, and JSON parsing failures

Requirements

  • Python 3.9+
  • Anthropic API key
  • pymupdf for optimized PDF-to-JPEG extraction

Installation

Install from PyPI:

pip install awb-extractor

For local development:

pip install -e ".[dev]"

Usage

from awb_extractor import AWBExtractor

extractor = AWBExtractor(api_key="sk-ant-...")
result = extractor.from_file("label.pdf")

print(result.recipient_name)
print(result.carrier)
print(result.platform)
print(result.to_dict())

Example result:

{
    "tracking_number": "NHSVC972103440",
    "recipient_name": "Nguyen Van A",
    "recipient_phone": "(+84)03******37",
    "recipient_address": "237 Nguyen Trai",
    "recipient_ward": "Phuong Ben Thanh",
    "recipient_district": "Quan 1",
    "recipient_province": "TP. Ho Chi Minh",
    "sender_name": "Onflow",
    "sender_address": "TP. Ho Chi Minh",
    "cod": "0",
    "weight": "0.700 KG",
    "order_id": "584425059595159079",
    "carrier": "GHN",
    "platform": "Shopee",
}

By default, AWBExtractor converts the first PDF page to JPEG before sending it to Claude:

extractor = AWBExtractor(
    api_key="sk-ant-...",
    optimize=True,
    dpi=200,
)

If you want to send the original PDF document directly, set optimize=False:

extractor = AWBExtractor(api_key="sk-ant-...", optimize=False)

Supported Inputs

PDF bytes

from awb_extractor import AWBExtractor

extractor = AWBExtractor(api_key="sk-ant-...")

with open("label.pdf", "rb") as file:
    result = extractor.from_bytes(file.read())

Local PDF file

from awb_extractor import AWBExtractor

extractor = AWBExtractor(api_key="sk-ant-...")
result = extractor.from_file("label.pdf")

PDF URL

from awb_extractor import AWBExtractor

extractor = AWBExtractor(
    api_key="sk-ant-...",
    http_headers={"Authorization": "Bearer token"},
)

result = extractor.from_url("https://example.com/awb.pdf")

You can pass request-specific headers with extra_headers:

result = extractor.from_url(
    "https://example.com/awb.pdf",
    extra_headers={"X-Request-ID": "request-123"},
)

Multiple URLs

from_urls() returns a list of dictionaries with url, data, and error. Failed URLs do not stop the whole batch.

from awb_extractor import AWBExtractor

extractor = AWBExtractor(api_key="sk-ant-...")
results = extractor.from_urls([
    "https://example.com/good.pdf",
    "https://example.com/bad.pdf",
])

Estimate Cost

estimate_cost() estimates token usage and cost before calling the API.

from pathlib import Path
from awb_extractor import estimate_cost

pdf_bytes = Path("label.pdf").read_bytes()
cost = estimate_cost(pdf_bytes, optimize=True, dpi=200)

print(cost)

Example output:

{
    "mode": "image/jpeg",
    "input_tokens": 800,
    "output_tokens": 150,
    "cost_usd": 0.00155,
    "awb_per_10_usd": 6451,
}

Result Fields

AWBResult includes:

  • tracking_number
  • recipient_name
  • recipient_phone
  • recipient_address
  • recipient_ward
  • recipient_district
  • recipient_province
  • sender_name
  • sender_address
  • cod
  • weight
  • order_id
  • carrier
  • platform

Use to_dict() or to_json() to serialize the result.

Empty strings returned by Claude are normalized to None.

Exceptions

  • APIKeyError: missing API key
  • PDFDownloadError: PDF URL download failed
  • ExtractionError: Claude response could not be parsed as JSON

Package Structure

  • awb_extractor/extractor.py: public AWBExtractor class
  • awb_extractor/models.py: AWBResult dataclass
  • awb_extractor/exceptions.py: package exceptions

Development

Install dependencies and run tests:

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest -q

Publishing

GitHub Actions builds and publishes the package to PyPI on every push to main.

The repository must define this GitHub secret:

PYPI_API_TOKEN

PyPI does not allow replacing an existing version. If a commit on main does not bump project.version in pyproject.toml, the publish step skips the existing distribution.

Metadata

Release files for awb-extractor 0.1.6

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for awb-extractor 0.1.6
File Size Uploaded Provenance Actions
awb_extractor-0.1.6.tar.gz 7.8 kB Without provenance Details for awb_extractor-0.1.6.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for awb-extractor 0.1.6
File Interpreter ABI Platform Actions
awb_extractor-0.1.6-py3-none-any.whl Python 3 none any Details for awb_extractor-0.1.6-py3-none-any.whl

Total release size: 15.0 kB

Release files / awb_extractor-0.1.6.tar.gz

Download URL awb_extractor-0.1.6.tar.gz
Size 7.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4b84c528aaa40d4257ad7132c8ebd2544fe933cac8ff2f534e7f204ef77b1bfd
BLAKE2b-256 checksum
How to use checksums
88cb8cd94f076af441e9591a7ee8085b98680129f418511904c9a4f291aa98bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Release files / awb_extractor-0.1.6-py3-none-any.whl

Download URL awb_extractor-0.1.6-py3-none-any.whl
Size 7.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
533776dfe7be0de18dc80ee916e899b55d2c4e7300e4c4cfd84ea39446b7dae3
BLAKE2b-256 checksum
How to use checksums
a067e26d3e12dca778d59fd2150653a47a2591ef5f04c1e1d85d049b21454346
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.13

Security for awb-extractor 0.1.6

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page