Гид по технологиям

Поиск рецептов на Python с Tkinter и Edamam API

6 min read Разработка Обновлено 31 Dec 2025
Поиск рецептов на Python с Tkinter и Edamam
Поиск рецептов на Python с Tkinter и Edamam

Женщина готовит блюдо

В эпоху множества разрозненных рецептов и рекламы удобно иметь собственное приложение, которое возвращает только релевантные результаты. Создание приложения-поисковика рецептов даёт единый, понятный интерфейс, помогает отточить навыки работы с HTTP, хранением API-ключей, обработкой изображений и динамическим GUI.

Что вы получите

  • Рабочее настольное приложение на Python с вводом названия блюда и выводом топ‑5 рецептов.
  • Отображение заголовка, изображения и ссылки на рецепт.
  • Примеры улучшений: фильтры, закладки, сортировка, локализация.

Основные понятия (в одну строку)

  • Tkinter — стандартная библиотека Python для создания GUI.
  • Requests — библиотека для HTTP-запросов.
  • Pillow (PIL) — библиотека для обработки изображений.
  • Edamam Recipe Search API — сторонний API для поиска рецептов.

Установка зависимостей

Для работы потребуется Python (рекомендуем 3.8+). Установите модули через pip (на некоторых системах Tkinter уже встроен):

pip install tkinter
pip install requests
pip install Pillow

Модуль webbrowser включён в стандартную библиотеку Python, его подключать отдельно не нужно.

Важно: храните API‑ключи в безопасном месте (см. раздел «Хранение ключей»).

Получение ключа Edamam API

  1. Перейдите на сайт Edamam (https://www.edamam.com).
  2. Зарегистрируйтесь и выберите план «Recipe Search API - Developer».
  3. Войдите в аккаунт и откройте панель управления (Dashboard).

Страница Edamam API

  1. Перейдите во вкладку «Applications» и выберите View рядом с Recipe Search API.

Кнопка панели управления Edamam

  1. Скопируйте Application ID и Application Key — они понадобятся в приложении.

Вкладка приложений Edamam

Совет: никогда не добавляйте ключи в публичные репозитории. Используйте .env или переменные окружения.

Структура приложения и ключевые функции

Ниже — упрощённый план исполнения функции get_top_5_recipes(), которая получает топ‑5 рецептов по запросу пользователя, скачивает и ресайзит изображения, и отображает результат в Tkinter.

Ключевые шаги:

  • Получить текст запроса из поля ввода.
  • Сформировать параметры для Edamam API (q, app_id, app_key, from, to).
  • Выполнить GET-запрос и распарсить JSON.
  • Для каждого рецепта скачать изображение, открыть через Pillow, изменить размер и показать в GUI.

Пример кода (фрагмент):

import tkinter as tk
import requests
from PIL import Image, ImageTk
import webbrowser

def get_top_5_recipes():
    recipe_name = entry_recipe_name.get()
    if recipe_name:
        api_url = "https://api.edamam.com/search"
        app_id = # Put your app id for edamam api
        app_key = # Put your app key for edamam api

        params = {
            "q": recipe_name,
            "app_id": app_id,
            "app_key": app_key,
            "from": 0,
            "to": 5,
        }

        response = requests.get(api_url, params=params)
        data = response.json()
        clear_recipe_list()

        if "hits" in data and data["hits"]:
            for i, hit in enumerate(data["hits"]):
                recipe = hit["recipe"]
                recipe_list.append(recipe)
                recipe_name = recipe["label"]
                recipe_link = recipe["url"]
                image_url = recipe["image"]

                image_response = requests.get(image_url, stream=True)
                image = Image.open(image_response.raw)
                image = image.resize((200, 200), Image.LANCZOS)
                photo_image = ImageTk.PhotoImage(image)

                recipe_title_label = tk.Label(
                    canvas_frame,
                    text=f"{i+1}. {recipe_name}",
                    font=("Helvetica", 12, "bold"),
                )
                recipe_title_label.pack(pady=(5, 0), anchor=tk.CENTER)

                image_label = tk.Label(canvas_frame, image=photo_image)
                image_label.image = photo_image
                image_label.pack(pady=(0, 5), anchor=tk.CENTER)

                link_label = tk.Label(canvas_frame, text=recipe_link, fg="blue", cursor="hand2")
                link_label.pack(pady=(0, 10), anchor=tk.CENTER)
                link_label.bind("", lambda event, link=recipe_link: open_link(link))

                recipe_labels.append(recipe_title_label)
                recipe_images.append(photo_image)
                recipe_links.append(link_label)

def clear_recipe_list():
    recipe_list.clear()
    for label in recipe_labels:
        label.pack_forget()
    recipe_labels.clear()
    for image_label in recipe_images:
        try:
            image_label.pack_forget()
        except Exception:
            pass
    recipe_images.clear()
    for link_label in recipe_links:
        link_label.pack_forget()
    recipe_links.clear()

def open_link(link):
    webbrowser.open(link)

Полная сборка интерфейса (основные фрагменты)

Инициализация окна, frame, поля ввода, кнопки поиска и область прокрутки:

root = tk.Tk()
root.title("Recipe Finder")
root.geometry("600x600")
root.configure(bg="#F1F1F1")

frame = tk.Frame(root, bg="#F1F1F1")
frame.pack(fill=tk.BOTH, expand=tk.YES, padx=20, pady=20)

label_recipe_name = tk.Label(
   frame, text="Enter Recipe Name:", font=("Helvetica", 14, "bold"), bg="#F1F1F1"
)
label_recipe_name.pack()

entry_recipe_name = tk.Entry(frame, font=("Helvetica", 12))
entry_recipe_name.pack(pady=5)

search_button = tk.Button(
   frame,
   text="Search Recipes",
   font=("Helvetica", 12, "bold"),
   command=get_top_5_recipes,
)
search_button.pack(pady=10)

canvas = tk.Canvas(frame, bg="white")
canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES)

scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL, command=canvas.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
canvas.configure(yscrollcommand=scrollbar.set)

canvas_frame = tk.Frame(canvas, bg="white")
canvas.create_window((0, 0), window=canvas_frame, anchor=tk.NW)
canvas_frame.bind("", lambda event: canvas.configure(scrollregion=canvas.bbox("all")))

recipe_list = []
recipe_labels = []
recipe_images = []
recipe_links = []

root.mainloop()

Демонстрация вывода

При вводе «Chicken Burger» приложение покажет пять результатов — заголовок, изображение и ссылку; клик по ссылке откроет браузер по умолчанию, а полоса прокрутки позволит увидеть все элементы.

Результат поиска Chicken Burger

Улучшения и расширения (планы и идеи)

  • Фильтры: диета (веган, без глютена), время приготовления, калории.
  • Сортировка: по популярности, времени, рейтингу (если есть поле).
  • Закладки: локальная база (SQLite) для сохранения любимых рецептов.
  • Поделиться: интеграция с социальными сетями или копирование ссылки.
  • Кэширование изображений и результатов для снижения числа запросов.

Хранение ключей и безопасность

Лучше не хранить app_id/app_key прямо в коде. Используйте:

  • Файл .env, который не добавляется в Git (.gitignore).
  • Переменные окружения на прод-сервере.
  • Менеджеры секретов (для более серьёзных развёртываний).

Пример чтения ключей из .env:

from dotenv import load_dotenv
import os

load_dotenv()
app_id = os.getenv('EDAMAM_APP_ID')
app_key = os.getenv('EDAMAM_APP_KEY')

Обработка ошибок и устойчивость

  • Проверяйте статус ответа: response.status_code.
  • Обрабатывайте исключения requests.exceptions.RequestException.
  • На случай ошибок сети показывайте пользователю уведомление и предлагайте «Попробовать снова».

Пример базовой обработки:

try:
    response = requests.get(api_url, params=params, timeout=10)
    response.raise_for_status()
    data = response.json()
except requests.exceptions.RequestException as e:
    # Показать диалог об ошибке в GUI
    print("Ошибка запроса:", e)
    return

Локализация и единицы измерения для русскоязычных пользователей

  • Переводите заголовки интерфейса и кнопки: «Enter Recipe Name» → «Введите название рецепта», «Search Recipes» → «Найти рецепты».
  • Приводите единицы времени (мин, ч) и веса (г, кг) к локальному формату, если вы будете показывать шаги рецепта.
  • Будьте осторожны с названиями ингредиентов: в разных регионах одно и то же блюдо может называться по-разному.

Альтернативные подходы к источникам рецептов

  • Другие API: Spoonacular, TheMealDB, Tasty API (при наличии доступа).
  • Скрапинг сайтов рецептов — быстро, но требует соблюдения правил сайта и может нарушать ToS.
  • Локальная база рецептов — хороша для оффлайн-режима и полной кастомизации.

Когда альтернативы не подходят: если нужен лицензированный контент или официальные данные о пищевой ценности — используйте официальные API.

