mg643 commited on
Commit
b97e32c
·
2 Parent(s): a8d63affee0793

Merge pull request #2 from MrinalGoel643/han_result_dashboard

Browse files
Files changed (3) hide show
  1. .gitignore +2 -1
  2. main.py +46 -28
  3. met_api.py +123 -0
.gitignore CHANGED
@@ -1,2 +1,3 @@
1
  venv
2
- final_project
 
 
1
  venv
2
+ final_project
3
+ .idea
main.py CHANGED
@@ -1,8 +1,11 @@
1
  import streamlit as st
2
  import pandas as pd
3
- from met_api import get_objectsWithImages, get_images
 
 
 
 
4
 
5
- # Caching Section
6
  @st.cache_data
7
  def cache_objectsWithImages():
8
  return get_objectsWithImages()
@@ -44,32 +47,47 @@ st.markdown(
44
  unsafe_allow_html=True
45
  )
46
 
47
- total, ids = cache_objectsWithImages()
48
- images = cache_images(total, ids, limit=3)
49
-
50
-
51
- if images:
52
- # Columns with fixed-height images
53
- col1, col2, col3 = st.columns(3)
54
-
55
- with col1:
56
- st.markdown(
57
- f"<div class='img-box'><img src='{images[0][0]}'></div>",
58
- unsafe_allow_html=True
59
- )
60
- st.markdown(f"<div>{images[0][1]}</div>", unsafe_allow_html=True)
61
- with col2:
62
- st.markdown(
63
- f"<div class='img-box'><img src='{images[1][0]}'></div>",
64
- unsafe_allow_html=True
65
- )
66
- st.markdown(f"<div>{images[1][1]}</div>", unsafe_allow_html=True)
67
- with col3:
68
- st.markdown(
69
- f"<div class='img-box'><img src='{images[2][0]}'></div>",
70
- unsafe_allow_html=True
71
- )
72
- st.markdown(f"<div>{images[2][1]}</div>", unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
  st.write("")
75
  st.write("")
 
1
  import streamlit as st
2
  import pandas as pd
3
+ from met_api import search_for_images, get_objectsWithImages, get_images
4
+
5
+ @st.cache_data
6
+ def cached_search_for_images(query):
7
+ return search_for_images(query, 2,departments=[1,3,4,5,6,7])
8
 
 
9
  @st.cache_data
10
  def cache_objectsWithImages():
11
  return get_objectsWithImages()
 
47
  unsafe_allow_html=True
48
  )
49
 
50
+
51
+ # Columns with fixed-height images
52
+ col1, col2, col3 = st.columns(3)
53
+
54
+ q = st.text_input("Search term (for images only)", value="UFO", key="search_query")
55
+
56
+ r = cached_search_for_images(q)
57
+
58
+ summary = r[["primaryImageSmall","title","department","objectName"]]
59
+
60
+ config = {
61
+ "primaryImageSmall": st.column_config.ImageColumn(),
62
+ }
63
+
64
+ event = st.dataframe(summary, column_config=config, use_container_width=True, on_select="rerun", selection_mode="single-row")
65
+
66
+ if event.selection.rows:
67
+ selected_index = event.selection.rows[0] # Get the index of the first selected row
68
+ selected_row_data = r.iloc[selected_index]
69
+
70
+ st.subheader("Details of Selected Row:")
71
+ st.image(selected_row_data["primaryImage"], caption=selected_row_data["title"], width=500)
72
+ st.write(selected_row_data)
73
+ else:
74
+ st.info("Select a row in the table to see its details.")
75
+
76
+ with col1:
77
+ st.markdown(
78
+ "<div class='img-box'><img src='https://images.metmuseum.org/CRDImages/ep/web-large/DP-29324-001.jpg'></div>",
79
+ unsafe_allow_html=True
80
+ )
81
+ with col2:
82
+ st.markdown(
83
+ "<div class='img-box'><img src='https://images.metmuseum.org/CRDImages/ad/web-large/DP124705.jpg'></div>",
84
+ unsafe_allow_html=True
85
+ )
86
+ with col3:
87
+ st.markdown(
88
+ "<div class='img-box'><img src='https://images.metmuseum.org/CRDImages/gr/web-large/DP21847edited.jpg'></div>",
89
+ unsafe_allow_html=True
90
+ )
91
 
92
  st.write("")
93
  st.write("")
met_api.py CHANGED
@@ -1,5 +1,7 @@
 
1
  import requests
2
  import random
 
3
 
4
  URL = "https://collectionapi.metmuseum.org/public/collection/v1/"
5
 
@@ -59,3 +61,124 @@ def department_counts(q="*", max_ids=200):
59
 
60
  # return sorted (department, count) pairs, highest first
