인터넷에서 사용할 수 있는 다양한 옵션 중에서 이상적인 레시피를 찾는 것은 수많은 링크와 웹사이트로 인해 어려울 수 있습니다. 레시피 찾기 애플리케이션은 관련 없는 콘텐츠를 필터링하는 개인화되고 간소화된 인터페이스를 제공하여 관련 정보를 쉽게 찾을 수 있도록 도와줍니다.

이 소프트웨어를 만들면 HTTP 요구, API 키 관리, 이미지 변경, 실시간 업데이트와 같은 기능을 갖춘 대화형 사용자 인터페이스 구성에 대한 숙련도를 향상시킬 수 있습니다.

Tkinter, 요청, 필 및 웹브라우저 모듈 설치

레시피를 찾기 위한 애플리케이션을 구성하려면 Tkinter, 요청, PIL 및 웹브라우저 모듈을 사용해야 합니다. Tkinter를 활용하면 데스크톱 환경 내에서 그래픽 사용자 인터페이스를 만들 수 있습니다. 이 라이브러리는 사용자 인터페이스 설계 프로세스를 용이하게 하는 다양한 위젯을 제공합니다. Tkinter를 시스템에 도입하려면 터미널을 실행하고 명령을 실행하면 됩니다:

 pip install tkinter 

요청 모듈을 활용하면 인코딩 및 상태와 같은 필수 세부 정보를 포함하는 응답 객체를 생성하는 HTTP 요청 프로세스가 용이해집니다. 이 다용도 도구를 사용하면 발신자 ID 정보를 확보하고, 웹사이트 상태 모니터를 구성하고, 통화 변환을 수행하거나, 뉴스 애그리게이터를 개발할 수도 있습니다. 프로젝트에 요청 모듈을 통합하려면 터미널로 이동하여 명령을 실행하세요:

 pip install requests 

Python 이미징 라이브러리(PIL)에서 파생된 Pillow 라이브러리는 사용자가 통합 인터페이스를 통해 다양한 이미지 형식을 편집, 생성, 변환 및 저장할 수 있는 고급 이미지 조작 기능을 제공합니다. 프로젝트 내에서 이 기능을 통합하려면 다음 단계를 따르세요:

 pip install Pillow 

웹브라우저 모듈은 포괄적인 Python 표준 라이브러리의 일부로 선호하는 웹 브라우저 내에서 모든 URL을 쉽게 열 수 있으므로 외부 소스에서 추가 설치가 필요하지 않습니다.

레시피 검색을 위한 에담 레시피 API 키 생성

에담 레시피 검색 API 키를 획득하기 위해서는 다음 절차를 준수하시기 바랍니다:

에담맘 을 방문하여 API 가입 버튼을 클릭합니다. 세부 정보를 입력하고 플랜을 레시피 검색 API – 개발자로 선택합니다.

⭐ 계정에 로그인하고 계정 버튼을 클릭한 다음 대시보드로 이동 버튼을 클릭합니다.

⭐ 그 후 애플리케이션 탭을 클릭하고 마지막으로 레시피 검색 API 옆의 보기 버튼을 클릭합니다.

제공된 애플리케이션 ID와 해당 애플리케이션 키는 애플리케이션 내에 Google 지도 JavaScript API를 통합하는 데 필요하므로 나중에 참조할 수 있도록 저장해 두세요.

상위 5개 레시피를 가져오는 기능 구축하기

Python을 사용하여 레시피를 찾는 애플리케이션을 구축하는 데 필요한 전체 소스 코드는 이 GitHub 리포지토리에서 확인할 수 있습니다.

이 글도 확인해 보세요:  Python을 사용하여 할 일 목록 프로그램 만들기

필요한 모듈을 임포트하고 사용자가 입력한 검색어를 기반으로 상위 5개의 레시피 제목, 이미지, 링크를 검색하는 `get_top_5_recipes()`라는 메서드를 제공해 주세요. 이 함수는 `get()` 메서드를 사용하여 검색된 요리의 이름을 가져와야 합니다.

지정된 이름을 사용하여 Edamam API에서 레시피를 가져오려면 복사한 애플리케이션 ID와 키를 인증 자격 증명으로 통합하여 레시피 검색 엔드포인트의 기초 URL을 설정합니다.

 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

