The easiest way to get accurate nutrition data in Python
# Install the Python SDK pip install avocavo # Or with conda conda install -c conda-forge avocavo
import avocavo as av
# One-time OAuth login (opens browser)
av.login() # Google OAuth (default)
av.auto_setup_api_key() # One-time API key setup
# Now use the nutrition API without API keys!
result = av.analyze_ingredient("2 cups chocolate chips")
print(f"Calories: {result.nutrition.calories}")
print(f"Protein: {result.nutrition.protein}g")
print(f"USDA: {result.usda_match.description}")from avocavo import NutritionAPI
client = NutritionAPI(api_key="your_api_key_here")
result = client.analyze_ingredient("1 cup rice")
print(f"Calories: {result.nutrition.calories}")Install the package and authenticate using OAuth for secure access to the nutrition API.
import avocavo as av
# Login once, use everywhere
av.login() # Opens browser for Google OAuth
av.auto_setup_api_key() # One-time API key setup
# Credentials stored securely with keyring
result = av.analyze_ingredient("1 cup rice")
# Check login status
if av.is_logged_in():
user = av.get_current_user()
print(f"Logged in as: {user['email']}")
# Logout when done
av.logout()from avocavo import NutritionAPI
# Direct API key usage
client = NutritionAPI(api_key="your_api_key")
result = client.analyze_ingredient("1 cup rice")# Set environment variable
export AVOCAVO_API_KEY="your_api_key_here"
# API key automatically detected
import avocavo as av
result = av.analyze_ingredient("1 cup rice")import avocavo as av
# Any ingredient with quantity
result = av.analyze_ingredient("2 tbsp olive oil")
if result.success:
nutrition = result.nutrition
print(f"Calories: {nutrition.calories}")
print(f"Fat: {nutrition.fat}g")
print(f"Protein: {nutrition.protein}g")
print(f"Carbs: {nutrition.carbs}g")
print(f"Fiber: {nutrition.fiber}g")
print(f"Sodium: {nutrition.sodium}mg")
# USDA verification
usda = result.usda_match
print(f"\nUSDA FDC ID: {usda.fdc_id}")
print(f"Description: {usda.description}")
print(f"Data Type: {usda.data_type}")
print(f"Verify: {result.verification_url}")
else:
print(f"Error: {result.error}")result = av.analyze_ingredient("1 cup cooked brown rice")
nutrition = result.nutrition
# Core nutrients
print(f"Calories: {nutrition.calories}")
print(f"Protein: {nutrition.protein}g")
print(f"Carbohydrates: {nutrition.carbs}g")
print(f"Total Fat: {nutrition.fat}g")
# Detailed breakdown
print(f"Dietary Fiber: {nutrition.fiber}g")
print(f"Sugars: {nutrition.sugar}g")
print(f"Saturated Fat: {nutrition.saturated_fat}g")
# Minerals
print(f"Sodium: {nutrition.sodium}mg")
print(f"Calcium: {nutrition.calcium}mg")
print(f"Iron: {nutrition.iron}mg")
print(f"Potassium: {nutrition.potassium}mg")
# Vitamins (when available)
print(f"Vitamin A: {nutrition.vitamin_a}mcg")
print(f"Vitamin C: {nutrition.vitamin_c}mg")
# System performance & caching
print(f"\nFrom Cache: {result.from_cache}") # True/False
print(f"Cache Type: {result.cache_type}") # "redis" | "supabase" | None
print(f"Processing Time: {result.processing_time_ms}ms") # Typically 300-400ms
print(f"Method Used: {result.method_used}") # "sql_exact" | "fuzzy_match_90%"
# Parsing details
print(f"\nParsing Info:")
print(f"Estimated Grams: {result.estimated_grams}") # 195.0
print(f"Parsed Name: {result.ingredient_name}") # "1 cup cooked brown rice"Our multi-method parsing system handles complex ingredient descriptions with natural language support. Perfect for real-world recipes with natural language ingredients.
# Complex natural language ingredients that work perfectly
import avocavo as av
# Natural language portions that other APIs can't handle
ingredients = [
"1 handful of baby spinach",
"a splash of vanilla extract",
"1 very small pinch of salt",
"2 medium bananas, ripe",
"a drizzle of extra virgin olive oil",
"1 generous dollop of Greek yogurt",
"a few sprigs of fresh thyme",
"1 small bunch of fresh cilantro",
"a squeeze of fresh lemon juice"
]
print("Advanced Parsing Demonstration:")
print("=" * 50)
for ingredient in ingredients:
result = av.analyze_ingredient(ingredient)
if result.success:
print(f"ā
{ingredient}")
print(f" Calories: {result.nutrition.calories}")
print(f" Method: {result.method_used}")
print(f" Parsing: {result.parsing.quantity} {result.parsing.unit} {result.parsing.ingredient_name}")
print(f" Estimated grams: {result.estimated_grams}g")
print()
else:
print(f"ā {ingredient}: {result.error}")
# Advanced Recipe with Mixed Ingredient Types
print("\n" + "=" * 50)
print("Advanced Recipe Analysis:")
print("=" * 50)
recipe = av.analyze_recipe([
"2 cups all-purpose flour", # Traditional measurement
"1 handful of baby spinach", # Natural language portion
"a splash of vanilla extract", # Vague quantity description
"1 very small pinch of salt", # Size modifier + traditional
"2 medium bananas, ripe", # Size + ripeness descriptor
"a drizzle of olive oil", # Cooking-style portion
"1 generous dollop of yogurt" # Informal + size modifier
], servings=4)
if recipe.success:
print(f"Recipe Analysis Success! ({recipe.processing_time_ms}ms)")
print(f"Per serving: {recipe.nutrition.per_serving.calories} calories")
print(f"USDA matches: {recipe.usda_matches}/{len(recipe.nutrition.ingredients)}")
print("\nIngredient breakdown:")
for ingredient in recipe.nutrition.ingredients:
if ingredient.success:
print(f" ā
{ingredient.ingredient}: {ingredient.nutrition.calories} cal")
print(f" Parsing method: {ingredient.method_used}")
print(f" Powered by USDA: {ingredient.usda_match.description if ingredient.usda_match else 'N/A'}")
else:
print(f" ā {ingredient.ingredient}: Failed")
else:
print(f"Recipe failed: {recipe.error}")
print("\nšÆ Key Features Demonstrated:")
print("⢠Size modifiers: 'very small', 'medium', 'generous'")
print("⢠Natural portions: 'handful', 'splash', 'drizzle', 'dollop'")
print("⢠Complex descriptors: 'extra virgin', 'fresh', 'ripe'")
print("⢠Traditional + modern mixing in same recipe")
print("⢠100% USDA-verifiable results with parsing transparency")Every response includes detailed parsing information so you can understand exactly how we processed your ingredient. This transparency helps you trust our results and optimize your inputs.
import avocavo as av
# Get detailed response with full parsing breakdown
result = av.analyze_ingredient("1 handful of baby spinach")
print("š PARSING TRANSPARENCY:")
print("=" * 50)
print(f"Original input: {result.original_ingredient}") # "1 handful of baby spinach"
print(f"Extracted quantity: {result.parsing.quantity}") # 1
print(f"Recognized unit: {result.parsing.unit}") # "handful"
print(f"Clean ingredient: {result.parsing.ingredient_name}") # "baby spinach"
print(f"Estimated grams: {result.estimated_grams}") # 30
print("\nšÆ HOW WE FOUND THE ANSWER:")
print("=" * 50)
print(f"Method used: {result.method_used}") # "gpt_normalized"
print(f"Parsing tier: {result.portion_source}") # "gpt_processing"
print(f"Processing time: {result.processing_time_ms}ms") # 23.4
print(f"From cache: {result.cached}") # False
print("\nā
USDA VERIFICATION:")
print("=" * 50)
print(f"USDA FDC ID: {result.usda_match.fdc_id}") # 168462
print(f"Description: {result.usda_match.description}") # "Spinach, baby, raw"
print(f"Data type: {result.usda_match.data_type}") # "sr_legacy_food"
print(f"Verify at: {result.verification_url}")
print("\nš„ NUTRITION RESULTS:")
print("=" * 50)
print(f"Calories: {result.nutrition.calories}") # 7
print(f"Protein: {result.nutrition.protein}g") # 0.9
print(f"Total fat: {result.nutrition.total_fat}g") # 0.1
print(f"Carbs: {result.nutrition.carbohydrates}g") # 1.1
print(f"Fiber: {result.nutrition.fiber}g") # 0.7
print(f"Sodium: {result.nutrition.sodium}mg") # 24# See exactly how different ingredients are parsed:
# Direct SQL Match (fastest)
result = av.analyze_ingredient("1 cup rice")
print(f"Method: {result.method_used}") # "sql_exact"
print(f"Cached: {result.cached}") # True/False
# Fuzzy Match (spelling variations)
result = av.analyze_ingredient("1 cup ryce")
print(f"Method: {result.method_used}") # "fuzzy_match_90%"
print(f"Cached: {result.cached}") # True/False
# GPT-Powered Ingredient Normalization
result = av.analyze_ingredient("1 large apple")
print(f"Method: {result.method_used}") # "gpt_normalized"
print(f"Cached: {result.cached}") # True/False
# Complex Ingredient Processing
result = av.analyze_ingredient("1 very small pinch of salt")
print(f"Method: {result.method_used}") # "gpt_normalized"
print(f"Cached: {result.cached}") # True/False
# Generic Portion Fallback
result = av.analyze_ingredient("a splash of vanilla extract")
print(f"Method: {result.method_used}") # "redis_cache"
print(f"Cached: {result.cached}") # True/False
# Small Measurement Handling
result = av.analyze_ingredient("a dash of cinnamon")
print(f"Method: {result.method_used}") # "supabase_cache"
print(f"Cached: {result.cached}") # True/Falseimport avocavo as av
# Full recipe with per-serving calculations
recipe = av.analyze_recipe([
"2 cups all-purpose flour",
"1 cup whole milk",
"2 large eggs",
"1/4 cup sugar",
"2 tsp baking powder",
"1/2 tsp salt"
], servings=8)
if recipe.success:
# Per serving nutrition
per_serving = recipe.nutrition.per_serving
print(f"Per serving ({recipe.servings} servings):")
print(f" Calories: {per_serving.calories}")
print(f" Protein: {per_serving.protein}g")
print(f" Carbs: {per_serving.carbs}g")
print(f" Fat: {per_serving.fat}g")
# Total recipe nutrition
total = recipe.nutrition.total
print(f"\nTotal recipe:")
print(f" Calories: {total.calories}")
print(f" Protein: {total.protein}g")
# Recipe-level performance
print(f"\nRecipe Performance:")
print(f" USDA Matches: {recipe.usda_matches}") # Number of USDA-verifiable ingredients
print(f" Processing Time: {recipe.processing_time_ms}ms") # Total processing time
# Note: All nutrition data is USDA-verifiable via included FDC IDs and verification URLs
# Individual ingredient details
print(f"\nIngredient Details:")
for ingredient in recipe.nutrition.ingredients:
if ingredient.success:
print(f" ā
{ingredient.ingredient}: {ingredient.nutrition.calories} cal")
if ingredient.usda_match:
print(f" USDA: {ingredient.usda_match.description}")
print(f" Verify: {ingredient.verification_url}")
else:
print(f" ā {ingredient.ingredient}: Failed to analyze")
else:
print(f"Recipe analysis failed: {recipe.error}")# Analyze recipe with metadata
recipe_data = {
"name": "Healthy Green Smoothie",
"description": "A nutritious smoothie packed with vitamins",
"ingredients": [
"1 banana",
"100g spinach",
"1 cup almond milk",
"1 tbsp honey",
"1/2 cup frozen mango"
],
"servings": 2,
"prep_time": 5, # minutes
"cook_time": 0
}
recipe = av.analyze_recipe(
ingredients=recipe_data["ingredients"],
servings=recipe_data["servings"],
name=recipe_data["name"]
)
# Calculate nutrition density
if recipe.success:
per_serving = recipe.nutrition.per_serving
# Macronutrient percentages
total_cals = per_serving.calories
protein_cals = per_serving.protein * 4
carb_cals = per_serving.carbs * 4
fat_cals = per_serving.fat * 9
print(f"Macronutrient breakdown per serving:")
print(f" Protein: {protein_cals/total_cals*100:.1f}%")
print(f" Carbs: {carb_cals/total_cals*100:.1f}%")
print(f" Fat: {fat_cals/total_cals*100:.1f}%")
# Nutrition density score
fiber_score = min(per_serving.fiber / 25 * 100, 100) # 25g daily target
protein_score = min(per_serving.protein / 50 * 100, 100) # 50g daily target
print(f"\nNutrition Quality:")
print(f" Fiber Score: {fiber_score:.1f}/100")
print(f" Protein Score: {protein_score:.1f}/100")Batch processing is available on all plans with varying limits: Free (3), Starter (8), Professional (25), Enterprise (50) ingredients per batch.
import avocavo as av
# Analyze multiple ingredients efficiently
ingredients_list = [
"1 cup quinoa",
"2 tbsp olive oil",
"4 oz salmon",
"1 cup spinach",
"1/4 cup almonds"
]
batch_result = av.analyze_batch(ingredients_list)
print(f"Batch Analysis Results:")
print(f"Success rate: {batch_result.success_rate}%")
print(f"Processed: {len(batch_result.results)} ingredients")
print(f"Processing time: {batch_result.total_processing_time_ms}ms")
# Iterate through results
for item in batch_result.results:
if item.success:
print(f"ā
{item.ingredient}: {item.nutrition.calories} cal, {item.nutrition.protein}g protein")
else:
print(f"ā {item.ingredient}: {item.error}")
# Calculate totals
total_calories = sum(item.nutrition.calories for item in batch_result.results if item.success)
total_protein = sum(item.nutrition.protein for item in batch_result.results if item.success)
print(f"\nTotal: {total_calories} calories, {total_protein}g protein")# Batch processing with error handling and progress
import time
def analyze_shopping_list(ingredients, chunk_size=5):
"""Analyze a large shopping list in chunks"""
results = []
# Process in chunks to respect rate limits
for i in range(0, len(ingredients), chunk_size):
chunk = ingredients[i:i + chunk_size]
print(f"Processing chunk {i//chunk_size + 1}/{(len(ingredients)-1)//chunk_size + 1}...")
try:
batch_result = av.analyze_batch(chunk)
results.extend(batch_result.results)
# Show progress
successful = sum(1 for r in batch_result.results if r.success)
print(f" ā
{successful}/{len(chunk)} successful")
except Exception as e:
print(f" ā Chunk failed: {e}")
# Continue with next chunk
# Brief pause between chunks
time.sleep(0.1)
return results
# Usage
shopping_list = [
"2 lbs ground beef", "1 dozen eggs", "1 gallon milk",
"2 lbs chicken breast", "1 bag brown rice", "2 lbs bananas",
"1 lb spinach", "1 lb carrots", "1 jar peanut butter",
"1 loaf whole wheat bread", "1 lb oats", "1 lb almonds"
]
results = analyze_shopping_list(shopping_list)
# Summarize results
successful_results = [r for r in results if r.success]
total_calories = sum(r.nutrition.calories for r in successful_results)
total_cost_estimate = len(successful_results) * 0.02 # Rough API cost estimate
print(f"\nShopping List Summary:")
print(f"Analyzed: {len(successful_results)}/{len(shopping_list)} items")
print(f"Total calories: {total_calories:,.0f}")
print("Estimated API cost: $" + f"{total_cost_estimate:.2f}")Search by UPC/barcode across USDA Branded Foods and Open Food Facts databases. Perfect for barcode scanning apps!
import avocavo as av
# Search for a product by UPC
result = av.search_upc("034000052004")
if result.found:
print(f"Product: {result.product.product_name}")
print(f"Brand: {result.product.brand}")
print(f"Sources: {result.product.sources}")
print(f"Categories: {len(result.product.categories)} categories")
# Access nutrition data if available
if result.product.has_nutrition:
nutrition = result.product.nutrition['merged']
calories = nutrition.get('energy-kcal', 'N/A')
protein = nutrition.get('proteins', 'N/A')
print(f"Calories: {calories}")
print(f"Protein: {protein}g")
# Show data sources
print(f"Data from: {', '.join(result.product.sources)}")
print(f"Processing time: {result.processing_time_ms}ms")
else:
print(f"Product not found: {result.error}")# Search multiple UPCs efficiently
upcs = [
"034000052004", # Known UPC (Hershey's Cocoa)
"123456789012", # Test UPC
"999999999999", # Invalid UPC
]
batch_result = av.search_upc_batch(upcs)
print(f"Batch Results: {batch_result.found_count}/{batch_result.total_count} found")
print(f"Success Rate: {batch_result.success_rate:.1f}%")
print(f"Processing Time: {batch_result.processing_time_ms}ms")
# Process individual results
for upc_result in batch_result.results:
if upc_result.found:
product = upc_result.product
print(f"ā
{upc_result.upc}: {product.product_name}")
print(f" Brand: {product.brand}")
print(f" Sources: {product.sources}")
else:
print(f"ā {upc_result.upc}: {upc_result.error}")from avocavo import NutritionAPI
# Initialize client with API key
client = NutritionAPI(api_key="your_api_key")
# Search UPC with client instance
result = client.search_upc("034000052004")
if result.found:
product = result.product
print(f"Product: {product.product_name}")
print(f"Brand: {product.brand}")
# Check data quality indicators
if product.quality_score:
print(f"Quality Score: {product.quality_score}")
# Show serving information
if hasattr(product, 'serving_info'):
serving = product.serving_info
if 'serving_size' in serving:
print(f"Serving Size: {serving['serving_size']}")
# Multi-source data advantages
if product.is_multi_source:
print("⨠Enhanced data from multiple sources!")
# Check UPC service health
health = client.upc_health_check()
print(f"UPC Service Status: {health['status']}")import avocavo as av
from typing import List, Dict, Optional
class RecipeNutritionCalculator:
"""Calculate nutrition for recipes in your app"""
def __init__(self):
# Initialize with OAuth login
if not av.is_logged_in():
av.login()
av.auto_setup_api_key() # One-time API key setup
def calculate_recipe_nutrition(self,
ingredients: List[str],
servings: int = 1,
recipe_name: str = None) -> Dict:
"""Calculate comprehensive nutrition for a recipe"""
try:
recipe = av.analyze_recipe(ingredients, servings, name=recipe_name)
if recipe.success:
per_serving = recipe.nutrition.per_serving
total = recipe.nutrition.total
return {
'success': True,
'recipe_name': recipe_name,
'servings': servings,
'per_serving': {
'calories': per_serving.calories,
'protein': per_serving.protein,
'carbs': per_serving.carbs,
'fat': per_serving.fat,
'fiber': per_serving.fiber,
'sodium': per_serving.sodium
},
'total': {
'calories': total.calories,
'protein': total.protein,
'carbs': total.carbs,
'fat': total.fat
},
'ingredient_analysis': [
{
'ingredient': ing.original,
'calories': ing.nutrition.calories if ing.success else 0,
'usda_match': ing.usda_match.description if ing.success else None,
'success': ing.success
}
for ing in recipe.ingredients
],
'usda_match_rate': f"{recipe.successful_matches}/{len(recipe.ingredients)}",
'processing_time_ms': recipe.processing_time_ms
}
else:
return {'success': False, 'error': recipe.error}
except Exception as e:
return {'success': False, 'error': str(e)}
# Usage in your app
calculator = RecipeNutritionCalculator()
# Calculate nutrition for user's recipe
user_recipe = [
"2 cups whole wheat flour",
"1 cup Greek yogurt",
"2 large eggs",
"1/4 cup honey",
"1 tsp vanilla extract",
"1 tsp baking soda"
]
nutrition_data = calculator.calculate_recipe_nutrition(
ingredients=user_recipe,
servings=12,
recipe_name="Healthy Muffins"
)
if nutrition_data['success']:
print(f"Recipe: {nutrition_data['recipe_name']}")
print(f"Per muffin: {nutrition_data['per_serving']['calories']} calories")
print(f"USDA matches: {nutrition_data['usda_match_rate']}")
# Store in your database
# save_recipe_nutrition(recipe_id, nutrition_data)
else:
print(f"Error: {nutrition_data['error']}")import avocavo as av
from datetime import datetime, date
from typing import List, Dict
class FitnessNutritionTracker:
"""Track daily nutrition from food entries"""
def __init__(self):
if not av.is_logged_in():
av.login()
av.auto_setup_api_key() # One-time API key setup
def track_daily_nutrition(self, food_entries: List[Dict]) -> Dict:
"""
Track nutrition from daily food entries
Args:
food_entries: List of {"food": "1 cup rice", "meal": "lunch", "time": "12:30"}
"""
# Extract just the food descriptions for batch processing
foods = [entry["food"] for entry in food_entries]
# Use batch processing for efficiency
batch_result = av.analyze_batch(foods)
# Initialize daily totals
daily_totals = {
'calories': 0, 'protein': 0, 'carbs': 0, 'fat': 0,
'fiber': 0, 'sodium': 0, 'sugar': 0
}
# Group by meal
meals = {'breakfast': [], 'lunch': [], 'dinner': [], 'snacks': []}
# Process results
for i, result in enumerate(batch_result.results):
if result.success:
nutrition = result.nutrition
entry = food_entries[i]
# Add to daily totals
daily_totals['calories'] += nutrition.calories
daily_totals['protein'] += nutrition.protein
daily_totals['carbs'] += nutrition.carbs
daily_totals['fat'] += nutrition.fat
daily_totals['fiber'] += nutrition.fiber
daily_totals['sodium'] += nutrition.sodium
daily_totals['sugar'] += nutrition.sugar
# Group by meal
meal = entry.get('meal', 'snacks')
meals[meal].append({
'food': entry['food'],
'time': entry.get('time'),
'calories': nutrition.calories,
'protein': nutrition.protein,
'carbs': nutrition.carbs,
'fat': nutrition.fat
})
# Calculate macro percentages
total_cals = daily_totals['calories']
if total_cals > 0:
macro_percentages = {
'protein_percent': (daily_totals['protein'] * 4 / total_cals) * 100,
'carbs_percent': (daily_totals['carbs'] * 4 / total_cals) * 100,
'fat_percent': (daily_totals['fat'] * 9 / total_cals) * 100
}
else:
macro_percentages = {'protein_percent': 0, 'carbs_percent': 0, 'fat_percent': 0}
return {
'date': date.today().isoformat(),
'daily_totals': daily_totals,
'macro_percentages': macro_percentages,
'meals': meals,
'foods_analyzed': len([r for r in batch_result.results if r.success]),
'total_foods': len(food_entries),
'success_rate': batch_result.success_rate
}
def get_nutrition_goals_progress(self, daily_nutrition: Dict, user_goals: Dict) -> Dict:
"""Compare daily nutrition against user goals"""
progress = {}
for nutrient, consumed in daily_nutrition['daily_totals'].items():
if nutrient in user_goals:
goal = user_goals[nutrient]
progress[nutrient] = {
'consumed': consumed,
'goal': goal,
'percent_of_goal': (consumed / goal * 100) if goal > 0 else 0,
'remaining': max(0, goal - consumed)
}
return progress
# Usage example
tracker = FitnessNutritionTracker()
# User's daily food log
todays_foods = [
{"food": "1 cup oatmeal with banana", "meal": "breakfast", "time": "7:30"},
{"food": "1 tbsp almond butter", "meal": "breakfast", "time": "7:30"},
{"food": "6 oz grilled chicken breast", "meal": "lunch", "time": "12:00"},
{"food": "2 cups mixed salad", "meal": "lunch", "time": "12:00"},
{"food": "2 tbsp olive oil dressing", "meal": "lunch", "time": "12:00"},
{"food": "1 medium apple", "meal": "snacks", "time": "15:30"},
{"food": "8 oz salmon fillet", "meal": "dinner", "time": "19:00"},
{"food": "1 cup steamed broccoli", "meal": "dinner", "time": "19:00"},
{"food": "1/2 cup brown rice", "meal": "dinner", "time": "19:00"}
]
# Track daily nutrition
daily_nutrition = tracker.track_daily_nutrition(todays_foods)
print(f"Daily Nutrition Summary for {daily_nutrition['date']}:")
print(f"Total Calories: {daily_nutrition['daily_totals']['calories']:.0f}")
print(f"Protein: {daily_nutrition['daily_totals']['protein']:.1f}g ({daily_nutrition['macro_percentages']['protein_percent']:.1f}%)")
print(f"Carbs: {daily_nutrition['daily_totals']['carbs']:.1f}g ({daily_nutrition['macro_percentages']['carbs_percent']:.1f}%)")
print(f"Fat: {daily_nutrition['daily_totals']['fat']:.1f}g ({daily_nutrition['macro_percentages']['fat_percent']:.1f}%)")
# Check against goals
user_goals = {
'calories': 2000,
'protein': 150, # grams
'carbs': 250, # grams
'fat': 67 # grams
}
progress = tracker.get_nutrition_goals_progress(daily_nutrition, user_goals)
print(f"\nGoal Progress:")
for nutrient, data in progress.items():
print(f"{nutrient.title()}: {data['consumed']:.1f}/{data['goal']} ({data['percent_of_goal']:.1f}%)")import avocavo as av
import json
from typing import List, Dict
class RestaurantMenuAnalyzer:
"""Analyze nutrition for restaurant menu items"""
def __init__(self):
if not av.is_logged_in():
av.login()
av.auto_setup_api_key() # One-time API key setup
def analyze_menu_item(self,
item_name: str,
ingredients: List[str],
serving_size: str = "1 serving") -> Dict:
"""Analyze a single menu item"""
try:
# Use batch processing for efficiency
batch_result = av.analyze_batch(ingredients)
# Calculate totals
total_nutrition = {
'calories': 0, 'protein': 0, 'carbs': 0, 'fat': 0,
'fiber': 0, 'sodium': 0, 'saturated_fat': 0
}
ingredient_details = []
for result in batch_result.results:
if result.success:
n = result.nutrition
# Add to totals
total_nutrition['calories'] += n.calories
total_nutrition['protein'] += n.protein
total_nutrition['carbs'] += n.carbs
total_nutrition['fat'] += n.fat
total_nutrition['fiber'] += n.fiber
total_nutrition['sodium'] += n.sodium
total_nutrition['saturated_fat'] += getattr(n, 'saturated_fat', 0)
ingredient_details.append({
'ingredient': result.ingredient,
'calories': n.calories,
'usda_description': result.usda_match.description if hasattr(result, 'usda_match') else None
})
else:
ingredient_details.append({
'ingredient': result.ingredient,
'error': result.error,
'calories': 0
})
# Calculate nutrition facts panel values (based on FDA requirements)
nutrition_facts = {
'serving_size': serving_size,
'calories': round(total_nutrition['calories']),
'total_fat': round(total_nutrition['fat'], 1),
'saturated_fat': round(total_nutrition['saturated_fat'], 1),
'sodium': round(total_nutrition['sodium']),
'total_carbs': round(total_nutrition['carbs'], 1),
'dietary_fiber': round(total_nutrition['fiber'], 1),
'protein': round(total_nutrition['protein'], 1),
# Daily Value percentages (based on 2000 calorie diet)
'fat_dv': round((total_nutrition['fat'] / 65) * 100),
'saturated_fat_dv': round((total_nutrition['saturated_fat'] / 20) * 100),
'sodium_dv': round((total_nutrition['sodium'] / 2300) * 100),
'carbs_dv': round((total_nutrition['carbs'] / 300) * 100),
'fiber_dv': round((total_nutrition['fiber'] / 25) * 100),
'protein_dv': round((total_nutrition['protein'] / 50) * 100)
}
return {
'success': True,
'item_name': item_name,
'nutrition_facts': nutrition_facts,
'ingredient_analysis': ingredient_details,
'success_rate': batch_result.success_rate,
'total_ingredients': len(ingredients),
'successful_matches': len([r for r in batch_result.results if r.success])
}
except Exception as e:
return {
'success': False,
'item_name': item_name,
'error': str(e)
}
def analyze_full_menu(self, menu_items: Dict[str, List[str]]) -> Dict:
"""Analyze an entire menu"""
menu_analysis = {}
for item_name, ingredients in menu_items.items():
print(f"Analyzing: {item_name}...")
analysis = self.analyze_menu_item(item_name, ingredients)
menu_analysis[item_name] = analysis
# Generate menu summary
successful_items = [item for item in menu_analysis.values() if item['success']]
if successful_items:
avg_calories = sum(item['nutrition_facts']['calories'] for item in successful_items) / len(successful_items)
high_sodium_items = [item['item_name'] for item in successful_items
if item['nutrition_facts']['sodium_dv'] > 20] # >20% DV
summary = {
'total_items_analyzed': len(menu_items),
'successful_analyses': len(successful_items),
'average_calories': round(avg_calories),
'high_sodium_items': high_sodium_items,
'analysis_timestamp': datetime.now().isoformat()
}
else:
summary = {'error': 'No items could be analyzed successfully'}
return {
'menu_summary': summary,
'item_analyses': menu_analysis
}
# Usage example
analyzer = RestaurantMenuAnalyzer()
# Sample restaurant menu items
menu_items = {
"Classic Burger": [
"1 beef patty 6 oz",
"1 hamburger bun",
"2 slices cheddar cheese",
"2 leaves lettuce",
"2 slices tomato",
"1 tbsp mayonnaise"
],
"Caesar Salad": [
"4 cups romaine lettuce",
"2 tbsp caesar dressing",
"1/4 cup parmesan cheese",
"1/2 cup croutons",
"6 oz grilled chicken breast"
],
"Margherita Pizza": [
"1 pizza dough 12 inch",
"1/2 cup tomato sauce",
"8 oz fresh mozzarella",
"10 fresh basil leaves",
"2 tbsp olive oil"
]
}
# Analyze the menu
menu_analysis = analyzer.analyze_full_menu(menu_items)
# Display results
print("\n=== MENU NUTRITION ANALYSIS ===")
print(f"Items analyzed: {menu_analysis['menu_summary']['successful_analyses']}/{menu_analysis['menu_summary']['total_items_analyzed']}")
print(f"Average calories: {menu_analysis['menu_summary']['average_calories']}")
if menu_analysis['menu_summary']['high_sodium_items']:
print(f"High sodium items: {', '.join(menu_analysis['menu_summary']['high_sodium_items'])}")
print("\n=== INDIVIDUAL ITEMS ===")
for item_name, analysis in menu_analysis['item_analyses'].items():
if analysis['success']:
nf = analysis['nutrition_facts']
print(f"\n{item_name}:")
print(f" Calories: {nf['calories']}")
print(f" Fat: {nf['total_fat']}g ({nf['fat_dv']}% DV)")
print(f" Sodium: {nf['sodium']}mg ({nf['sodium_dv']}% DV)")
print(f" Protein: {nf['protein']}g")
print(f" USDA matches: {analysis['successful_matches']}/{analysis['total_ingredients']}")
else:
print(f"\n{item_name}: Analysis failed - {analysis['error']}")
# Save results to file
with open('menu_nutrition_analysis.json', 'w') as f:
json.dump(menu_analysis, f, indent=2)
print(f"\nDetailed analysis saved to menu_nutrition_analysis.json")from avocavo import (
ApiError,
RateLimitError,
AuthenticationError,
ValidationError,
NetworkError
)
import avocavo as av
def robust_nutrition_analysis(ingredient: str):
"""Nutrition analysis with comprehensive error handling"""
try:
result = av.analyze_ingredient(ingredient)
if result.success:
print(f"ā
{ingredient}")
print(f" Calories: {result.nutrition.calories}")
print(f" USDA: {result.usda_match.description}")
print(f" Verify: {result.verification_url}")
return result
else:
print(f"ā {ingredient}: {result.error}")
return None
except AuthenticationError as e:
print(f"š Authentication failed: {e.message}")
print("š” Try: av.login() or check your API key")
return None
except RateLimitError as e:
print(f"ā±ļø Rate limit exceeded: {e.message}")
print(f" Current usage: {e.usage}/{e.limit}")
print(f" Resets at: {e.reset_time}")
print("š” Consider upgrading your plan or waiting")
return None
except ValidationError as e:
print(f"š Invalid input: {e.message}")
print("š” Check ingredient format: '1 cup rice' not just 'rice'")
return None
except NetworkError as e:
print(f"š Network error: {e.message}")
print("š” Check internet connection and try again")
return None
except ApiError as e:
print(f"šØ API error: {e.message}")
print(f" Status code: {e.status_code}")
print("š” Contact support if this persists")
return None
except Exception as e:
print(f"ā Unexpected error: {str(e)}")
print("š” Please report this issue")
return None
# Usage
ingredients = [
"1 cup brown rice",
"invalid ingredient format",
"2 tbsp olive oil",
"", # Empty string
"1 cup imaginary food that doesn't exist"
]
successful_analyses = []
for ingredient in ingredients:
if ingredient.strip(): # Skip empty strings
result = robust_nutrition_analysis(ingredient)
if result:
successful_analyses.append(result)
print(f"\nSuccessfully analyzed: {len(successful_analyses)}/{len([i for i in ingredients if i.strip()])} ingredients")import time
import avocavo as av
from avocavo import NetworkError, RateLimitError
def analyze_with_retry(ingredient: str, max_retries: int = 3, backoff_factor: float = 1.0):
"""Analyze ingredient with exponential backoff retry logic"""
for attempt in range(max_retries):
try:
result = av.analyze_ingredient(ingredient)
return result
except RateLimitError as e:
if attempt == max_retries - 1:
raise # Re-raise on final attempt
# Wait for rate limit reset or exponential backoff
wait_time = min(e.retry_after or (backoff_factor * (2 ** attempt)), 60)
print(f"Rate limited. Waiting {wait_time:.1f}s before retry {attempt + 1}/{max_retries}")
time.sleep(wait_time)
except NetworkError as e:
if attempt == max_retries - 1:
raise
wait_time = backoff_factor * (2 ** attempt)
print(f"Network error. Retrying in {wait_time:.1f}s... ({attempt + 1}/{max_retries})")
time.sleep(wait_time)
raise Exception(f"Failed after {max_retries} attempts")
# Usage with timeout configuration
from avocavo import NutritionAPI
# Configure client with custom timeout
client = NutritionAPI(
api_key="your_api_key",
timeout=30, # 30 second timeout
max_retries=3
)
# Analyze with retry logic
try:
result = analyze_with_retry("1 cup quinoa", max_retries=3)
if result.success:
print(f"Success: {result.nutrition.calories} calories")
except Exception as e:
print(f"Final failure: {e}")result.success before accessing nutrition dataresult = av.analyze_ingredient("1 cup cooked brown rice")
# Core Properties
result.success # bool: True if analysis succeeded
result.ingredient # str: Original ingredient text
result.nutrition # Nutrition: Complete nutrition data
result.usda_match # USDAMatch: USDA verification info
result.verification_url # str: Direct USDA verification link
# Performance & System Data
result.from_cache # bool: True if served from cache
result.cache_type # str: "redis" | "supabase" | None
result.processing_time_ms # float: Processing time in milliseconds
result.method_used # str: "llm_driven_search" | "sql_exact" | "fuzzy_match"
# Parsing Details
result.estimated_grams # float: Estimated grams for ingredient
result.ingredient_name # str: Parsed ingredient name
result.error # str: Error message if success=Falserecipe = av.analyze_recipe(ingredients, servings=4)
# Core Properties
recipe.success # bool: True if analysis succeeded
recipe.recipe # dict: Original recipe info
recipe.nutrition # RecipeNutrition: Complete nutrition breakdown
# Recipe Performance
recipe.usda_matches # int: Number of USDA-verifiable ingredients
recipe.processing_time_ms # float: Total processing time (sum of ingredients)
# Note: All data is USDA-verifiable via included FDC IDs and verification URLs
# Nutrition Breakdown
recipe.nutrition.total # Nutrition: Total recipe nutrition
recipe.nutrition.per_serving # Nutrition: Per-serving nutrition
recipe.nutrition.ingredients # List[RecipeIngredient]: Individual ingredients
# Individual Ingredient Details
for ingredient in recipe.nutrition.ingredients:
ingredient.ingredient # str: Ingredient text
ingredient.nutrition # Nutrition: Individual nutrition data
ingredient.usda_match # USDAMatch: USDA verification
ingredient.verification_url # str: USDA verification link (NEW)
ingredient.success # bool: Analysis success for this ingredient| Function | Description | Returns |
|---|---|---|
| av.analyze_ingredient(ingredient) | Analyze single ingredient | IngredientResult |
| av.analyze_recipe(ingredients, servings) | Analyze complete recipe | RecipeResult |
| av.analyze_batch(ingredients) | Batch analyze multiple ingredients | BatchResult |
| av.get_account_usage() | Check API usage and limits | AccountUsage |
| Function | Description | Example |
|---|---|---|
| av.login(provider="google") | OAuth login (opens browser) | av.login("github") |
| av.is_logged_in() | Check if logged in | if av.is_logged_in(): |
| av.get_current_user() | Get current user info | user = av.get_current_user() |
| av.logout() | Logout and clear credentials | av.logout() |
# IngredientResult
class IngredientResult:
success: bool
ingredient: str
nutrition: NutritionData
usda_match: USDAMatch
verification_url: str
error: str | None
from_cache: bool
processing_time_ms: float
# NutritionData
class NutritionData:
calories: float
protein: float # grams
carbs: float # grams
fat: float # grams
fiber: float # grams
sugar: float # grams
sodium: float # milligrams
calcium: float # milligrams
iron: float # milligrams
saturated_fat: float # grams
cholesterol: float # milligrams
# USDAMatch
class USDAMatch:
fdc_id: int
description: str
data_type: str # "Foundation", "SR Legacy", etc.
food_category: str
# RecipeResult
class RecipeResult:
success: bool
ingredients: List[IngredientResult]
nutrition: RecipeNutrition
servings: int
successful_matches: int
processing_time_ms: float
# RecipeNutrition
class RecipeNutrition:
total: NutritionData # Total recipe nutrition
per_serving: NutritionData # Per serving nutrition
# BatchResult
class BatchResult:
results: List[IngredientResult]
success_rate: float
total_processing_time_ms: float
successful_matches: int
# AccountUsage
class AccountUsage:
plan_name: str
usage: UsageData
class UsageData:
current_month: int
monthly_limit: int
remaining: int
reset_date: strWe're here to help you integrate our Python SDK successfully into your application.