Source code for usda_fdc.models

"""
Data models for the USDA FDC API.
"""

from dataclasses import dataclass, field
from typing import Dict, List, Optional, Any, Union
from datetime import datetime


[docs]@dataclass class Nutrient: """ Represents a nutrient in a food item. """ id: int name: str amount: float unit_name: str nutrient_nbr: Optional[int] = None rank: Optional[int] = None
[docs] @classmethod def from_api_data(cls, data: Dict[str, Any]) -> 'Nutrient': """ Create a Nutrient instance from API data. Args: data: The API response data for a nutrient. Returns: A Nutrient instance. """ nutrient_data = data.get('nutrient', {}) return cls( id=nutrient_data.get('id'), name=nutrient_data.get('name'), amount=data.get('amount', 0), unit_name=nutrient_data.get('unitName'), nutrient_nbr=nutrient_data.get('number'), rank=nutrient_data.get('rank') )
[docs]@dataclass class FoodPortion: """ Represents a food portion. """ id: int amount: float gram_weight: float portion_description: Optional[str] = None modifier: Optional[str] = None measure_unit: Optional[str] = None
[docs] @classmethod def from_api_data(cls, data: Dict[str, Any]) -> 'FoodPortion': """ Create a FoodPortion instance from API data. Args: data: The API response data for a food portion. Returns: A FoodPortion instance. """ measure_unit_data = data.get('measureUnit', {}) return cls( id=data.get('id'), amount=data.get('amount', 0), gram_weight=data.get('gramWeight', 0), portion_description=data.get('portionDescription'), modifier=data.get('modifier'), measure_unit=measure_unit_data.get('name') )
[docs]@dataclass class Food: """ Represents a food item from the FDC database. """ fdc_id: int description: str data_type: str publication_date: Optional[str] = None food_class: Optional[str] = None food_category: Optional[str] = None scientific_name: Optional[str] = None brand_owner: Optional[str] = None brand_name: Optional[str] = None ingredients: Optional[str] = None serving_size: Optional[float] = None serving_size_unit: Optional[str] = None household_serving_fulltext: Optional[str] = None nutrients: List[Nutrient] = field(default_factory=list) food_portions: List[FoodPortion] = field(default_factory=list)
[docs] @classmethod def from_api_data(cls, data: Dict[str, Any], abridged: bool = False) -> 'Food': """ Create a Food instance from API data. Args: data: The API response data for a food. abridged: Whether the data is in abridged format. Returns: A Food instance. """ food = cls( fdc_id=data.get('fdcId'), description=data.get('description', ''), data_type=data.get('dataType', ''), publication_date=data.get('publicationDate'), food_class=data.get('foodClass'), food_category=data.get('foodCategory', {}).get('description') if data.get('foodCategory') else None, scientific_name=data.get('scientificName'), brand_owner=data.get('brandOwner'), brand_name=data.get('brandName'), ingredients=data.get('ingredients'), serving_size=data.get('servingSize'), serving_size_unit=data.get('servingSizeUnit'), household_serving_fulltext=data.get('householdServingFullText') ) # Parse nutrients if present if 'foodNutrients' in data and not abridged: food.nutrients = [ Nutrient.from_api_data(nutrient) for nutrient in data['foodNutrients'] if 'nutrient' in nutrient ] # Parse food portions if present if 'foodPortions' in data and not abridged: food.food_portions = [ FoodPortion.from_api_data(portion) for portion in data['foodPortions'] ] return food
[docs]@dataclass class SearchResultFood: """ Represents a food item in search results. """ fdc_id: int description: str data_type: str publication_date: Optional[str] = None food_category: Optional[str] = None brand_owner: Optional[str] = None brand_name: Optional[str] = None
[docs] @classmethod def from_api_data(cls, data: Dict[str, Any]) -> 'SearchResultFood': """ Create a SearchResultFood instance from API data. Args: data: The API response data for a search result food. Returns: A SearchResultFood instance. """ return cls( fdc_id=data.get('fdcId'), description=data.get('description', ''), data_type=data.get('dataType', ''), publication_date=data.get('publicationDate'), food_category=data.get('foodCategory'), brand_owner=data.get('brandOwner'), brand_name=data.get('brandName') )
[docs]@dataclass class SearchResult: """ Represents search results from the FDC API. """ foods: List[SearchResultFood] total_hits: int current_page: int total_pages: int
[docs] @classmethod def from_api_data(cls, data: Dict[str, Any]) -> 'SearchResult': """ Create a SearchResult instance from API data. Args: data: The API response data for search results. Returns: A SearchResult instance. """ foods = [ SearchResultFood.from_api_data(food) for food in data.get('foods', []) ] return cls( foods=foods, total_hits=data.get('totalHits', 0), current_page=data.get('currentPage', 1), total_pages=data.get('totalPages', 1) )