API 요청의 일부로 전달해야 하는 다양한 파라미터를 포괄하는 `params`로 표시되는 어휘집을 개발합니다. 그리고 `q`, `app_id`, `app_key`에 대한 키-값 쌍을 각각 획득한 값에 할당합니다. 또한 `from` 및 `to` 매개변수를 지정하여 원하는 검색 결과의 규모를 나타냅니다.

Edamam API를 사용하여 GET 요청을 실행하려면 먼저 API의 URL을 GET 메서드 내에서 쿼리 문자열 형태로 제공된 파라미터와 결합해야 합니다. 이렇게 결합된 URL은 파이썬에서 ‘url’ 변수의 인수로 사용됩니다. 그 후 서버로부터 받은 응답을 ‘response’라는 로컬 변수에 응답 객체를 할당하여 저장할 수 있습니다. 그런 다음 응답에서 얻은 데이터를 추출하여 목록이나 사전과 같이 사용 가능한 구조로 변환할 수 있으며, 특히 Python의 json 라이브러리를 사용하여 JSON 형식으로 변환할 수 있습니다. 마지막으로, 후속 요청을 하기 전에 ‘clear\_recipe\_list()’ 함수를 호출하여 인터페이스에 여전히 남아 있을 수 있는 이전에 가져온 레시피를 제거해야 합니다.

         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()

제공된 JSON 데이터에 지정된 키워드 ‘히트’가 포함되어 있고 원하는 검색 결과가 포함되어 있나요? 예, 이제 JSON 데이터에서 찾은 각 검색 결과를 처리하고 각각의 레시피 세부 정보를 검색하겠습니다. 이를 위해 요청된 이미지에 대한 실시간 업데이트를 받을 수 있도록 스트림 매개변수를 true로 설정한 HTTP GET 요청을 보내겠습니다.

Pillow 라이브러리의 ‘이미지’ 객체에서 제공하는 기능을 활용하여 가져온 이미지 데이터에 액세스합니다.고품질 결과를 생성하는 것으로 알려진 Lanczos 리샘플링 알고리즘을 사용하여 이미지의 크기를 높이와 너비가 200픽셀이 되도록 조정합니다. 결과 이미지를 `PhotoImage` 인스턴스로 변환하여 Tkinter에서 지원하는 GUI 환경에서 표시할 수 있는 형태로 변환합니다.

         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)

애플리케이션 구조 구축하기

이 글도 확인해 보세요:  내부에서 REST API 호출을 수행하는 방법 VS 코드

링크와 마우스 왼쪽 클릭 이벤트를 바인딩하여 open\_link() 함수를 호출하세요. pack() 메서드를 사용하여 모든 위젯을 가로 및 세로 중앙에 배치하고 필요한 패딩을 추가하여 정리합니다. 또한 코드에서 쉽게 액세스할 수 있도록 원하는 제목, 이미지 및 링크를 별도의 목록에 추가합니다.

                 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_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)
               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(
                   "<Button-1>", lambda event, link=recipe_link: open_link(link)
               )

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

주어진 작업에 대해 가능한 개선된 문구는 다음과 같을 수 있습니다: 초기 쿼리로 인해 이전에 인터페이스에 표시된 모든 시각적 요소를 효과적으로 제거할 수 있는 “clear\_recipe\_list()”라는 알고리즘 접근 방식을 고안하는 것이 목표입니다. 이 함수는 ‘레시피\_라벨’ 카탈로그 내의 모든 단일 항목을 반복하면서 레시피의 현재 인벤토리를 제거합니다.

기본 위젯 구조를 유지하면서 표시된 라벨을 분리하기 위해 “pack\_forget()” 함수를 활용하는 프로세스를…

새로운 정보를 도입하기 전에 레시피\_라벨 카탈로그에서 이전 데이터가 모두 삭제되었는지 확인합니다. 이미지 파일과 해당 하이퍼링크에 대해서도 유사한 작업을 수행합니다. open\_link()를 호출하면 원하는 인터넷 브라우저에서 관련 레시피 웹페이지를 자동으로 실행하는 방법을 개발합니다.

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

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

Tkinter 루트 창을 설정하고 제목, 크기, 배경 색조를 지정하여 애플리케이션의 그래픽 사용자 인터페이스를 시작합니다. 애플리케이션 내에 프레임 컨테이너를 구성하여 다른 요소와의 관계를 정의하고 고유한 배경 음영을 할당합니다. Tkinter에서 제공하는 생성 메서드를 사용하여 레이블, 항목 및 버튼과 같은 개별 위젯을 생성합니다. pack() 메서드를 사용하여 이러한 시각적 구성 요소를 효율적으로 배열하고, 필요한 경우 배치를 조정하고, 구성 요소 사이에 적절한 공간을 통합합니다.

 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)

