immunobiotech commited on
Commit
2ea7db4
·
verified ·
1 Parent(s): 5ca9391

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +180 -75
app.py CHANGED
@@ -5,92 +5,197 @@ from PIL import Image
5
  import io
6
 
7
  # API 기본 URL
8
- BASE_URL = "https://api.artic.edu/api/v1"
9
 
10
- def search_artworks(query, is_public_domain=False):
11
- # 아트워크 검색 API 호출
12
- search_url = f"{BASE_URL}/artworks/search"
 
 
 
 
 
 
13
  params = {
14
- "q": query,
15
- "limit": 10,
16
- "fields": "id,title,artist_display,date_display,image_id,is_public_domain",
 
17
  }
18
 
19
- if is_public_domain:
20
- params["query"] = {"term": {"is_public_domain": True}}
 
 
 
 
21
 
22
- response = requests.get(search_url, params=params)
23
- results = response.json()
24
-
25
- if "data" not in results:
26
- return "검색 결과가 없습니다."
27
 
28
- output = []
29
- for artwork in results["data"]:
30
- if artwork.get("image_id"):
31
- # IIIF 이미지 URL 생성
32
- image_url = f"https://www.artic.edu/iiif/2/{artwork['image_id']}/full/843,/0/default.jpg"
33
 
34
- # 작품 정보 포맷팅
35
- artwork_info = f"""
36
- 제목: {artwork.get('title', 'Unknown')}
37
- 작가: {artwork.get('artist_display', 'Unknown')}
38
- 제작연도: {artwork.get('date_display', 'Unknown')}
39
- """
 
 
 
 
 
40
 
41
- # 이미지 다운로드 및 PIL Image로 변환
42
- try:
43
- img_response = requests.get(image_url)
44
- img = Image.open(io.BytesIO(img_response.content))
45
- output.append((img, artwork_info))
46
- except:
47
- continue
48
-
49
- return output if output else "검색 결과가 없습니다."
50
-
51
- def get_gallery_info(gallery_id):
52
- # 갤러리 정보 API 호출
53
- gallery_url = f"{BASE_URL}/galleries/{gallery_id}"
54
- response = requests.get(gallery_url)
55
- gallery = response.json()
56
-
57
- if "data" not in gallery:
58
- return "갤러리 정보를 찾을 수 없습니다."
 
 
 
59
 
