Skip to main content

3tears-search

Provider-agnostic web and media search for the 3tears family.

The authority for everything in this package is docs/search-spec.md (decisions D1-D28), with requirement IDs (SR-*, G*, P*) defined in docs/search-requirements.md.

Layout

threetears/search/
  contracts/        # the leaf within the leaf -- types, protocols, errors, keys
  adapters/
    searxng.py      # one provider's API, over the injected transport
  call.py           # a query → one candidate set, bounded and negotiated
  bind.py           # prose for a model + the metadata projection
  standalone.py     # bare-httpx transport   [standalone] -- the sanctioned path (D19)
  testing/          # the shared provider-conformance suite + declared doubles

Layer names (Adapter, Call, Bind, …) are module vocabulary and never type names, so a later re-cut of the layers stays cheap.

contracts/ is the lingua franca every layer and every consumer speaks:

  • SearchRequest and the open criteria vocabulary (typed constructors for well-known criteria, namespaced keys for everything else), with per-criterion dispositions (pushdown | local | unsatisfied | ignored-unknown).
  • Candidate -- the carrier-neutral result core: identity, locators, provenance, named provenanced scores (never a single score field, D1), fidelity available/achieved, an optional content slot, and additive facets keyed by the media-contracts vocabulary.
  • Spend -- every resource a call consumed: money (Decimal), wall-clock, call count, weighted provider units, bytes.
  • The typed error taxonomy (SR-J1), every error carrying Spend (SR-E3). Zero results is a success value, not an error (SR-J2).
  • SearchTransport -- the injected transport seam (SR-N1, P9). A thin host-side adapter over threetears.core.http_client.TracedHttpClient satisfies it structurally; this package never imports core.
  • SEARCH_RESULTS_METADATA_KEY and the versioned metadata projection (D13, D22).
  • ProviderCapabilities -- what a provider can express, declared and queryable so a consumer branches before sending rather than after failing (SR-B4), following the 3tears-models capability-metadata pattern.
  • SearchProvider -- the provider seam Call depends on and the conformance suite parametrizes over.
  • Canonical serialization of request/parameter types -- one canonical form consumed by both the D26 replay key and eval run identity (SR-F1).

Using it

import asyncio

from threetears.search.adapters.searxng import SearxngAdapter
from threetears.search.bind import bind_search
from threetears.search.contracts import Criterion, SearchRequest
from threetears.search.standalone import StandaloneTransport   # or your own


async def main() -> None:
    adapter = SearxngAdapter(
        base_url="https://searx.internal.example",   # deployment config, never env
        transport=StandaloneTransport(allow_private_addresses=True),
        provider_instance="searxng-main",
    )
    rendered = await bind_search(
        SearchRequest(query="capybara habitat range", criteria=(Criterion.max_results(5),)),
        provider=adapter,
    )
    print(rendered.content)                                  # prose for a model
    print(rendered.metadata["search_results"]["candidates"])  # structure for a program


asyncio.run(main())

bind_search never raises: a typed failure arrives as a failed RenderedSearch carrying its spend under the same metadata key (D10). Callers that want the exception go through threetears.search.call.search instead.

Budgets and pacing pass through the same entry point: hand bind_search (or search) a budget= implementing BudgetPort, a limiter= such as threetears.search.limiter.InProcessRateLimiter -- construct one per process and share it, or pacing paces nothing -- and the egress= name your transport actually exits by (D8, D20). A budget refusal or pacing denial renders as a failed result like any other typed failure; omitting the ports means no budget is consulted and no pacing applies.

Hosts that already have threetears.core should inject a thin adapter over TracedHttpClient rather than take the [standalone] extra -- it brings timeouts, retry, circuit-breaking and spans for free.

Provider conformance

threetears.search.testing ships the suite every adapter passes -- contract shape, spend on failure, error taxonomy, disposition honesty, zero-results-is-success (SR-O5). It imports no test framework, so a consumer can run it against its own wiring:

from threetears.search.testing import ProviderConformanceCase, ProviderConformanceSuite


class TestMyProviderConformance(ProviderConformanceSuite):
    case = ProviderConformanceCase(...)

Not here yet

aggregate.py, extract.py, select.py, limiter.py and replay.py are later phases of docs/search-spec.md §7. Budget-port consultation and pacing are marked seams inside call.py: the port types are Phase 1 PR 2, and a placeholder protocol would only be a second vocabulary to migrate off.

Import-cleanliness

Importing threetears.search.contracts pulls nothing beyond stdlib, pydantic, and 3tears-media-contracts. Nothing in this package imports threetears.core, threetears.agent.*, langchain, or NATS. Nothing reads environment variables -- the host passes base URLs, secret references, and transport (SR-K1).

standalone.py is the only module that imports httpx, and nothing in the package imports standalone at module level: the extra stays opt-in, and a host that injects its own transport never installs it. Both facts are pinned by tests/test_package_boundaries.py, and the module's path is the D19 widening of the no-bespoke-client norm in tests/enforcement/test_no_bespoke_reuse.py -- a sanctioned transport, with no exemption filed.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

3tears_search-0.26.1.tar.gz (223.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

3tears_search-0.26.1-py3-none-any.whl (159.8 kB view details)

Uploaded Python 3

File details

Details for the file 3tears_search-0.26.1.tar.gz.

File metadata

  • Download URL: 3tears_search-0.26.1.tar.gz
  • Upload date:
  • Size: 223.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for 3tears_search-0.26.1.tar.gz
Algorithm Hash digest
SHA256 add28563e2bb4c97933986bce953c2ac894dbeace70c7fde31d001ffaf2411b3
MD5 fe1ebc99bc896b61b6c1a90c40be4f43
BLAKE2b-256 a7c84e0cd8e1c9db73836a2b67b493b381e7d7e0d1428a9e19e39b43f4514830

See more details on using hashes here.

Provenance

The following attestation bundles were made for 3tears_search-0.26.1.tar.gz:

Publisher: release.yml on pacepace/3tears

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file 3tears_search-0.26.1-py3-none-any.whl.

File metadata

  • Download URL: 3tears_search-0.26.1-py3-none-any.whl
  • Upload date:
  • Size: 159.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for 3tears_search-0.26.1-py3-none-any.whl
Algorithm Hash digest
SHA256 30354783cfcf487daf9bbc087f2ef2b7929a22b150aad73d45390a124df09fdf
MD5 0ab04bead526c8a638caef5bfc763ec4
BLAKE2b-256 80521547c506980619de586663ab883764500eaa8c7c3ff952994c14106dfeda

See more details on using hashes here.

Provenance

The following attestation bundles were made for 3tears_search-0.26.1-py3-none-any.whl:

Publisher: release.yml on pacepace/3tears

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.27.0

2 files

This release

0.26.1 This release

2 files

0.26.0

2 files

0.25.0

2 files

0.24.7

2 files

0.24.6

2 files

0.24.5

2 files

0.24.4

2 files

0.24.3

2 files

0.24.2

2 files

0.24.1

2 files

0.24.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page