Skip to content

PIGS-1096 - Add Optimize API benchmark sample - #14

Merged
brianom merged 4 commits into
mainfrom
pigs-1096-optimize-benchmark
Sep 10, 2026
Merged

brianom merged 4 commits into
mainfrom
pigs-1096-optimize-benchmark

Conversation

@SudNitro23

Copy link
Copy Markdown
Contributor

What

A new sample, optimize_benchmark.py, for prospects and customers evaluating the Optimize API on their own documents. It runs a folder of PDFs through one or more optimization profiles and reports per-file size reduction as CSVs plus a self-contained HTML report (headline numbers, size-reduction distribution chart, filterable per-file table) that opens in the browser when the run finishes.

uv run python optimize_benchmark.py ./pdfs ./output              # default: minimal-file-size
uv run python optimize_benchmark.py ./pdfs ./output -p minimal-file-size -p web
task optimize-benchmark INPUT_DIR=./pdfs OUTPUT_DIR=./output

Changes

  • api/platform_api.py — async job support: submit with Prefer: respond-async, follow the SSE status stream, download the result (Accept: application/octet-stream). Adds optimize() and JobFailedError. Large documents no longer time out on the synchronous request window.
  • benchmark/ — the operation runner (a result is only "success" when a valid PDF came back) and the report builder; the report's CSS/JS live as assets and are inlined at build time so the output stays one shareable file.
  • optimize_benchmark.py — typer CLI; auth/transport errors are recorded as failures instead of crashing, and a 401 from the token endpoint stops the run early with a hint.
  • test_files/optimize-benchmark/ — three sample PDFs (text-heavy, mixed, image-heavy) to try it on.
  • Taskfile task and README entries.

Verification

  • ruff check, ruff format and pyright (strict) all clean on the new/changed files
  • Tested against the live API: 3/3 sample PDFs optimized with minimal-file-size — 41.8% / 43.0% / 89.5% smaller, 56.5% overall (4.07 MB → 1.77 MB)

🤖 Generated with Claude Code

SudNitro23 and others added 4 commits September 7, 2026 17:25
Adds optimize_benchmark.py: runs a folder of PDFs through the Optimize
API and reports per-file size reduction as CSVs plus a self-contained
HTML report (headline numbers, distribution chart, filterable table).

- api/platform_api.py: async job support (Prefer: respond-async ->
  SSE status stream -> result download) and an optimize() method, so
  large documents no longer time out on the synchronous request window
- benchmark/: operation runner and report builder, with the report's
  CSS/JS kept as assets and inlined at build time
- test_files/optimize-benchmark/: three sample PDFs to try it on
- Taskfile task (optimize-benchmark) and README entries

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
An auth or transport error (e.g. a 401 from the token endpoint) is now
recorded as a per-file failure instead of crashing with a traceback,
which rich's locals rendering would have used to print the client
secret on screen. A 401 from /oauth/token also stops the run early
with a hint to check the .env credentials.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…load

The job result endpoint returns the job's JSON representation unless the
request asks for the file with Accept: application/octet-stream. Verified
against the live API: 3/3 sample PDFs optimized (56.5% overall reduction).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ars (#15)

## Summary
- Switched file uploads to the platform's presigned-URL flow (mint a
fresh pair, stream the file to it, submit an
`application/vnd.gonitro.url+json` file reference) instead of inlining
raw bytes into the multipart request
- Stream both the upload and the async job's result download in chunks
with a live `rich` progress bar, instead of buffering whole files in
memory
- `BaseOAuthClient.build()` is now a context-managed factory backed by
two `httpx2` clients — one authenticated against the platform, one plain
for presigned/arbitrary URLs, so the platform bearer token never leaks
onto them
- Rewrote the SSE job-status handling on `httpx2`'s native SSE support
with a discriminated pydantic union
(`ProgressUpdate`/`StatusUpdate`/`Redirect`), replacing the hand-rolled
line parser
- Fixed `_request_async_bytes` fetching the job's JSON representation
instead of the actual result file (it relied on an `Accept` header the
API doesn't honor)
- Split `benchmark.OperationResult` into
`OperationSuccess`/`OperationFailure` so a run's fields are only ever
the ones that outcome can actually produce
- Added `FatalError` (a `SystemExit` subclass) for clean, traceback-free
CLI errors on user-facing validation failures
- Added `services.OptimizerService` as a small facade over
`PlatformAPIClient` for the optimize workflow, and wired
`optimize_benchmark.py` through it
- Assorted cleanup: MIME type lookup by extension instead of the stdlib
`mimetypes` module, `httpx2` status codes instead of hardcoded ints, and
other small consistency fixes across the API clients

## Test plan
- [x] `ruff check .` and `pyright` clean across the whole
`samples/python` project
- [x] End-to-end tests against local fake servers for: single-file
operations (convert/redact/etc.), `merge` (multi-file), the full async
optimize job flow (submit → SSE progress → result download), and the
streaming upload/download progress bars (verified byte-for-byte content
integrity via SHA-256 on a multi-MB file)
- [x] Verified terminal output rendering with `pyte` (real terminal
emulation) to confirm the progress bars don't corrupt surrounding CLI
output
- [ ] Manual run against the real API (`task optimize-benchmark
INPUT_DIR=... OUTPUT_DIR=...`)

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
@brianom
brianom merged commit 4ac538d into main Sep 10, 2026
2 checks passed
@brianom
brianom deleted the pigs-1096-optimize-benchmark branch September 10, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants