Skip to main content

Dataset utilities for AgriStress-500 — HuggingFace download, metadata lookup, and retrieval payload assembly for the PAI embedding evaluator.

Project description

Precision AI Logo

PAI AgriStress Utils

Dataset utilities for AgriStress-500 — download the dataset from HuggingFace, look up image and instance metadata, and assemble ready-to-POST payloads for the agrieval embedding evaluator.

PyPI Python License


Installation

python -m venv .venv && source .venv/bin/activate  # Windows: .venv\Scripts\activate

pip install precisionai-agristress-utils

# Full development (tests, pre-commit, type checking)
pip install -e ".[dev]"

Quick start

from precisionai.agristress.utils import AgriStressDataset, download_dataset

download_dataset("/path/to/agristress", repo_id="precisionaiinc/AgriStress-500")
ds = AgriStressDataset("/path/to/agristress")

See examples/ for complete walkthroughs of all three evaluator routes and dataset validation.


Downloading the dataset

from precisionai.agristress.utils import download_dataset

download_dataset("/path/to/agristress", repo_id="precisionaiinc/AgriStress-500")

Single-shot only — partial downloads are not supported. The internal/ directory is always excluded. Returns the resolved local Path.

After downloading, the directory layout is:

/path/to/agristress/
  images/          # source images, one subdirectory per L2 cluster
  instances/       # instance crops, one subdirectory per annotated cluster
  image2image.json
  plant2image.json
  plant2plant.json
  README.md

Pass that directory directly to AgriStressDataset:

ds = AgriStressDataset("/path/to/agristress")

Enumeration and filtering

Before embedding images you need to know what IDs exist. All IDs are relative paths that match the dataset layout exactly (e.g. "images/A1/pai-FvearqMK.png").

# All clusters, images, and instances
clusters      = ds.list_clusters()                        # sorted list of L2 cluster names
all_images    = ds.list_image_ids()                       # all image paths
all_instances = ds.list_instance_ids()                    # all instance paths

# Narrow by cluster or label
a1_images     = ds.list_image_ids(cluster="A1")
soy_instances = ds.list_instance_ids(label="Crop | Soybean")

# Filter by cluster attributes — scalar or list values
drone_images  = ds.filter_images_by_attribute(camera_source="drone")
noon_drone    = ds.filter_images_by_attribute(camera_source="drone", time_period="noon")
soy_clusters  = ds.filter_images_by_attribute(plants="Crop | Soybean")

Path resolution

Map relative IDs to absolute file paths so you can open them with your image loader:

paths = ds.resolve_paths(ds.list_image_ids(cluster="A1"))
# {"images/A1/pai-FvearqMK.png": Path("/path/to/agristress/images/A1/pai-FvearqMK.png"), ...}

from PIL import Image
for abs_path in paths.values():
    img = Image.open(abs_path)
    # … run embedding model

Both image and instance IDs are accepted. The returned paths are resolved but not checked for existence.


Embedding utilities

The agrieval evaluator requires every vector to be L2-normalized (‖v‖₂ = 1.0 ± 1e-3). Use these utilities to normalize and validate before building payloads:

from precisionai.agristress.utils import normalize_embeddings, validate_embeddings

# Normalize raw model output
raw = {"images/A1/pai-FvearqMK.png": model.encode(...)}  # unnormalized
normed = normalize_embeddings(raw)                        # returns new dict, does not mutate

# Validate before posting (raises ValueError if any vector deviates)
validate_embeddings(normed)

normalize_embeddings raises ValueError for zero vectors. validate_embeddings raises ValueError with the offending path and its actual norm if any vector fails the check.


Metadata lookups

IDs are relative paths matching the dataset layout (e.g. "images/A1/pai-FvearqMK.png").

Image metadata

records = ds.image_metadata([
    "images/A1/pai-FvearqMK.png",
    "images/A1/pai-XYZ123.png",
])
for r in records:
    print(r.image_id, r.cluster, r.attributes.plants, r.instances)