60
- gallery_data = gallery["data"]
61
- return f"""
62
- 갤러리 이름: {gallery_data.get('title', 'Unknown')}
63
- 위치: {gallery_data.get('location', 'Unknown')}
64
- 설명: {gallery_data.get('description', 'No description available')}
65
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
- # Gradio 인터페이스 구성
68
- with gr.Blocks() as demo:
69
- gr.Markdown("# Art Institute of Chicago Gallery")
 
 
 
 
 
 
 
 
 
70
 
71
- with gr.Tab("작품 검색"):
72
- with gr.Row():
73
- search_input = gr.Textbox(label="검색어를 입력하세요")
74
- public_domain = gr.Checkbox(label="공개 도메인 작품만 보기")
75
- search_btn = gr.Button("검색")
76
- gallery = gr.Gallery(label="검색 결과")
77
- info = gr.Textbox(label="작품 정보", lines=3)
78
-
79
- search_btn.click(
80
- fn=search_artworks,
81
- inputs=[search_input, public_domain],
82
- outputs=[gallery, info]
83
- )
84
 
85
- with gr.Tab("갤러리 정보"):
86
- gallery_id = gr.Number(label="갤러리 ID를 입력하세요")
87
- gallery_btn = gr.Button("정보 조회")
88
- gallery_info = gr.Textbox(label="갤러리 정보", lines=5)
89
-
90
- gallery_btn.click(
91
- fn=get_gallery_info,
92
- inputs=gallery_id,
93
- outputs=gallery_info
94
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
  demo.launch()
 
5
  import io
6
 
7
  # API 기본 URL
8
+ BASE_URL = "https://collectionapi.metmuseum.org/public/collection/v1"
9
 
10
+ def get_departments():
11
+ """Get all departments from the Met API"""
12
+ response = requests.get(f"{BASE_URL}/departments")
13
+ return response.json()['departments']
14
+
15
+ def search_artworks(query, department_id=None, is_highlight=False, has_images=True,
16
+ is_on_view=False, medium=None, geo_location=None):
17
+ """Search artworks with various filters"""
18
+ search_url = f"{BASE_URL}/search"
19
  params = {
20
+ 'q': query,
21
+ 'hasImages': has_images,
22
+ 'isHighlight': is_highlight,
23
+ 'isOnView': is_on_view
24
  }
25
 
26
+ if department_id:
27
+ params['departmentId'] = department_id
28
+ if medium:
29
+ params['medium'] = medium
30
+ if geo_location:
31
+ params['geoLocation'] = geo_location
32
 
33
+ try:
34
+ # Get object IDs from search
35
+ response = requests.get(search_url, params=params)
36
+ results = response.json()
 
37
 
38
+ if not results.get('objectIDs'):
39
+ return [], "No results found."
 
 
 
40
 
41
+ # Limit to first 12 objects for performance
42
+ object_ids = results['objectIDs'][:12]
43
+
44
+ images = []
45
+ captions = []
46
+
47
+ # Get details for each object
48
+ for object_id in object_ids:
49
+ object_url = f"{BASE_URL}/objects/{object_id}"
50
+ object_response = requests.get(object_url)
51
+ artwork = object_response.json()
52
 
53
+ if artwork.get('primaryImage'):
54
+ try:
55
+ img_response = requests.get(artwork['primaryImage'], timeout=10)
56
+ img = Image.open(io.BytesIO(img_response.content))
57
+
58
+ if img.mode in ('RGBA', 'LA') or (img.mode == 'P' and 'transparency' in img.info):
59
+ img = img.convert('RGB')
60
+
61
+ artwork_info = f"""
62
+ Title: {artwork.get('title', 'Unknown')}
63
+ Artist: {artwork.get('artistDisplayName', 'Unknown')}
64
+ Date: {artwork.get('objectDate', 'Unknown')}
65
+ Medium: {artwork.get('medium', 'Unknown')}
66
+ Department: {artwork.get('department', 'Unknown')}
67
+ """
68
+
69
+ images.append(img)
70
+ captions.append(artwork_info)
71
+ except Exception as e:
72
+ print(f"Error processing image for object {object_id}: {e}")
73
+ continue
74
 
75
+ return images, "\n\n".join(captions)
76
+
77
+ except Exception as e:
78
+ return [], f"An error occurred: {str(e)}"
79
+
80
+ # Custom CSS
81
+ custom_css = """
82
+ .gradio-container {
83
+ background: linear-gradient(135deg, #1a1a1a, #2d2d2d) !important;
84
+ color: #ffffff !important;
85
+ }
86
+ .gr-button {
87
+ background: linear-gradient(135deg, #8e2de2, #4a00e0) !important;
88
+ border: none !important;
89
+ color: white !important;
90
+ font-weight: bold !important;
91
+ padding: 10px 20px !important;
92
+ font-size: 1.1em !important;
93
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2) !important;
94
+ }
95
+ .gr-button:hover {
96
+ transform: translateY(-2px);
97
+ box-shadow: 0 6px 20px rgba(0,0,0,0.3) !important;
98
+ transition: all 0.3s ease;
99
+ }
100
+ .gr-input, .gr-select {
101
+ border: 2px solid #4a00e0 !important;
102
+ background: rgba(255, 255, 255, 0.1) !important;
103
+ color: white !important;
104
+ font-size: 1.1em !important;
105
+ border-radius: 8px !important;
106
+ }
107
+ .gr-gallery {
108
+ background: rgba(0, 0, 0, 0.3) !important;
109
+ border-radius: 15px !important;
110
+ padding: 20px !important;
111
+ min-height: 800px !important;
112
+ box-shadow: 0 8px 32px rgba(0,0,0,0.3) !important;
113
+ }
114
+ .title-text {
115
+ text-align: center !important;
116
+ color: #ffffff !important;
117
+ font-size: 2.8em !important;
118
+ margin-bottom: 0.3em !important;
119
+ text-shadow: 2px 2px 4px rgba(0,0,0,0.5) !important;
120
+ font-weight: bold !important;
121
+ }
122
+ .subtitle-text {
123
+ text-align: center !important;
124
+ color: #cccccc !important;
125
+ font-size: 1.3em !important;
126
+ margin-bottom: 2em !important;
127
+ font-style: italic !important;
128
+ text-shadow: 1px 1px 2px rgba(0,0,0,0.3) !important;
129
+ }
130
+ """
131
 
132
+ # Get departments for dropdown
133
+ departments = get_departments()
134
+ department_choices = {dept['displayName']: dept['departmentId'] for dept in departments}
135
+
136
+ # Gradio interface
137
+ with gr.Blocks(css=custom_css) as demo:
138
+ gr.HTML(
139
+ """
140
+ <div class="title-text">🎨 The Met Art Explorer</div>
141
+ <div class="subtitle-text">Explore over 5,000 years of art from The Metropolitan Museum of Art's collection</div>
142
+ """
143
+ )
144
 
145
+ with gr.Row():
146
+ with gr.Column(scale=3):
147
+ search_input = gr.Textbox(
148
+ label="Search artwork",
149
+ placeholder="Enter keywords (e.g., sunflowers, portrait, landscape...)"
150
+ )
151
+ with gr.Column(scale=2):
152
+ department_dropdown = gr.Dropdown(
153
+ choices=list(department_choices.keys()),
154
+ label="Department",
155
+ value=None
156
+ )
 
157
 
158
+ with gr.Row():
159
+ with gr.Column():
160
+ highlight_checkbox = gr.Checkbox(label="Show Highlights Only", value=False)
161
+ on_view_checkbox = gr.Checkbox(label="Currently On View", value=False)
162
+ with gr.Column():
163
+ medium_input = gr.Textbox(
164
+ label="Medium",
165
+ placeholder="e.g., Paintings, Sculpture, Ceramics"
166
+ )
167
+ location_input = gr.Textbox(
168
+ label="Geographic Location",
169
+ placeholder="e.g., France, Japan, Egypt"
170
+ )
171
+
172
+ search_btn = gr.Button("🔍 Search Collection", variant="primary")
173
+
174
+ gallery = gr.Gallery(
175
+ label="Search Results",
176
+ show_label=True,
177
+ elem_id="gallery",
178
+ columns=3,
179
+ rows=4,
180
+ height="800px",
181
+ object_fit="contain"
182
+ )
183
+
184
+ info = gr.Textbox(
185
+ label="Artwork Details",
186
+ lines=10,
187
+ show_label=True
188
+ )
189
+
190
+ def handle_search(query, dept, highlight, on_view, medium, location):
191
+ dept_id = department_choices.get(dept) if dept else None
192
+ return search_artworks(query, dept_id, highlight, True, on_view, medium, location)
193
+
194
+ search_btn.click(
195
+ fn=handle_search,
196
+ inputs=[search_input, department_dropdown, highlight_checkbox,
197
+ on_view_checkbox, medium_input, location_input],
198
+ outputs=[gallery, info]
199
+ )
200
 
201
  demo.launch()