Skip to content

Rebuild the CLI on the Places API (0.4.0) - #10

Merged
moranlemusj merged 6 commits into
mainfrom
places-api-rebuild
Oct 21, 2026
Merged

moranlemusj merged 6 commits into
mainfrom
places-api-rebuild

Conversation

@yamarkov

Copy link
Copy Markdown
Contributor

What changed

The CLI was built on /v1/business-status, which is no longer part of the published API. This rebuilds voygr and its Python client on the endpoints described at https://api.voygr.tech/docs/.

  • voygr validate checks whether a place exists and is open. 1 credit.
  • voygr enrich returns phone, website, opening hours, social profiles and email for 1 credit per place. Research fields cost 1 credit per place per field. --estimate prices a request without running it.
  • --file places.csv on either command submits a bulk job of up to 10,000 rows, waits, and prints one JSON line per row. voygr jobs status, results and cancel pick a job up later.
  • voygr usage and voygr pricing are new. Pricing needs no key.
  • The default base URL is now https://api.voygr.tech.
  • voygr check is gone. That breaks existing scripts, so the version goes to 0.4.0.

Charges

  • The CLI never retries a single validate or enrich call after a server error, a timeout or a dropped connection, because the API may already have charged for it. It retries those calls on 429 only.
  • A job submit sends one Idempotency-Key and reuses it on every retry, so a retry replays the same job.
  • The CLI checks a CSV locally first. A bad row stops the command with its line number before anything reaches the API.
  • The client downloads result files without the API key and checks each one against its sha256.

Release

.github/workflows/release.yml publishes to PyPI when a v* tag is pushed. It uses trusted publishing, so the repo holds no PyPI token. The voygr project on PyPI needs a trusted publisher for this workflow before the first tag.

Tests

  • 481 unit and integration tests pass locally, with 99% line coverage.
  • actionlint passes on both workflows.
  • python -m build produces voygr-0.4.0.tar.gz and voygr-0.4.0-py3-none-any.whl.
  • Every README output that calls the API comes from a live run on 21 October 2026, which used 20 credits on a free key.

The release workflow hasn't run yet. The first tag will be its first run.

🤖 Generated with Claude Code

yamarkov and others added 5 commits October 21, 2026 05:18
…-call retries

Replace the retired /v1/business-status call with validate() and enrich(),
add pricing(), and let signup() tag its source. The default base URL is now
https://api.voygr.tech.

Each call picks its own retry set: validate, enrich, signup and recover retry
on 429 only, reads retry on 429 and transient 5xx. A numeric Retry-After is
honoured up to 60 s, otherwise backoff is exponential with jitter. Timeouts
and connection errors are never retried. Enrich waits up to 3,700 s when any
attribute is a research field, 90 s otherwise. Error bodies map error_code,
validation detail lists and plain detail strings to APIError.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
…ult download

Submit, poll, cancel and download bulk jobs. Submits carry one Idempotency-Key
across retries; result files are fetched without the API key, checked against
their sha256 and decoded from gzipped JSON Lines. An expired presigned link
triggers one status refresh per file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
Add `validate` and `enrich` for one place, `pricing` (no key needed), and
human output for every command in a new `voygr.human` module. `signup`
sends `src: voygr-cli` and its human output points to `voygr recover`.
The default base URL is now https://api.voygr.tech, and JSON output keeps
non-ASCII text. `check` and its CSV batch mode are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
validate and enrich take --file PATH (instead of NAME) and --no-wait. The CSV
is checked row by row before anything is sent; the job is submitted, polled
and its rows printed as JSON Lines. Ctrl-C stops waiting and leaves the job
running. A failed or cancelled job prints its rows, then exits 1.

voygr jobs status, results and cancel work on a batch ID. The integration
tests now run the CLI and the real client over a fake transport.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
…n README

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
@greptile-apps

greptile-apps Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[High impact] The follow-up appears safe to merge, with no new blocking findings.

Summary

Rebuilds the CLI and Python client around the Places API, with bulk jobs and a PyPI release workflow.

  • The CLI checks places and looks up details through the Places API.
  • CSV files run as bulk jobs that people can revisit later.
  • People can check credit use and see what requests cost.
  • A version tag builds and publishes the CLI package to PyPI.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Read CSV] --> B[Check rows and headers]
  B --> C[Choose idempotency key]
  C --> D[Submit job]
  D --> E{Submit outcome}
  E -->|Unclear failure| F[Print key for replay]
  E -->|Job returned| G[Poll job]
  G --> H[Download and check result files]
  H --> I[Print JSON Lines]
Loading

Reviews (2) · Last reviewed commit: "fix: keep the submit key after an unclea..." · Reviewed by Greptile

Comment thread src/voygr/cli.py Outdated
Comment thread src/voygr/client.py Outdated
Comment thread src/voygr/csv_input.py
…ts, refuse repeated CSV columns

A bulk submit that fails without a clear answer (timeout, dropped connection
or 5xx) now prints the Idempotency-Key it used. --idempotency-key KEY replays
that job instead of creating a second paid one.

wait_for_job cuts its sleeps and poll requests to the time left and never
starts a poll after the deadline.

A CSV whose header repeats a supported column after case and space folding
(address, Address) stops with a line 1 error instead of silently keeping one.

The README now says --max-credits applies to each place, and to each row with
--file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: multica-agent <github@multica.ai>
@yamarkov

Copy link
Copy Markdown
Contributor Author

@greptileai please re-review. ad2856a fixes the three findings from the first review: the submit key after an unclear failure, wait_for_job timeouts, and repeated CSV columns. This is a public repository, so please keep comments to the code in this PR.

@moranlemusj
moranlemusj self-requested a review October 21, 2026 16:06
@moranlemusj
moranlemusj merged commit f5c0322 into main Oct 21, 2026
5 checks passed
@moranlemusj
moranlemusj deleted the places-api-rebuild branch October 21, 2026 16:06
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.

2 participants