The easiest way to get accurate nutrition data in Python
# Install the Python SDK pip install avocavo-nutrition # Or with conda conda install -c conda-forge avocavo-nutrition
import avocavo_nutrition as av # One-time OAuth login (opens browser) av.login() # Google OAuth (default) # 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_nutrition import NutritionAPI client = NutritionAPI(api_key="your_api_key_here") result = client.analyze_ingredient("1 cup rice") print(f"Calories: {result.nutrition.calories}")
Start with 1,000 free API calls - no credit card required!Get your free API key ā
import avocavo_nutrition as av # Login once, use everywhere av.login() # Opens browser for Google OAuth # 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_nutrition 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_nutrition as av result = av.analyze_ingredient("1 cup rice")
import avocavo_nutrition 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 (NEW in v1.7.3+) 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") # Sub-second response print(f"Method Used: {result.method_used}") # "llm_driven_search" | "sql_exact" # Parsing details (NEW in v1.7.3+) 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 7-tier hierarchical parsing system handles complex ingredient descriptions that no other nutrition API can process accurately. Perfect for real-world recipes with natural language ingredients.
# Complex natural language ingredients that work perfectly import avocavo_nutrition 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" USDA verified: {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_nutrition 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}") # "tiered_portion_conversion" print(f"Parsing tier: {result.portion_source}") # "tier_3_adjusted" 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: # TIER 1: Direct SQL Match (fastest) result = av.analyze_ingredient("1 cup rice") print(f"Method: {result.method_used}") # "sql_exact" print(f"Tier: {result.portion_source}") # "tier_1_exact" # TIER 2: Fuzzy Match (spelling variations) result = av.analyze_ingredient("1 cup ryce") print(f"Method: {result.method_used}") # "fuzzy_match" print(f"Tier: {result.portion_source}") # "tier_2_fuzzy" # TIER 3: Size Modifier Applied result = av.analyze_ingredient("1 large apple") print(f"Method: {result.method_used}") # "portion_adjusted" print(f"Tier: {result.portion_source}") # "tier_3_adjusted" # TIER 4: Complex Modifier Processing result = av.analyze_ingredient("1 very small pinch of salt") print(f"Method: {result.method_used}") # "modifier_adjusted_conversion" print(f"Tier: {result.portion_source}") # "tier_4_with_modifier" # TIER 5: Generic Portion Fallback result = av.analyze_ingredient("a splash of vanilla extract") print(f"Method: {result.method_used}") # "small_measurement_fallback" print(f"Tier: {result.portion_source}") # "tier_5_generic" # TIER 6: Small Measurement Handling result = av.analyze_ingredient("a dash of cinnamon") print(f"Method: {result.method_used}") # "small_measurement" print(f"Tier: {result.portion_source}") # "tier_6_small_measurement" # TIER 7: Smart USDA Matching result = av.analyze_ingredient("about 2 heaping tablespoons of chunky peanut butter") print(f"Method: {result.method_used}") # "llm_driven_search" print(f"Tier: {result.portion_source}") # "tier_7_semantic_match"
import avocavo_nutrition 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 (NEW in v1.7.3+) 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 (NEW in v1.7.3+) 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 (5), Starter (10), Professional (20), Enterprise (50+) ingredients per batch.
import avocavo_nutrition 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}")
import avocavo_nutrition 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() 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_nutrition 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() 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_nutrition 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() 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_nutrition import ( ApiError, RateLimitError, AuthenticationError, ValidationError, NetworkError ) import avocavo_nutrition 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_nutrition as av from avocavo_nutrition 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_nutrition 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 dataThe Python SDK now returns all the same fields as the raw API, including caching details, parsing information, and performance metrics for complete transparency.
result = 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 (NEW in v1.7.3+) 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 (NEW in v1.7.3+) result.estimated_grams # float: Estimated grams for ingredient result.ingredient_name # str: Parsed ingredient name result.error # str: Error message if success=False
recipe = 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 (NEW in v1.7.3+) 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: str
We're here to help you integrate our Python SDK successfully into your application.