Spaces:
Build error
Build error
| 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( | |
| """ | |
| <div class="title-text">🎨 The Met Art Explorer</div> | |
| <div class="subtitle-text">Explore over 5,000 years of art from The Metropolitan Museum of Art's collection</div> | |
| """ | |
| ) | |
| gr.HTML("""<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fimmunobiotech-MetropolitanMuseum.hf.space"> | |
| <img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fimmunobiotech-MetropolitanMuseum.hf.space&countColor=%23263759" /> | |
| </a>""") | |
| with gr.Row(): | |
| with gr.Column(scale=3): | |
| search_input = gr.Textbox( | |
| label="Search artwork", | |
| placeholder="Enter keywords (e.g., sunflowers, portrait, landscape...)" | |
| ) | |
| with gr.Column(scale=2): | |
| department_dropdown = gr.Dropdown( | |
| choices=list(department_choices.keys()), | |
| label="Department", | |
| value=None | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| highlight_checkbox = gr.Checkbox(label="Show Highlights Only", value=False) | |
| on_view_checkbox = gr.Checkbox(label="Currently On View", value=False) | |
| with gr.Column(): | |
| medium_input = gr.Textbox( | |
| label="Medium", | |
| placeholder="e.g., Paintings, Sculpture, Ceramics" | |
| ) | |
| location_input = gr.Textbox( | |
| label="Geographic Location", | |
| placeholder="e.g., France, Japan, Egypt" | |
| ) | |
| search_btn = gr.Button("🔍 Search Collection", variant="primary") | |
| gallery = gr.Gallery( | |
| label="Search Results", | |
| show_label=True, | |
| elem_id="gallery", | |
| columns=3, | |
| rows=4, | |
| height="800px", | |
| object_fit="contain" | |
| ) | |
| info = gr.Textbox( | |
| label="Artwork Details", | |
| lines=10, | |
| show_label=True | |
| ) | |
| def handle_search(query, dept, highlight, on_view, medium, location): | |
| dept_id = department_choices.get(dept) if dept else None | |
| return search_artworks(query, dept_id, highlight, True, on_view, medium, location) | |
| search_btn.click( | |
| fn=handle_search, | |
| inputs=[search_input, department_dropdown, highlight_checkbox, | |
| on_view_checkbox, medium_input, location_input], | |
| outputs=[gallery, info] | |
| ) | |
| demo.launch() |