Мини‑методология разработки (быстрый SOP)

  1. Подготовка: получить API ключ, настроить виртуальное окружение, .gitignore.
  2. MVP: рабочий поиск, отображение топ‑5, открытие ссылок.
  3. Тесты: базовые тесты GUI и интеграционные тесты запросов (mock ответа).
  4. Улучшения: фильтры, кеш, локализация, закладки.
  5. Релиз: упаковка как exe (pyinstaller) или снапшот для платформы.

Критерии приёмки

  • Приложение запускается без ошибок на чистой машине с Python 3.8+.
  • При вводе названия блюда отображаются максимум 5 карточек с заголовком, изображением и рабочей ссылкой.
  • Ссылки открываются в браузере по умолчанию.
  • Если сеть отсутствует — показывается понятная ошибка.

Ручной тест: примеры тест-кейсов

  1. Ввод пустой строки → ничего не ищем, уведомление «Введите название».
  2. Корректный запрос «pasta» → получено 1–5 рецептов, изображения загружены.
  3. Неверный app_key → обработка ошибки и сообщение пользователю.
  4. Большой ответ API → GUI остаётся отзывчивым (при необходимости вынесите работу в фоновый поток).

Role-based чек-листы

Разработчик:

  • Настроить .env и .gitignore.
  • Обработать исключения сети.
  • Написать модульные тесты для парсинга ответа.

QA-инженер:

  • Проверить UI на масштабирование и прокрутку.
  • Проверить открытие ссылок на разных ОС.
  • Смоделировать ошибки API и проверить поведение.

Дизайнер:

  • Подобрать читаемые шрифты и отступы.
  • Предложить варианты карточек рецептов (размеры изображений).

Производительность и масштабирование (советы)

  • Кешируйте последние поисковые запросы и скачанные изображения в локальную папку.
  • Для многопоточности скачивания изображений используйте ThreadPoolExecutor.
  • Для веб-версии — вынесите логику обращений к API на серверную часть и кеширование.

Технический чек-лист безопасности и приватности

  • Не храните ключи в публичных репозиториях.
  • Не логируйте чувствительные данные.
  • Для сбора персональных данных (например, закладки пользователя) предупредите о хранении данных и предоставьте способ удаления.

Модель принятия решений: когда использовать Edamam

  • Если нужен быстрый старт с готовыми данными рецептов и изображениями — Edamam подходит.
  • Если нужен полный контроль над контентом или оффлайн-доступ — лучше локальная база.
flowchart TD
  A[Начало] --> B{Есть API ключ Edamam?}
  B -- Да --> C[Использовать Edamam]
  B -- Нет --> D{Можно оплатить API?}
  D -- Да --> E[Зарегистрироваться и получить ключ]
  D -- Нет --> F[Рассмотреть локальную БД или другой API]
  C --> G[Реализовать поиск и UI]
  F --> G

Примеры кода и сниппеты (cheat sheet)

  • Запрос с проверкой статуса:
resp = requests.get(api_url, params=params, timeout=10)
if resp.status_code != 200:
    print('Ошибка API', resp.status_code)
else:
    data = resp.json()
  • Скачивание и сохранение изображения в кэш:
from pathlib import Path

cache_dir = Path('cache')
cache_dir.mkdir(exist_ok=True)

img_path = cache_dir / 'recipe_123.jpg'
with requests.get(image_url, stream=True) as r:
    r.raise_for_status()
    with open(img_path, 'wb') as f:
        for chunk in r.iter_content(1024):
            f.write(chunk)

Что делать, если что‑то идёт не так (runbook)

  1. Приложение не стартует — проверить версию Python и установленные зависимости.
  2. Нет ответов от API — проверить статус API и корректность app_id/app_key.
  3. Изображения не загружаются — проверить URL, обработать исключения Pillow.
  4. Программа подтормаживает — профиль производительности, перенос загрузки в отдельный поток.

Заключение

Это руководство даёт полный набор шагов от установки зависимостей до идей по расширению приложения «поиск рецептов». Начните с MVP, затем добавляйте фильтры, кеш, локализацию и хранение избранного. Приложение легко портируется в исполняемый файл или в веб‑версию при необходимости.

Важное: не публикуйте свои ключи в открытом доступе и тестируйте обработку ошибок сети.

Краткое резюме и шаги для старта: 1) получить ключ Edamam; 2) собрать минимальный интерфейс; 3) реализовать get_top_5_recipes(); 4) добавить обработку ошибок и кеширование.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство