Skip to content

Latest commit

 

History

History
259 lines (194 loc) · 9.12 KB

README.md

File metadata and controls

259 lines (194 loc) · 9.12 KB

Photon Commerce

Photon SDK for Python

The official Python SDK for Photon Commerce — extract structured data from invoices, receipts, and financial documents.

PyPI SOC 2 GDPR Accuracy Languages Python 3.10+

Website · API Docs · Pricing · Free Trial


Overview

Photon Commerce extracts standardized data from documents (PDFs, images, Word, HTML, and emails) with 99%+ accuracy, combining AI processing with human verification. Results come back as JSON with 100+ standardized fields across amounts, vendor, bill-to, metadata, line items, and payment details, in 25+ languages.

This SDK wraps that API in a fully typed Python client: extract a document in a single call, read the result as typed attributes, and correct it in place.

Installation

pip install photon-sdk

Quick Start

from photon import PhotonClient

client = PhotonClient(
    client_id="YOUR_CLIENT_ID",
    username="YOUR_USERNAME",
    api_key="YOUR_API_KEY",
    password="YOUR_PASSWORD",
    secret_key="YOUR_SECRET_KEY",
)

# Submit a document and wait for the extracted result
invoice = client.extract("invoice.pdf", doctype="invoice")

print(invoice["Vendor_Name"])  # Acme Supplies
print(invoice["Invoice_Number"])  # INV-2024-00842
print(invoice["Total"])  # 4750.00
print(invoice["Currency_Code"])  # USD

Get free sandbox credentials (20 complimentary extractions, no payment info required) at app.photoncommerce.com.

Extracted Fields

Category Fields
Amounts Balance due, total, subtotal, tax, discounts, currency
Vendor Name, address, phone, email, tax ID
Bill To Name, address, phone, email, tax ID
Metadata Invoice number, date, due date, PO number
Line Items Description, quantity, unit price, amount, SKU, GL code
Payment Payment terms, bank details, IBAN, routing number

Usage

Credentials

Pass the five credentials to PhotonClient, or set them as environment variables and use PhotonClient.from_env():

export PHOTON_CLIENT_ID=...
export PHOTON_USERNAME=...      # your account email
export PHOTON_API_KEY=...
export PHOTON_PASSWORD=...
export PHOTON_SECRET_KEY=...
export PHOTON_ENVIRONMENT=sandbox   # or "production"
from photon import PhotonClient

with PhotonClient.from_env() as client:
    ...

Extract a document

extract() uploads the document and polls until the result is ready:

invoice = client.extract("invoice.pdf", doctype="invoice", timeout=600)

invoice.vendor_name  # "Acme Supplies Ltd"
invoice.total  # Decimal("1397.50")
invoice.due_date  # datetime.date(2026, 11, 18)
for line in invoice.line_items:
    print(line.line, line.description, line.qty, line.amount)

invoice["Vendor_Name"]  # the API's own field names work too
invoice.raw  # the untouched payload
invoice.to_dict()  # typed fields as a dict; to_json() for JSON

A document can be a path, an open binary file, raw bytes, or a public URL (client.extract(url="https://...")).

Invoices and receipts (doctype="invoice" / "receipt-expense") return a typed InvoiceDocument: amounts are exact Decimals, ISO dates are datetime.date, and anything absent reads as None. Every other doctype (check, remittance, bol, statement, ...) returns a RawDocument, read by the API's field names: doc["payerName"].

Submit now, retrieve later

Processing can take from seconds (AI extraction) to hours (human verification), so you can also split the two steps:

submission = client.submit("invoice.pdf", doctype="invoice", webhook_url="https://example.com/hook")
# ... later, or once the webhook fires:
invoice = client.retrieve(submission.photon_key, doctype="invoice")

retrieve() raises NotReadyError while the document is still processing. extract(..., timeout=None) submits without waiting and returns the Submission.

Correct extracted data

Updates use the API's field names, exactly as the result spells them:

key = invoice.photon_key

client.update_fields(key, {"Vendor_Name": "Acme Supplies Ltd", "Total": "1397.50"})
client.update_line_item(key, 2, {"QTY": 3, "Amount": "225.00"})
client.add_line_item(key, {"Line": 3, "Description": "Shipping", "QTY": 1, "Amount": "25.00"})
client.delete_line_item(key, 3)

Errors

Every error raised by the SDK is a PhotonError carrying status_code, message and the response body:

Exception When
AuthenticationError Credentials rejected (401)
QuotaExceededError The account's allowance is used up
InvalidRequestError The request or file was rejected (bad file, unknown key, invalid line item, ...)
NotReadyError The document is still processing
ExtractionTimeoutError extract() gave up waiting; retrieve later by photon_key
PhotonConnectionError The API could not be reached
APIError Any other unsuccessful response
ConfigurationError Missing credentials or an unknown environment

Invalid arguments raise ValueError before anything is sent.

Retries

Server errors (5xx) and network failures are retried up to max_retries times (default 3) with exponential backoff. Requests that could take effect twice — submitting a document, adding or deleting a line item — are only retried when the connection itself failed. 4xx errors are never retried.

client = PhotonClient.from_env(max_retries=5, backoff_factor=1.0, timeout=60)

Retries are logged at DEBUG on the photon logger; credentials and document keys are never logged.

Processing Times

Account Type Turnaround
Trial Up to 24 hours (human verification included)
Production 5 minutes to 24 hours (human verification included)
AI Extraction Seconds (contact support@photoncommerce.com to activate)

Authentication

The SDK sends your credentials as four headers on every request. Free sandbox credentials are available at no cost.

CLIENT-ID:     your-client-id
AUTHORIZATION: apikey your-username:your-api-key
PASSWORD:      your-password
SECRET-KEY:    your-secret-key

Sample Response

{
  "data": {
    "Total": 22001.38,
    "Balance_Due": 22001.38,
    "Subtotal": 22001.38,
    "Tax": 0,
    "Currency_Code": "USD",
    "Document_Type": "Invoice",
    "Invoice_Number": "2/02/2021",
    "Date": "2021-02-03",
    "Due_Date": "2021-02-10",
    "Vendor_Name": "TUNEGO, INC.",
    "Vendor_Address": "32505 Anthem Village Drive, Suite E283, Henderson, NV 89052",
    "Bill_To_Name": "MOBILE REALITY sp. z o. o",
    "Bill_To_Address": "03-901 Warszawa, Poland",
    "Line_Items": [
      {
        "Line": 1,
        "Description": "React.JS frontend development",
        "QTY": 160,
        "Unit": "hrs",
        "Price": 42.5,
        "Amount": 6800
      }
    ],
    "Pages": 1,
    "photon_key": "data/johndoe@abc.com/2026-01-05/23-40-12_TuneGO.json"
  },
  "message": "success",
  "status": "success"
}

Development

git clone https://github.com/Photon-Commerce/photon-sdk-python.git
cd photon-sdk-python
pip install -e ".[dev]"

pytest --cov          # run tests with coverage
ruff check .          # lint
ruff format --check . # formatting
mypy                  # type-check

Releasing

Bump __version__ in src/photon/_version.py, add the version to CHANGELOG.md, merge to main, then push a matching tag:

git tag v0.1.0 && git push origin v0.1.0

The release workflow builds the package, installs it in a clean environment, publishes it to PyPI and creates the GitHub release.

Links

License

MIT