Abby Reynolds commited on
Commit
1476642
·
1 Parent(s): 42db9ab

added api and display for analyzing department for specific artworks

Browse files
Files changed (4) hide show
  1. .gitignore +2 -1
  2. main.py +21 -1
  3. met_api.py +61 -0
  4. requirements.txt +3 -1
.gitignore CHANGED
@@ -1 +1,2 @@
1
- venv
 
 
1
+ venv
2
+ final_project
main.py CHANGED
@@ -1,5 +1,6 @@
1
  import streamlit as st
2
-
 
3
  # Page setup
4
  st.set_page_config(page_title="The METrics", layout="centered")
5
 
@@ -62,6 +63,25 @@ st.markdown("""
62
  </div>
63
  """, unsafe_allow_html=True)
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  st.write("")
66
 
67
  # Footer
 
1
  import streamlit as st
2
+ import met_api
3
+ import pandas as pd
4
  # Page setup
5
  st.set_page_config(page_title="The METrics", layout="centered")
6
 
 
63
  </div>
64
  """, unsafe_allow_html=True)
65
 
66
+ # Department analytic
67
+ st.write("")
68
+ st.subheader("Departments for your search")
69
+
70
+ query = st.text_input("Search term (for images only)", value="cats", key="dept_query")
71
+ max_ids = st.slider("How many results to analyze", 20, 400, 150, 10, key="dept_max")
72
+
73
+ if st.button("Run department analytic", key="dept_run"):
74
+ with st.spinner("Fetching and tallying departments…"):
75
+ rows = met_api.department_counts(q=query, max_ids=max_ids)
76
+
77
+ if not rows:
78
+ st.info("No results found (or the API call failed). Try another term.")
79
+ else:
80
+ df = pd.DataFrame(rows, columns=["Department", "Count"])
81
+ # show a quick bar chart + table
82
+ st.bar_chart(df.set_index("Department"))
83
+ st.dataframe(df, use_container_width=True)
84
+
85
  st.write("")
86
 
87
  # Footer
met_api.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import random
3
+
4
+ URL = "https://collectionapi.metmuseum.org/public/collection/v1/"
5
+
6
+ '''
7
+ Need to add error handling
8
+ '''
9
+
10
+ # gets information on a single object
11
+ def get_object(objectID):
12
+ return requests.get(f"{URL}/objects/{objectID}").json()
13
+
14
+ # gets all the objects that have some sort of image
15
+ def get_objectsWithImages():
16
+ response = requests.get(f"{URL}search?hasImages=true&q=*").json()
17
+ total = response["total"]
18
+ objectIDs = response["objectIDs"]
19
+ return total, objectIDs
20
+
21
+ # gets the urls for random objects with images
22
+ def get_images(totalObjects, objectIDs, limit):
23
+ images = []
24
+ # grabbing extra in case a primary image is blank (Works best on small limits)
25
+ rand_indexes = random.sample(range(totalObjects), limit + 20)
26
+ for i in rand_indexes:
27
+ obj = get_object(objectIDs[i])
28
+ if obj["primaryImage"]:
29
+ images.append((obj["primaryImage"], obj["title"]))
30
+ if len(images) == limit:
31
+ break
32
+
33
+ return images
34
+
35
+ def department_counts(q="*", max_ids=200):
36
+ """
37
+ Analytic: return a list of (department, count) for search results.
38
+ - q: search query (default '*' = anything)
39
+ - max_ids: cap how many object IDs to inspect (keeps it fast)
40
+
41
+ Uses the Met search endpoint (images only), then tallies the 'department'
42
+ field from each object's metadata.
43
+ """
44
+ try:
45
+ resp = requests.get(f"{URL}search", params={"q": q, "hasImages": True}, timeout=15)
46
+ resp.raise_for_status()
47
+ ids = (resp.json().get("objectIDs") or [])[:max_ids]
48
+ except Exception:
49
+ return []
50
+
51
+ counts = {}
52
+ for oid in ids:
53
+ try:
54
+ obj = get_object(oid) # uses your existing helper
55
+ dep = obj.get("department") or "(unknown)"
56
+ counts[dep] = counts.get(dep, 0) + 1
57
+ except Exception:
58
+ continue
59
+
60
+ # return sorted (department, count) pairs, highest first
61
+ return sorted(counts.items(), key=lambda x: x[1], reverse=True)
requirements.txt CHANGED
@@ -1 +1,3 @@
1
- streamlit==1.48.1
 
 
 
1
+ streamlit==1.48.1
2
+ pandas
3
+ requests