Files
chat/docs/FATSECRET_API.md
Andrew K. Choi 537e7b363f
All checks were successful
continuous-integration/drone/push Build is passing
main commit
2025-10-16 16:30:25 +09:00

228 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Работа с FatSecret API в проекте
Этот документ описывает, как используется API FatSecret для получения данных о продуктах питания и их пищевой ценности в нашем проекте.
## Настройка API
### Ключи API
Для работы с FatSecret API необходимы следующие ключи:
- `FATSECRET_CLIENT_ID` - ID клиента
- `FATSECRET_CLIENT_SECRET` - секрет клиента
- `FATSECRET_CUSTOMER_KEY` - ключ пользователя (используется как альтернатива CLIENT_ID)
Эти ключи хранятся в `.env` файле проекта и загружаются в конфигурацию через модуль `shared/config.py`.
### Методы аутентификации
FatSecret API поддерживает два метода аутентификации:
1. **OAuth 2.0** - требует прокси-сервер с белым списком IP для запроса токенов (не работает в нашем тестовом окружении)
2. **OAuth 1.0** - работает напрямую и подписывает каждый запрос (рекомендуется использовать)
## Примеры использования API
### Поиск продуктов питания
```python
def search_food(query, max_results=5):
"""Поиск продуктов по названию"""
# URL для API
url = "https://platform.fatsecret.com/rest/server.api"
# Параметры запроса
params = {
'method': 'foods.search',
'search_expression': query,
'max_results': max_results,
'format': 'json'
}
# Подписываем запрос с помощью OAuth 1.0
oauth_params = generate_oauth_params("GET", url, params)
# Отправляем запрос
response = requests.get(url, params=oauth_params)
if response.status_code == 200:
return response.json()
return None
```
### Получение информации о продукте
```python
def get_food_details(food_id):
"""Получение подробной информации о продукте по ID"""
# URL для API
url = "https://platform.fatsecret.com/rest/server.api"
# Параметры запроса
params = {
'method': 'food.get',
'food_id': food_id,
'format': 'json'
}
# Подписываем запрос с помощью OAuth 1.0
oauth_params = generate_oauth_params("GET", url, params)
# Отправляем запрос
response = requests.get(url, params=oauth_params)
if response.status_code == 200:
return response.json()
return None
```
## Генерация OAuth 1.0 подписи
```python
def generate_oauth_params(http_method, url, params):
"""Создание и подписание OAuth 1.0 параметров"""
# Текущее время в секундах
timestamp = str(int(time.time()))
# Случайная строка для nonce
nonce = ''.join([str(random.randint(0, 9)) for _ in range(8)])
# Базовый набор параметров OAuth
oauth_params = {
'oauth_consumer_key': FATSECRET_KEY,
'oauth_nonce': nonce,
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': timestamp,
'oauth_version': '1.0'
}
# Объединяем с параметрами запроса
all_params = {**params, **oauth_params}
# Сортируем параметры по ключу
sorted_params = sorted(all_params.items())
# Создаем строку параметров для подписи
param_string = "&".join([f"{urllib.parse.quote(str(k), safe='')}={urllib.parse.quote(str(v), safe='')}"
for k, v in sorted_params])
# Создаем строку для подписи
signature_base = f"{http_method}&{urllib.parse.quote(url, safe='')}&{urllib.parse.quote(param_string, safe='')}"
# Создаем ключ для подписи
signing_key = f"{urllib.parse.quote(str(FATSECRET_SECRET), safe='')}&"
# Создаем HMAC-SHA1 подпись
signature = base64.b64encode(
hmac.new(
signing_key.encode(),
signature_base.encode(),
hashlib.sha1
).digest()
).decode()
# Добавляем подпись к параметрам OAuth
all_params['oauth_signature'] = signature
return all_params
```
## Формат ответа API
### Поиск продуктов
Структура ответа от метода `foods.search`:
```json
{
"foods": {
"max_results": "5",
"total_results": "1000",
"page_number": "0",
"food": [
{
"food_id": "35718",
"food_name": "Apples",
"food_description": "Per 100g - Calories: 52kcal | Fat: 0.17g | Carbs: 13.81g | Protein: 0.26g",
"food_url": "https://www.fatsecret.com/calories-nutrition/usda/apples?portionid=34128"
},
// ...другие продукты
]
}
}
```
### Информация о продукте
Структура ответа от метода `food.get`:
```json
{
"food": {
"food_id": "35718",
"food_name": "Apples",
"food_type": "Generic",
"servings": {
"serving": [
{
"serving_id": "34128",
"serving_description": "100g",
"calories": "52",
"carbohydrate": "13.81",
"protein": "0.26",
"fat": "0.17",
// другие пищевые вещества
},
// другие варианты порций
]
}
}
}
```
## Ограничения API
1. Функциональность поиска на русском языке может быть недоступна в базовой версии API
2. Ограничение на количество запросов в месяц (зависит от уровня доступа)
3. OAuth 2.0 требует прокси-сервера, настроенного на определенные IP-адреса
## Тестирование API
Для тестирования API можно использовать готовый тестовый скрипт, который находится в корне проекта:
```bash
# Активировать виртуальное окружение
source venv/bin/activate
# Запустить тестовый скрипт
python test_fatsecret_api_oauth1.py
```
Вы также можете использовать этот скрипт как шаблон для написания собственных тестов. Примеры использования:
```python
# Импортировать функции из тестового скрипта
from test_fatsecret_api_oauth1 import search_food, process_search_results
# Поиск продуктов на английском
result = search_food("chicken breast")
process_search_results(result)
# Поиск продуктов на русском
result = search_food("яблоко", locale="ru_RU")
process_search_results(result)
```
### Примеры команд для тестирования через cURL
Для тестирования API через cURL можно использовать следующие команды:
```bash
# Поиск продуктов через nutrition service (требуется авторизация)
curl -X POST http://localhost:8006/api/v1/nutrition/search \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{"query": "apple", "max_results": 5}'
# Прямое тестирование FatSecret API (OAuth 1.0)
curl -X GET "https://platform.fatsecret.com/rest/server.api?method=foods.search&search_expression=apple&max_results=5&format=json&oauth_consumer_key=YOUR_CONSUMER_KEY&oauth_signature_method=HMAC-SHA1&oauth_timestamp=TIMESTAMP&oauth_nonce=NONCE&oauth_version=1.0&oauth_signature=YOUR_SIGNATURE"
```
> **Примечание:** Для выполнения прямого запроса к FatSecret API через cURL необходимо сгенерировать правильную OAuth 1.0 подпись. Рекомендуется использовать скрипт `test_fatsecret_api_oauth1.py` вместо этого.
## Рекомендации по использованию
1. Использовать OAuth 1.0 для аутентификации, так как он работает без дополнительной инфраструктуры
2. Кэшировать результаты запросов, чтобы снизить нагрузку на API
3. Обрабатывать возможные ошибки API и предоставлять пользователям понятные сообщения
4. Использовать английские запросы для поиска, так как база данных в основном на английском языке