미식 데이터를 보관하는 리셉터클 요소의 전시장으로 빛나는 배경으로 자연 그대로의 광활한 대지를 장식합니다. 이 시각적 구성을 뷰포트의 왼쪽 주변부에 배치하여 크기를 유지하면서 리스케일링 시 전체 너비와 폭을 차지하도록 합니다.

캔버스 위젯의 오른쪽에 수직 스크롤바가 포함되도록 코드를 수정하여 캔버스 객체의 yView 메서드에 연결합니다. 이렇게 하면 사용자가 스크롤 막대와 상호 작용하여 그래픽 디스플레이의 콘텐츠를 스크롤할 수 있습니다.

이 글도 확인해 보세요:  녹 매크로: 매크로를 사용하여 코드를 개선하는 방법

캔버스 내에 프레임워크를 설정하여 화면의 왼쪽 상단 모서리에 배치하여 재료의 인클로저 역할을 합니다. 상자의 콘텐츠가 변경되거나 크기가 조정될 때마다 상자가 적절한 스크롤 기능을 표시할 수 있도록 <구성> 이벤트를 트리거합니다.

 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(
   "<Configure>", lambda event: canvas.configure(scrollregion=canvas.bbox("all"))
)

Python에서 Tkinter를 사용하여 GUI 애플리케이션을 만들려면 레시피, 레이블, 이미지 및 하이퍼링크 목록을 정의해야 합니다. 이는 파이썬이 Tkinter 이벤트 루프를 실행하고 창이 닫힐 때까지 사용자 상호 작용을 지속적으로 모니터링하도록 지시하는 `mainloop()` 함수를 활용하여 달성할 수 있습니다.

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

root.mainloop()

클릭 한 번으로 전 세계의 요리를 편리하게 한곳에 모아두었으니 전 세계의 요리를 발견해보세요.

레시피 찾기 애플리케이션의 출력

애플리케이션을 실행하고 입력 필드에 “치킨 버거”를 입력하면 제목, 첨부 이미지, 해당 레시피 페이지로 연결되는 하이퍼링크가 포함된 상위 5개 검색 결과 목록이 사용자에게 표시됩니다. 이 링크를 클릭하면 기본 인터넷 브라우저가 열리고 지정된 요리에 대한 전체 레시피가 포함된 원하는 웹 페이지가 표시됩니다. 페이지를 스크롤할 때 표시되는 콘텐츠는 원래 크기로 고정된 상태로 유지되며 검색 결과가 중앙에 정렬된 방식으로 표시됩니다.

레시피 찾기 애플리케이션 개선

레시피 검색 도구의 기능을 개선하기 위해 다양한 사용자 기준에 따라 검색 결과를 구성할 수 있는 옵션을 추가했습니다. 사용자는 식단 제한, 준비 시간 및 요리 스타일과 같은 다양한 필터 중에서 선택하고 원하는 순서대로 결과를 정렬할 수 있습니다.

사용자가 선호하는 레시피를 저장하여 나중에 열람할 수 있는 ‘즐겨찾기’ 기능과 다양한 소셜 플랫폼에서 이러한 선택 사항을 전파할 수 있는 공유 기능을 통합하는 것이 우아한 해결책이 될 수 있습니다. 또한 ‘인기 검색’ 또는 ‘가장 많이 북마크한’ 카테고리를 구현하면 요리 커뮤니티 내에서 사용자 선호도와 트렌드에 대한 귀중한 인사이트를 얻을 수 있습니다.

프로그래밍에 대한 숙련도를 활용하고 API의 강력한 기능을 활용하면 이 초보적인 애플리케이션을 포괄적이고 완전한 기능을 갖춘 애플리케이션으로 전환할 수 있는 잠재력이 있습니다.

By 김민수

안드로이드, 서버 개발을 시작으로 여러 분야를 넘나들고 있는 풀스택(Full-stack) 개발자입니다. 오픈소스 기술과 혁신에 큰 관심을 가지고 있고, 보다 많은 사람이 기술을 통해 꿈꾸던 일을 실현하도록 돕기를 희망하고 있습니다.