Skip to main content

WonderSearch for Python

Upload files and retrieve relevant passages with matching synchronous and asynchronous clients. Install the SDK from PyPI with pip install wondersearch.

pip install wondersearch

Configure POLYGRES_API_KEY with a workspace API key from Console and POLYGRES_BASE_URL with your API origin. The SDK has no implicit staging or production destination. A read_write key can upload and change the workspace default; a search key retains its existing read/search permissions.

from wondersearch import WonderSearch

with WonderSearch() as client:
    batch = client.upload("handbook.pdf")
    results = client.ask("What is our refund policy?")
    for passage in results.results:
        print(passage.text, passage.document_id, passage.document_revision)
from wondersearch import AsyncWonderSearch


async def search_handbook():
    async with AsyncWonderSearch() as client:
        await client.upload(["handbook.pdf", "policies.docx"])
        return await client.ask("What is our refund policy?")

ask() returns ranked passages and citations, not a generated answer. Empty results is a successful search. It defaults to the small effort and ten results. Advanced options include effort, limit, folder_id, group_by_document, timeout_ms (server search budget), and timeout (whole SDK operation budget). The server enforces query length, quotas and enabled efforts.

Drives

New workspaces have a selected Default drive. Change it on the Storage page or through the SDK:

client.drives.list()
client.drives.get_default()
client.drives.set_default("DRIVE_UUID")
client.upload("handbook.pdf", drive_id="DRIVE_UUID")
client.ask("Refund policy?", drive_id="DRIVE_UUID")

Create a drive with either client:

drive = client.drives.create("Knowledge Base")
print(drive.id, drive.status)
# Async: drive = await client.drives.create("Knowledge Base")

create(name, *, timeout=30, idempotency_key=None) returns a typed Drive. Names are trimmed and must contain 1-120 characters. Creation requires content write permission. The index may still be provisioning when this call returns; creation does not change the shared default. Use drives.set_default(drive.id) to select it explicitly. Reuse an idempotency_key and the same name to retry a creation whose response was lost.

Selection order is the method's drive_id, the client's drive_id, then the shared workspace default. The default is resolved once per operation and remains pinned through retries and polling. Explicit invalid drives never fall back. Changing the shared default affects subsequent calls by all workspace users. You must choose another default before deleting the selected default drive.

Uploads and recovery

upload() accepts a path or a list of paths for PDF, DOCX, TXT and Markdown, each from 1 through 25,000,000 bytes. It hashes and streams original bytes, follows proxy or direct transfer instructions, then waits for indexing. At most three files run concurrently. Directories are not traversed. wait=False returns after queuing processing; the default overall deadline is 600 seconds.

Uploads return an UploadBatch, including for one file. Each receipt includes upload, drive and workspace IDs. Searchable receipts also contain document, operation and snapshot IDs. A fresh document identity is generated by default. Use a stable external_id on single-file uploads to deliberately replace that document with a server-assigned revision.

from wondersearch import UploadBatchError

try:
    batch = client.upload("handbook.pdf", idempotency_key="handbook-update-42")
except UploadBatchError as exc:
    print(exc.batch.files)  # Successful files are preserved.
    print(exc.idempotency_key, exc.drive_id)  # Reuse these for a retry.
    for filename, failure in exc.failures.items():
        print(filename, failure)

Reuse the same paths in the same order, content, metadata, drive and idempotency_key to retry an interrupted upload. Do not change the workspace default between those retries without passing the original explicit drive. Retries are bounded by the server's 24-hour upload session/idempotency lifetime. SDK recovery is not a persistent upload queue.

For an upload already queued for extraction/indexing:

receipt = client.uploads.resume("UPLOAD_UUID", drive_id="DRIVE_UUID")

If bytes have not been sealed, resume() raises upload_transfer_incomplete and instructs you to repeat upload() with the original operation key. It does not pretend that polling can finish transferring bytes. Cancellation stops local waiting; already accepted server work may continue. A synchronous network request already in flight may finish cleanup after its caller's deadline; outstanding transport work is bounded.

Errors and citations