61
  return sorted(counts.items(), key=lambda x: x[1], reverse=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
  import requests
3
  import random
4
+ import pandas as pd
5
 
6
  URL = "https://collectionapi.metmuseum.org/public/collection/v1/"
7
 
 
61
 
62
  # return sorted (department, count) pairs, highest first
63
  return sorted(counts.items(), key=lambda x: x[1], reverse=True)
64
+
65
+ """
66
+ Get a list of departments
67
+ """
68
+ def list_met_departments():
69
+ """
70
+ Return a DataFrame of all Met departments (id + name) to help you choose.
71
+ """
72
+ r = requests.get(f"{URL}/departments")
73
+ r.raise_for_status()
74
+ depts = r.json().get("departments", [])
75
+ return pd.DataFrame(depts)[["departmentId", "displayName"]]
76
+
77
+ """
78
+ returns a dataframe of list of objects with images and metadata that matches search term
79
+ To be polite, will only get default max 5 random results from each department,
80
+ but can be specified as parameter. Also, can choose the departments to search from.
81
+ """
82
+ def search_for_images(query,
83
+ max_per_department=5,
84
+ departments=None):
85
+
86
+ if not query or not query.strip():
87
+ raise ValueError("Please provide a query.")
88
+
89
+ # 1) Departments
90
+ if departments is None:
91
+ resp = requests.get(f"{URL}/departments")
92
+ resp.raise_for_status()
93
+ dept_list = resp.json().get("departments", [])
94
+ dept_ids = [d["departmentId"] for d in dept_list]
95
+ dept_id_to_name = {d["departmentId"]: d["displayName"] for d in dept_list}
96
+ else:
97
+ dept_ids = list(departments)
98
+ # Names will be filled from object details; provide a generic fallback
99
+ dept_id_to_name = {d: f"Department {d}" for d in dept_ids}
100
+
101
+ # 2) Per-department search → random sample of IDs → fetch details
102
+ rows = []
103
+ #session = requests.Session()
104
+
105
+ print("Searching for", query)
106
+ print("Departments:", dept_ids)
107
+
108
+ for dept_id in dept_ids:
109
+ # limit to only those with images and is highlighted
110
+ params = {
111
+ "q": query,
112
+ "hasImages": "true",
113
+ #"isHighlight": "true",
114
+ "departmentId": dept_id,
115
+ }
116
+ try:
117
+ r = requests.get(f"{URL}/search", params=params)
118
+ #print(r.url)
119
+ r.raise_for_status()
120
+ except requests.RequestException:
121
+ continue
122
+
123
+ object_ids = (r.json() or {}).get("objectIDs") or []
124
+ if not object_ids:
125
+ continue
126
+
127
+ sample_ids = random.sample(object_ids, k=min(max_per_department, len(object_ids)))
128
+
129
+ for oid in sample_ids:
130
+ #print(f"Found: {oid}")
131
+ try:
132
+ obj = requests.get(f"{URL}/objects/{oid}").json()
133
+ except requests.RequestException:
134
+ continue
135
+
136
+ # skip if no image
137
+ if not obj["primaryImage"]:
138
+ continue
139
+
140
+ rows.append({
141
+ "objectID": obj.get("objectID"),
142
+ "title": obj.get("title"),
143
+ "artistDisplayName": obj.get("artistDisplayName"),
144
+ "objectDate": obj.get("objectDate"),
145
+ "culture": obj.get("culture"),
146
+ "medium": obj.get("medium"),
147
+ "department": obj.get("department") or dept_id_to_name.get(dept_id),
148
+ "objectName": obj.get("objectName"),
149
+ "classification": obj.get("classification"),
150
+ "primaryImageSmall": obj.get("primaryImageSmall"),
151
+ "primaryImage": obj.get("primaryImage"),
152
+ "objectURL": obj.get("objectURL"),
153
+ "isPublicDomain": obj.get("isPublicDomain"),
154
+ })
155
+
156
+ df = pd.DataFrame(rows)
157
+ if not df.empty:
158
+ df = df.sort_values(["department", "title"]).reset_index(drop=True)
159
+ return df
160
+
161
+ """
162
+ CLI when run from command line
163
+ Displays the departments to allow user to input a department
164
+ Then searches the department based on input, and displays the results with images.
165
+ """
166
+ def main():
167
+ print("Welcome to Met Search")
168
+ departments = list_met_departments()
169
+ print(departments.to_string(index=False))
170
+ random.seed(time.time())
171
+ while True:
172
+ dept_no = input("Choose a departmentId #: (or enter for all)").strip()
173
+ if dept_no == '':
174
+ dept = None
175
+ else:
176
+ dept = [int(dept_no)]
177
+ results = search_for_images(input("Search the Met for: "),2, departments=dept)
178
+ if results.empty:
179
+ print("No results found.")
180
+ continue
181
+ print(results.to_string(index=False))
182
+
183
+ if __name__ == '__main__':
184
+ main()