Skip to content

Migrate indexer + web off raw httpx and onto the hevlayer Python SDK #8

Description

@hev

Motivation

hev-shop is the demo for "hevlayer coordinates ingest → embed → review search →
tag rollups." Today both the indexer and the web pod talk to layer-gateway via
hand-rolled HTTP:

  • indexer/app/layer_client.py — 551-line httpx wrapper, ~30 methods
  • web/lib/layer.ts — one POST to /v2/namespaces/{ns}/warm

That's the wrong story for a flagship demo. A customer adopting hevlayer would
reach for a published SDK, not reverse-engineer the gateway's REST shape. We
should use the official hevlayer Python client so the storefront is an
honest example of what integration actually looks like.

This issue tracks hev-shop adoption. The SDK itself lives in
hev/layer — see the companion issue there for
SDK design (codegen vs hand-written) and packaging.

Current surface to cover

The SDK needs to support everything LayerClient does today. Grouped by area:

Pipelines

  • create_pipeline(id, target_namespace, distance_metric)POST /v2/pipelines, 409-safe
  • pipeline_status(id)GET /v2/pipelines/{id}/status
  • claim_pipeline_documents(...) with document_id_prefix, lease, worker_id
  • heartbeat_pipeline_documents(...)
  • set_pipeline_documents_stage(...) with from_stage, create_missing
  • release / fail / complete convenience wrappers
  • stage_pipeline_document(...)PUT .../documents/{id} with chunks
  • get_chunks(pipeline_id, document_id)
  • write_vector(...) — single-vector PUT

Namespaces — read

  • fetch_document(ns, id, include_attributes=) + _with_perf variant
  • fetch_many_documents(ns, ids, include_attributes=)
  • query_namespace(ns, vector, top_k, include_attributes=, filters=) + _with_perf
  • fetch_namespace_metadata(ns) + _with_perf

Namespaces — write

  • upsert_vectors(ns, vectors)
  • patch_attributes(ns, patches) — attribute-only PATCH (does not clobber vectors)

Scans

  • create_scan / get_scan / list_scans / get_scan_results
  • wait_for_scan(...) — exponential backoff polling
  • scan(...) — create + wait convenience
  • warm_namespace(ns) — POST /v2/namespaces/{ns}/warm

Observability

  • LayerPerf(latency_ms, cache_status) returned alongside reads — surfaces the
    x-layer-cache header verbatim (hit / miss / miss-on-error / None for
    query). Product detail and search endpoints expose this to the UI; the SDK
    needs an equivalent (per-call timing + cache header).

Auth

  • Bearer token via Authorization header. Defensively strips whitespace from
    the key (1Password / kubectl --from-literal / YAML block scalars sometimes
    add a trailing newline; httpx rejects header CR/LF with an error that
    embeds the key, which would leak it into /detail/ surfaces — see
    48a6c26).

Hev-shop migration plan

  1. Add hevlayer to indexer/requirements.txt; drop the direct httpx
    import for gateway calls (httpx stays for the OpenRouter classifier).
  2. Replace indexer/app/layer_client.py with a thin shim that re-exports
    the SDK client + LayerPerf type (or delete it and import directly from
    hevlayer at call sites in main.py, pipeline.py, extraction.py,
    worker.py).
  3. Update tests/_fakes.py:FakeLayerClient to satisfy the SDK's
    client Protocol / ABC (the SDK should expose one for stub-friendliness;
    if it doesn't, raise it in the upstream issue).
  4. Run python3 -m pytest tests/ --tb=short in indexer/ — the pipeline
    driver, per-stage processors, and HTTP handlers should all pass against
    the new fake.
  5. Web side: replace the single fetch in web/lib/layer.ts:warmOne with
    the SDK's TS client if/when one ships. Until then, leave as-is — it's 30
    lines and isolated. (Out of scope for this issue if no TS SDK lands.)
  6. Smoke check against prod:
    curl -s https://api.hev-shop.com/healthz
    curl -s https://api.hev-shop.com/meta | jq .
    curl -s -X POST -H 'content-type: application/json' \
      -d '{"query":"wireless headphones","top_k":3}' \
      https://api.hev-shop.com/search | jq .
    

Out of scope

  • Building the SDK itself — tracked in hev/layer#22.
  • Migrating the Go CLI off its hand-rolled clients (go run . status/health);
    separate decision since the Go ecosystem story is different.
  • Web TS client — depends on whether a TS SDK ships.

Acceptance

  • indexer/app/layer_client.py is deleted or reduced to a re-export shim.
  • indexer/requirements.txt lists hevlayer (or equivalent).
  • All existing tests pass; FakeLayerClient satisfies the SDK's stub contract.
  • /product/{asin}, /search, /search/reviews, /meta return the same
    shape as before (including layer_perf blocks).
  • Cache-hit signals on product pages still render with latency + cache_status.

Dependencies

  • hev/layer#22: define + ship hevlayer Python SDK (build approach TBD).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions