Skip to content

Make acquire a reusable library: caller User-Agent, geometry, post-walk checks #64

Description

@ChelseaKR

What

perimeter.acquire is consumed by wildfire-service-territory-overlap, which pins a commit and on 2026-09-05 audited the seam, recording four gaps in its docs/UPSTREAM.md: the walk sends only perimeter's User-Agent, so CAL FIRE's logs cannot see who is calling; the paged walk cannot return geometry, so the consumer copied the offset loop; completeness is one record count read once before the walk, so the consumer added a post-walk recount and identifier ordering and uniqueness checks; and the package ships no py.typed, so a strict consumer carries two mypy overrides. This closes all four here so the consumer's compensations can be deleted: user_agent on layer_record_count and fetch_layer; geometry, format and spatial-reference arguments (or an exposed page iterator); a second count after the walk with strictly increasing unique identifiers as an acquisition guard; and src/perimeter/py.typed.

Why it matters

The relationship is "consume, do not re-implement", and every gap left open is a copied loop that will drift. Each change strengthens perimeter's own guarantee that a short download is not an acquisition (the post-walk count catches a truncated walk the pre-walk count cannot), and none touches the measurement or the pages. The network path stays hand-run and out of CI; tests substitute the socket as they do today.

Scope

  • acquire.py: user_agent: str = USER_AGENT threaded through _get; fetch_layer(..., return_geometry=False, out_fields=..., out_sr=...) or iter_pages(...); post-walk recount and identifier checks that refuse to write on failure, recorded in acquisition.json.
  • py.typed; pyproject.toml package data.
  • A CHANGELOG entry naming the consumer's audit, so its docs/UPSTREAM.md rows become closable at the next pin.

Out of scope

  • Changing what perimeter itself acquires by default.
  • Publishing to PyPI under a new name (a separate decision; perimeter is taken).

Done when

  • A test asserts the User-Agent a caller supplies is what _get sends, and the default still names this project.
  • A simulated walk returning fewer records than the post-walk count refuses to write and names both counts; a walk with a repeated identifier refuses.
  • mypy --strict over a minimal consumer importing perimeter.acquire passes with no overrides.
  • Geometry requested through the library round-trips a fixture feature's coordinates unchanged.

Pointers

Proposed with AI assistance.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfeatureMajor new capability proposal

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions