Skip to content

Provider adapter system

Provider-specific behavior implements one interface outside route handlers:

class ProviderAdapter(ABC):
    async def fetch_location(self, query: LocationQuery) -> ProviderPayload: ...
    def normalize_location(self, query, payload) -> LocationResponse: ...
    def raw_location(self, query, payload) -> RawProviderResponse: ...

An adapter owns provider input validation, request construction, timeout/retry behavior, raw parsing, canonical mapping, citations, warnings, licensing fields, and operational behavior.

USDA SDA implementation

The first adapter resolves a WGS84 point through an official SDA spatial table function, joins to map unit, legend, major component, and overlapping horizon tables, and selects only allowlisted columns. It limits provider rows to 500 and rejects unsupported properties before the request.

Routine tests use httpx.MockTransport; they do not call USDA. An integration test is skipped unless OPENSOIL_RUN_LIVE_TESTS=1.

Adapter safety rules

  • Never expose arbitrary SQL, URLs, table names, or provider credentials.
  • Bound result size and accepted spatial extent.
  • Use explicit timeouts and only limited retries for transient failures.
  • Preserve the original response when terms allow.
  • Never relabel modeled or mapped data as observed.
  • Record transformations; reject unknown conversions.
  • Treat a null provider field as unknown, not zero.
  • Keep provider failures structured and free of stack traces.
  • Add fixtures for success, empty data, malformed data, timeout, and failure.