import gradio as gr import requests import json from PIL import Image import io # API 기본 URL BASE_URL = "https://collectionapi.metmuseum.org/public/collection/v1" def get_departments(): """Get all departments from the Met API""" response = requests.get(f"{BASE_URL}/departments") return response.json()['departments'] def search_artworks(query, department_id=None, is_highlight=False, has_images=True, is_on_view=False, medium=None, geo_location=None): """Search artworks with various filters""" search_url = f"{BASE_URL}/search" params = { 'q': query, 'hasImages': has_images, 'isHighlight': is_highlight, 'isOnView': is_on_view } if department_id: params['departmentId'] = department_id if medium: params['medium'] = medium if geo_location: params['geoLocation'] = geo_location try: # Get object IDs from search response = requests.get(search_url, params=params) results = response.json() if not results.get('objectIDs'): return [], "No results found." # Limit to first 12 objects for performance object_ids = results['objectIDs'][:12] images = [] captions = [] # Get details for each object for object_id in object_ids: object_url = f"{BASE_URL}/objects/{object_id}" object_response = requests.get(object_url) artwork = object_response.json() if artwork.get('primaryImage'): try: img_response = requests.get(artwork['primaryImage'], timeout=10) img = Image.open(io.BytesIO(img_response.content)) if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info): img = img.convert('RGB') artwork_info = f""" Title: {artwork.get('title', 'Unknown')} Artist: {artwork.get('artistDisplayName', 'Unknown')} Date: {artwork.get('objectDate', 'Unknown')} Medium: {artwork.get('medium', 'Unknown')} Department: {artwork.get('department', 'Unknown')} """ images.append(img) captions.append(artwork_info) except Exception as e: print(f"Error processing image for object {object_id}: {e}") continue return images, "\n\n".join(captions) except Exception as e: return [], f"An error occurred: {str(e)}" # Custom CSS custom_css = """ .gradio-container { background: linear-gradient(135deg, #1a1a1a, #2d2d2d) !important; color: #ffffff !important; } .gr-button { background: linear-gradient(135deg, #8e2de2, #4a00e0) !important; border: none !important; color: white !important; font-weight: bold !important; padding: 10px 20px !important; font-size: 1.1em !important; box-shadow: 0 4px 15px rgba(0,0,0,0.2) !important; } .gr-button:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.3) !important; transition: all 0.3s ease; } .gr-input, .gr-select { border: 2px solid #4a00e0 !important; background: rgba(255, 255, 255, 0.1) !important; color: white !important; font-size: 1.1em !important; border-radius: 8px !important; } .gr-gallery { background: rgba(0, 0, 0, 0.3) !important; border-radius: 15px !important; padding: 20px !important; min-height: 800px !important; box-shadow: 0 8px 32px rgba(0,0,0,0.3) !important; } .title-text { text-align: center !important; color: #ffffff !important; font-size: 2.8em !important; margin-bottom: 0.3em !important; text-shadow: 2px 2px 4px rgba(0,0,0,0.5) !important; font-weight: bold !important; } .subtitle-text { text-align: center !important; color: #cccccc !important; font-size: 1.3em !important; margin-bottom: 2em !important; font-style: italic !important; text-shadow: 1px 1px 2px rgba(0,0,0,0.3) !important; } """ # Get departments for dropdown departments = get_departments() department_choices = {dept['displayName']: dept['departmentId'] for dept in departments} # Gradio interface with gr.Blocks(css=custom_css) as demo: gr.HTML( """