Metadata-Version: 2.4
Name: keble-data-infra-contract
Version: 0.3.0
Summary: Framework-free raw commerce contracts shared by Keble data providers and the raw API.
Author-email: zhenhao-ma <bob0103779@gmail.com>
Requires-Python: <3.14,>=3.13
Requires-Dist: keble-helpers<2,>=1.51.0
Requires-Dist: pydantic<3,>=2.10
Description-Content-Type: text/markdown

# keble-data-infra-contract

Install the provider-neutral public contract with
`pip install "keble-data-infra-contract>=0.3.0,<1"`.

Framework-free, provider-neutral raw-commerce contracts. This distribution owns
validated request/response models, provider protocols, operation keys, manifests,
and typed domain errors. It intentionally has no FastAPI, database, HTTP client,
provider, platform, or idea dependency.

The distribution declares only registry-resolvable runtime dependencies. Do not
add workspace-relative `tool.uv.sources` here: downstream Git/subdirectory installs
must build this contract without inheriting paths outside the repository checkout.

Provider packages own implementations and native DTOs. The raw API consumes
provider manifests and constructs HTTP paths from their typed operation keys.

`Page[T]` and `RankingSnapshot[T]` carry a provider-neutral `usage` list of
`keble-helpers.UsageAccountingEvent`. Providers measure physical tokens,
requests, items, media, or bytes; this contract only transports those facts.
It must never contain prices, currency conversion, allocation policy, or
deployment secrets. Cache hits return an empty list so old upstream spend is
not replayed to consumers.

Version `0.2.0` is the exact-usage release. It requires
`keble-helpers>=1.51.0` and preserves media/storage/compute quantities plus
fully failed video-operation attempts without reconstructing prices. The
distribution has no Git or workspace source override, so consumers resolve the
same public contract in clean build and runtime environments.

Version `0.3.0` adds first-class evidence-bearing `TRENDING` operations without
aliasing search or rank. Products, creators, sellers, and videos have distinct
typed query contracts; every result carries stable provider identity, optional
product-family identity, structured standout evidence, source exhaustion, and
shrink diagnostics. Providers report raw source truth and never apply cross-page
dedupe. The central raw API alone applies the request's `none`, `entity`, or
`product_family` policy through an opaque continuation session.

```python
request = ProductTrendingQuery(
    query="red clothing",
    market="US",
    dedupe_mode=TrendDedupeMode.PRODUCT_FAMILY,
)
```

Blank product intent is valid category browsing. A filtered/dedupe-empty page
may remain continuable; only definitive upstream evidence can set
`TrendExhaustion.EXHAUSTED`. `TrendEvidence.summary` is display-ready but must
also carry an auditable metric, event time, or provider-board position.

Side effects if changes:

- provider packages and the raw API serialize these exact camel-case events;
- the Ideas platform deduplicates producer attempt keys and prices quantities
  with its own immutable profile effective at the event time.

```bash
uv run --package keble-data-infra-contract pytest -q keble-data-infra-contract/tests
uv run --package keble-data-infra-contract npx --yes pyright keble-data-infra-contract
uv build --package keble-data-infra-contract
```

Contract values inherit `ContractModel`, which accepts snake-case Python names
and camel-case wire aliases, rejects undeclared fields, and is frozen. Persisted
Mongo shapes do not belong here; provider/API packages own `SchemaBase` /
`MongoObjectBase` aggregates when durability is required.
`ContractModel` and the deliberately producer-tolerant Job/Result projection
both configure Pydantic through `keble-helpers.PydanticModelConfig`; a local
`ConfigDict` convention would split alias and validation ownership again.

`Money`, `Currency`, and `AmazonMarketplace` are imported from
`keble-helpers`. Provider-native response details remain inside the provider
package instead of crossing this boundary through an untyped extension bag.

Video enrichment uses the same framework-free boundary: immutable asset,
submission, job, completion-event, result, and normalized-projection models plus
one `VideoEnrichmentGateway` Protocol. HTTP submission and Mongo correlation
remain implementations owned by `keble-data-infra-api`.

Each video operation outcome carries canonical `UsageAccountingEvent` rows and
an opaque producer price-profile identity. The normalized projection preserves
both the per-operation status (including partial failure) and a flattened usage
view. It deliberately omits producer estimates and monetary values: ASR/OCR
route policy stays in Video Enrichment, while the Ideas platform resolves its
own immutable rates.

The job read also retains `analysisOperationAttempts` for every whole-workflow
retry. This is the accounting path for fully failed jobs and for failed provider
calls that precede a later successful result. Consumers must deduplicate by the
producer attempt key carried by each usage event; they must not infer zero cost
from the absence of a result.

Authorized provider transcripts use one canonical `VideoTranscript`/
`VideoTranscriptSegment` shape across submission, authoritative result reads, and
the local projection. Reuse evidence binds the normalized transcript checksum to
the data-infra source reference and media SHA-256; a title/description such as
`ShortVideo.caption` is not a spoken transcript and cannot bypass ASR.
