Spaces:
Build error
Build error
File size: 3,154 Bytes
583e46a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | """
Breed metadata loader and lookup utility.
Reads breed_metadata.csv and provides enriched breed info for inference.
"""
import csv
from pathlib import Path
from typing import Optional
PROJECT_ROOT = Path(__file__).resolve().parents[3]
DEFAULT_METADATA_PATH = PROJECT_ROOT / 'data' / 'breed_metadata.csv'
class BreedMetadataStore:
"""Loads and provides lookup for breed metadata."""
def __init__(self, csv_path: Optional[str | Path] = None):
self.csv_path = Path(csv_path) if csv_path else DEFAULT_METADATA_PATH
self._data: dict[str, dict] = {}
self._load()
def _load(self) -> None:
"""Load CSV into an in-memory dict keyed by breed_name."""
if not self.csv_path.exists():
raise FileNotFoundError(f"Breed metadata file not found: {self.csv_path}")
with open(self.csv_path, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
breed_name = row['breed_name'].strip()
self._data[breed_name] = {
'breed_id': int(row['breed_id']),
'breed_name': breed_name,
'animal_type': row['animal_type'].strip(),
'region': row['region'].strip(),
'avg_milk_liters_per_day': row['avg_milk_liters_per_day'].strip(),
'lifespan_years': row['lifespan_years'].strip(),
'primary_use': row['primary_use'].strip(),
'coat_color_notes': row['coat_color_notes'].strip(),
'horn_notes': row['horn_notes'].strip(),
'description': row['description'].strip(),
'source_reference': row['source_reference'].strip(),
}
def get(self, breed_name: str) -> Optional[dict]:
"""Look up breed info by exact name."""
return self._data.get(breed_name)
def search(self, query: str) -> list[dict]:
"""Case-insensitive partial match search."""
query_lower = query.lower()
return [
info for name, info in self._data.items()
if query_lower in name.lower()
]
def get_all(self) -> list[dict]:
"""Return all breed records."""
return list(self._data.values())
def get_breed_names(self) -> list[str]:
"""Return sorted list of breed names."""
return sorted(self._data.keys())
@property
def num_breeds(self) -> int:
return len(self._data)
def get_summary_for_prediction(self, breed_name: str) -> Optional[dict]:
"""
Return a condensed breed info dict suitable for API responses.
"""
info = self.get(breed_name)
if info is None:
return None
return {
'breed_name': info['breed_name'],
'animal_type': info['animal_type'],
'region': info['region'],
'avg_milk_liters_per_day': info['avg_milk_liters_per_day'],
'lifespan_years': info['lifespan_years'],
'primary_use': info['primary_use'],
'description': info['description'],
}
|