All API errors derive from PolygresError and expose status, code, request_id, details and retry_after. Unknown server codes remain inspectable. Upload failures retain receipts when a session exists. UploadBatchError retains successes and per-file errors.

Search and mutation retries use the same payload and idempotency key, with at most two retries and bounded backoff. A search whose replay has expired is never silently re-executed. Supplying your own idempotency_key lets you identify a logical search across invocations.

Search results include passage text and citation identifiers directly. Search responses omit model details, snapshot IDs, cache counts and timings. passages.get() requires a separately known snapshot ID, such as one retained from an upload receipt. A current drive snapshot may differ from the snapshot used by a concurrent search, so it is not a substitute for that exact snapshot.

An expired snapshot raises the server error instead of returning newer content. SearchResponse.raw preserves additive response fields, and usage amounts retain the server's exact decimal representation.

Versions

Package versions use semantic versioning and PEP 440 release candidates. 0.1.1 targets API /v1. During the 0.x series, minor releases may introduce breaking changes; patch releases contain compatible fixes. From stable v1 onward, removals receive at least 90 days' notice and a migration guide.

Earlier 1.0.0rc* versions were TestPyPI previews. Version 0.1.0 begins the production release series and sorts below those previews. When migrating, explicitly install wondersearch==0.1.1 from PyPI and change imports from polygres_search to wondersearch. Version 0.1.1 corrects the client names to WonderSearch and AsyncWonderSearch. Update imports and constructors from PolygresSearch and AsyncPolygresSearch; the old names are not exported. This initial branding correction is an exception to the patch compatibility policy.

The SDK sends its version on API requests and processes compatibility metadata from the API. Unsupported API majors or explicitly unsupported SDK versions raise SDKCompatibilityError. Supported older versions receive SDKUpgradeWarning; deprecations use SDKDeprecationWarning. Warnings occur at most once per notice per process and can be controlled with Python warning filters or version_warnings=False. Structured notices remain available at client.notices. There is no automatic upgrade or import-time PyPI request.

Development and release

Use a project virtual environment. Run pytest, ruff check, and mypy src, then python -m build --no-isolation. Build tooling includes Hatchling, build, pytest, Ruff and mypy. The wheel needs only HTTPX and packaging plus their transitive dependencies.

Do not publish until package ownership, public metadata and package contents are approved. The release manifest must leave latest_stable_sdk_version null until a corresponding stable release actually exists. Deployment and package publication are separate actions. Python 3.10+ is the target; report the actual tested platforms and interpreter versions for each release.

The supplied tox.ini exercises installed wheels on Python 3.10 through 3.14. Run this matrix on Linux, macOS and Windows before stable publication; missing interpreters are failures rather than silently skipped. Tox is optional release tooling.

License

Licensed under Apache-2.0, matching the Polygres CLI and SDK.

Metadata

Release files for wondersearch 0.1.1

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

Source distribution (sdist)

Source distribution for wondersearch 0.1.1
File Size Uploaded Provenance Actions
wondersearch-0.1.1.tar.gz 23.0 kB With provenance Details for wondersearch-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for wondersearch 0.1.1
File Interpreter ABI Platform Actions
wondersearch-0.1.1-py3-none-any.whl Python 3 none any Details for wondersearch-0.1.1-py3-none-any.whl

Total release size: 47.1 kB

Release files / wondersearch-0.1.1.tar.gz

Download URL wondersearch-0.1.1.tar.gz
Size 23.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a4b9e126ddf9b6d2490dcda8c5ea7a13b81b46220b96bda1c702973df4d5a992
BLAKE2b-256 checksum
How to use checksums
300fbf89d6ef05a07ac0d67005d7d3af6957dd6ffceffa9504202cea661cc03e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release files / wondersearch-0.1.1-py3-none-any.whl

Download URL wondersearch-0.1.1-py3-none-any.whl
Size 24.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd2a7622c1c7ee45541c2ccc4ccd3db9e93475d55bd16bd5ed8dead84005df11
BLAKE2b-256 checksum
How to use checksums
5a09874130b2f21589ca26986287737aaf1bea45640f1f8308e49af0adb0d5f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Security for wondersearch 0.1.1

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for wondersearch-0.1.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

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