This commit is contained in:
247
tests/test_fatsecret_api_v2.py
Executable file
247
tests/test_fatsecret_api_v2.py
Executable file
@@ -0,0 +1,247 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для тестирования API FatSecret
|
||||
Выполняет тестовые запросы к API FatSecret с использованием ключей из конфигурации приложения
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
import base64
|
||||
import requests
|
||||
import urllib.parse
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Загружаем .env файл
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
env_path = os.path.join(current_dir, ".env")
|
||||
load_dotenv(env_path)
|
||||
print(f"✅ Loaded .env from: {env_path}")
|
||||
|
||||
# Получаем API ключи из переменных окружения
|
||||
FATSECRET_CLIENT_ID = os.environ.get("FATSECRET_CLIENT_ID")
|
||||
FATSECRET_CLIENT_SECRET = os.environ.get("FATSECRET_CLIENT_SECRET")
|
||||
|
||||
if not FATSECRET_CLIENT_ID or not FATSECRET_CLIENT_SECRET:
|
||||
raise ValueError("FatSecret API keys not found in .env file")
|
||||
|
||||
print(f"🔑 Using FatSecret API keys: CLIENT_ID={FATSECRET_CLIENT_ID[:8]}...")
|
||||
customer_key = os.environ.get("FATSECRET_CUSTOMER_KEY")
|
||||
if customer_key:
|
||||
print(f"🔑 Using CUSTOMER_KEY={customer_key[:8]}...")
|
||||
|
||||
|
||||
def get_oauth_token():
|
||||
"""Получение OAuth 2.0 токена для доступа к API"""
|
||||
print("🔄 Getting OAuth token...")
|
||||
|
||||
# Создаем заголовок авторизации с Base64-кодированными ID и секретом
|
||||
auth_string = f"{FATSECRET_CLIENT_ID}:{FATSECRET_CLIENT_SECRET}"
|
||||
auth_header = base64.b64encode(auth_string.encode()).decode()
|
||||
|
||||
# Полный вывод учетных данных для диагностики
|
||||
print(f"🔑 CLIENT_ID: {FATSECRET_CLIENT_ID}")
|
||||
if FATSECRET_CLIENT_SECRET:
|
||||
print(f"🔑 CLIENT_SECRET (first few chars): {FATSECRET_CLIENT_SECRET[:5]}...")
|
||||
else:
|
||||
print("⚠️ CLIENT_SECRET is missing!")
|
||||
print(f"🔑 Authorization header: Basic {auth_header}")
|
||||
|
||||
# Выполняем запрос на получение токена
|
||||
token_url = "https://oauth.fatsecret.com/connect/token"
|
||||
headers = {
|
||||
"Authorization": f"Basic {auth_header}",
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
}
|
||||
data = {
|
||||
"grant_type": "client_credentials",
|
||||
"scope": "basic"
|
||||
}
|
||||
|
||||
print("📤 Sending request with headers:")
|
||||
for key, value in headers.items():
|
||||
print(f" {key}: {value if key != 'Authorization' else value[:30]}...")
|
||||
print("📤 Sending request with data:")
|
||||
for key, value in data.items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
try:
|
||||
response = requests.post(token_url, headers=headers, data=data)
|
||||
|
||||
# Дополнительная информация о запросе
|
||||
print(f"📥 Response status code: {response.status_code}")
|
||||
print(f"📥 Response headers: {dict(response.headers)}")
|
||||
|
||||
# Проверяем успешность запроса
|
||||
if response.status_code == 200:
|
||||
token_data = response.json()
|
||||
access_token = token_data.get("access_token")
|
||||
expires_in = token_data.get("expires_in")
|
||||
print(f"✅ Got token, expires in {expires_in} seconds")
|
||||
return access_token
|
||||
else:
|
||||
print(f"❌ Error getting token: {response.status_code}")
|
||||
print(f"❌ Error response: {response.text}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Exception getting token: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def search_food(token, query, max_results=5):
|
||||
"""Поиск продуктов по названию"""
|
||||
if not token:
|
||||
print("⚠️ No token available, cannot search")
|
||||
return None
|
||||
|
||||
print(f"🔍 Searching for '{query}'...")
|
||||
|
||||
api_url = "https://platform.fatsecret.com/rest/server.api"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
params = {
|
||||
"method": "foods.search",
|
||||
"search_expression": query,
|
||||
"max_results": max_results,
|
||||
"format": "json"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(api_url, headers=headers, json=params)
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"✅ Search successful")
|
||||
result = response.json()
|
||||
return result
|
||||
else:
|
||||
print(f"❌ Error searching: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Exception during search: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def get_food_details(token, food_id):
|
||||
"""Получение информации о продукте по ID"""
|
||||
if not token:
|
||||
print("⚠️ No token available, cannot get food details")
|
||||
return None
|
||||
|
||||
print(f"🔍 Getting details for food ID: {food_id}")
|
||||
|
||||
api_url = "https://platform.fatsecret.com/rest/server.api"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
|
||||
params = {
|
||||
"method": "food.get",
|
||||
"food_id": food_id,
|
||||
"format": "json"
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(api_url, headers=headers, json=params)
|
||||
|
||||
if response.status_code == 200:
|
||||
print(f"✅ Got food details")
|
||||
result = response.json()
|
||||
return result
|
||||
else:
|
||||
print(f"❌ Error getting food details: {response.status_code}")
|
||||
print(response.text)
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"❌ Exception getting food details: {e}")
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
"""Основная функция для тестирования API FatSecret"""
|
||||
print("\n🚀 Starting FatSecret API test...\n")
|
||||
|
||||
# Получаем токен доступа
|
||||
token = get_oauth_token()
|
||||
|
||||
if not token:
|
||||
print("❌ Failed to get OAuth token, exiting")
|
||||
return
|
||||
|
||||
# Тестируем поиск продуктов
|
||||
print("\n--- 📋 Testing Food Search ---")
|
||||
search_queries = ["apple", "bread", "chicken breast", "молоко"]
|
||||
first_food_id = None
|
||||
|
||||
for query in search_queries:
|
||||
result = search_food(token, query)
|
||||
|
||||
if result and "foods" in result:
|
||||
foods_data = result["foods"]
|
||||
|
||||
if "food" not in foods_data:
|
||||
print(f"⚠️ No results found for '{query}'")
|
||||
continue
|
||||
|
||||
food_list = foods_data["food"]
|
||||
if not isinstance(food_list, list):
|
||||
food_list = [food_list] # Если только один результат, оборачиваем в список
|
||||
|
||||
print(f"📊 Found {len(food_list)} results")
|
||||
|
||||
# Выводим первые 3 результата
|
||||
for i, food in enumerate(food_list[:3]):
|
||||
food_name = food.get("food_name", "Unknown")
|
||||
food_id = food.get("food_id", "Unknown")
|
||||
food_desc = food.get("food_description", "No description")
|
||||
|
||||
print(f" {i+1}. [{food_id}] {food_name}")
|
||||
print(f" {food_desc}")
|
||||
|
||||
# Сохраняем ID первого продукта для следующего теста
|
||||
if not first_food_id and food_list:
|
||||
first_food_id = food_list[0].get("food_id")
|
||||
|
||||
# Тестируем получение информации о продукте
|
||||
if first_food_id:
|
||||
print("\n--- 🍎 Testing Food Details ---")
|
||||
food_details = get_food_details(token, first_food_id)
|
||||
|
||||
if food_details and "food" in food_details:
|
||||
food = food_details["food"]
|
||||
food_name = food.get("food_name", "Unknown")
|
||||
brand = food.get("brand_name", "Generic")
|
||||
|
||||
print(f"📝 Details for: {food_name} [{brand}]")
|
||||
|
||||
# Выводим информацию о пищевой ценности
|
||||
if "servings" in food:
|
||||
servings = food["servings"]
|
||||
if "serving" in servings:
|
||||
serving_data = servings["serving"]
|
||||
if not isinstance(serving_data, list):
|
||||
serving_data = [serving_data]
|
||||
|
||||
print("\n📊 Nutrition info per serving:")
|
||||
for i, serving in enumerate(serving_data[:2]): # Выводим до 2 видов порций
|
||||
serving_desc = serving.get("serving_description", "Standard")
|
||||
calories = serving.get("calories", "N/A")
|
||||
protein = serving.get("protein", "N/A")
|
||||
carbs = serving.get("carbohydrate", "N/A")
|
||||
fat = serving.get("fat", "N/A")
|
||||
|
||||
print(f" Serving {i+1}: {serving_desc}")
|
||||
print(f" Calories: {calories}")
|
||||
print(f" Protein: {protein}g")
|
||||
print(f" Carbohydrates: {carbs}g")
|
||||
print(f" Fat: {fat}g")
|
||||
|
||||
print("\n✅ Test completed!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user