Optionally attach embeddings. Embeddings are all-or-nothing — every requested ID must have an entry in the dict, or ValueError is raised:

embeddings = {
    "images/A1/pai-FvearqMK.png": [...],
    "images/A1/pai-XYZ123.png":   [...],
}
records = ds.image_metadata(list(embeddings), embeddings=embeddings)
print(records[0].embedding)   # [...] populated

Instance metadata

records = ds.instance_metadata([
    "instances/A1/pai-FvearqMK-1.png",
])
for r in records:
    print(r.instance_id, r.label, r.parent_image)

Retrieval payload builders

Assemble the exact request body expected by agrieval. All embedding vectors must be L2-normalized flat list[float].

Method Evaluator endpoint
build_i2i_payload(embeddings) POST /v1/embeddings/evaluate/image2image
build_p2i_payload(embeddings) POST /v1/embeddings/evaluate/plant2image
build_p2p_payload(embeddings) POST /v1/embeddings/evaluate/plant2plant
# Image → Image
i2i = ds.build_i2i_payload(image_embeddings, k_values=[5, 10, 20])

# Plant → Image  (embeddings must include BOTH image and instance paths)
p2i = ds.build_p2i_payload(combined_embeddings)

# Plant → Plant  (instance paths only)
p2p = ds.build_p2p_payload(instance_embeddings, sample_pairs=None)

Embedding keys not present in the dataset manifests are ignored. Clusters or instance groups with no matching embedding are dropped from the payload automatically.


Project layout

precisionai/agristress/utils/
  dataset/
    download.py      # HuggingFace single-shot download
    loader.py        # AgriStressDataset — metadata lookups + payload builders
  schemas/
    dataset.py       # ImageRecord, InstanceRecord, ImageAttributes  (Pydantic)
    retrieval.py     # I2IPayload, P2IPayload, P2PPayload  (TypedDicts)
docs/                # Sphinx (HTML + LaTeX/PDF)
tests/               # Mirrors package structure
examples/            # Standalone runnable scripts

Development

See CONTRIBUTING.md for setup, branching, and PR guidelines, and CODE_OF_CONDUCT.md for community expectations. CLAUDE.md documents the code style and conventions enforced in this repo.

# Run all tests with coverage report
python -m pytest

# Run a specific file
pytest tests/test_loader.py

# Run pre-commit hooks manually
pre-commit run --all-files

License

Licensed under the Apache License, Version 2.0. See LICENSE.md.

See CHANGELOG.md for release history.

Project details


Download files

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

Source Distribution

precisionai_agristress_utils-1.0.1.tar.gz (73.2 kB view details)

Uploaded Source

Built Distribution

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

precisionai_agristress_utils-1.0.1-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

Details for the file precisionai_agristress_utils-1.0.1.tar.gz.

File metadata

File hashes

Hashes for precisionai_agristress_utils-1.0.1.tar.gz
Algorithm Hash digest
SHA256 24fcac817a1c9c6b345ea8bbf8ed00e6837a9dd08e582bfcee48b03e5514b59c
MD5 272ba4a0a9db82a2f091830c74caf5c7
BLAKE2b-256 e8821a8bad59601ee98803899017b98cd79408e479bf28ae4aa934d7a99e852b

See more details on using hashes here.

Provenance

The following attestation bundles were made for precisionai_agristress_utils-1.0.1.tar.gz:

Publisher: release.yml on Precision-AI-Inc/agristress-utils

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

File details

Details for the file precisionai_agristress_utils-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for precisionai_agristress_utils-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3ab7552eca07141833879b64ce814610ccb0869e7ba5aa8da45b60593dbfa0ce
MD5 8ef86ef24e3806623e9e39a25f79803e
BLAKE2b-256 26606f765a72c2426bc0ea9ec60ffe08c64f3c22d1d13b1c9187873b0c201c51

See more details on using hashes here.

Provenance

The following attestation bundles were made for precisionai_agristress_utils-1.0.1-py3-none-any.whl:

Publisher: release.yml on Precision-AI-Inc/agristress-utils

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

Supported by

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