Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -5,6 +5,7 @@ import json
|
|
5 |
from datetime import datetime
|
6 |
import time
|
7 |
import os
|
|
|
8 |
|
9 |
# Set page configuration
|
10 |
st.set_page_config(
|
@@ -103,6 +104,129 @@ def get_access_token():
|
|
103 |
st.error(f"⚠️ Error getting access token: {str(e)}")
|
104 |
return None
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
# Function to search pets
|
107 |
def search_pets(params):
|
108 |
token = get_access_token()
|
|
|
5 |
from datetime import datetime
|
6 |
import time
|
7 |
import os
|
8 |
+
import functools
|
9 |
|
10 |
# Set page configuration
|
11 |
st.set_page_config(
|
|
|
104 |
st.error(f"⚠️ Error getting access token: {str(e)}")
|
105 |
return None
|
106 |
|
107 |
+
# Function to get RescueGroups API key
|
108 |
+
def get_rescuegroups_api_key():
|
109 |
+
api_key = os.environ.get('RESCUEGROUPS_API_KEY') or st.secrets.get('RESCUEGROUPS_API_KEY')
|
110 |
+
if not api_key:
|
111 |
+
st.error("⚠️ RescueGroups API key is missing. Please set it in environment variables or Streamlit secrets.")
|
112 |
+
return None
|
113 |
+
return api_key
|
114 |
+
|
115 |
+
# Function to search pets from RescueGroups.org
|
116 |
+
@functools.lru_cache(maxsize=32)
|
117 |
+
def search_rescuegroups_pets_cached(type_param, location, distance):
|
118 |
+
api_key = get_rescuegroups_api_key()
|
119 |
+
if not api_key:
|
120 |
+
return None
|
121 |
+
|
122 |
+
url = "https://api.rescuegroups.org/v5/public/animals/search"
|
123 |
+
|
124 |
+
headers = {
|
125 |
+
"Authorization": api_key,
|
126 |
+
"Content-Type": "application/vnd.api+json"
|
127 |
+
}
|
128 |
+
|
129 |
+
body = {
|
130 |
+
"data": {
|
131 |
+
"type": "animals",
|
132 |
+
"attributes": {
|
133 |
+
"species": type_param,
|
134 |
+
"locationPostalcode": location,
|
135 |
+
"distance": distance,
|
136 |
+
"status": "Available",
|
137 |
+
"sort": "distance",
|
138 |
+
"limit": 100
|
139 |
+
}
|
140 |
+
}
|
141 |
+
}
|
142 |
+
|
143 |
+
try:
|
144 |
+
response = requests.post(url, headers=headers, json=body)
|
145 |
+
response.raise_for_status()
|
146 |
+
return response.json()
|
147 |
+
except requests.exceptions.RequestException as e:
|
148 |
+
st.error(f"⚠️ Error searching pets from RescueGroups: {str(e)}")
|
149 |
+
return None
|
150 |
+
|
151 |
+
def search_rescuegroups_pets(params):
|
152 |
+
return search_rescuegroups_pets_cached(params.get("type", "Dog"), params.get("location", ""), params.get("distance", 50))
|
153 |
+
|
154 |
+
# Function to normalize RescueGroups results
|
155 |
+
def normalize_rescuegroups_data(rg_data):
|
156 |
+
pets = []
|
157 |
+
if not rg_data or 'data' not in rg_data:
|
158 |
+
return pets
|
159 |
+
|
160 |
+
for item in rg_data['data']:
|
161 |
+
pet = {
|
162 |
+
'id': f"RG-{item['id']}",
|
163 |
+
'name': item['attributes'].get('name', 'Unknown'),
|
164 |
+
'status': 'adoptable',
|
165 |
+
'age': item['attributes'].get('ageGroup', ''),
|
166 |
+
'gender': item['attributes'].get('sex', ''),
|
167 |
+
'size': item['attributes'].get('sizeGroup', ''),
|
168 |
+
'breeds': {
|
169 |
+
'primary': item['attributes'].get('breedPrimary', ''),
|
170 |
+
'secondary': item['attributes'].get('breedSecondary', ''),
|
171 |
+
'mixed': False
|
172 |
+
},
|
173 |
+
'colors': {
|
174 |
+
'primary': item['attributes'].get('colorPrimary', ''),
|
175 |
+
'secondary': item['attributes'].get('colorSecondary', ''),
|
176 |
+
'tertiary': ''
|
177 |
+
},
|
178 |
+
'photos': [],
|
179 |
+
'description': item['attributes'].get('description', ''),
|
180 |
+
'contact': {
|
181 |
+
'email': '',
|
182 |
+
'phone': '',
|
183 |
+
'address': {
|
184 |
+
'city': '',
|
185 |
+
'state': '',
|
186 |
+
'postcode': ''
|
187 |
+
}
|
188 |
+
},
|
189 |
+
'source': 'RescueGroups'
|
190 |
+
}
|
191 |
+
if 'photos' in item['attributes'] and item['attributes']['photos']:
|
192 |
+
pet['photos'] = [{'medium': item['attributes']['photos'][0]}]
|
193 |
+
pets.append(pet)
|
194 |
+
return pets
|
195 |
+
|
196 |
+
# Example modification in your search form to call BOTH APIs
|
197 |
+
with st.form("pet_search_form"):
|
198 |
+
# ... your existing form fields ...
|
199 |
+
submitted = st.form_submit_button("Search")
|
200 |
+
|
201 |
+
if submitted:
|
202 |
+
params = {
|
203 |
+
"type": animal_type.split(" ")[0],
|
204 |
+
"location": location,
|
205 |
+
"distance": distance
|
206 |
+
}
|
207 |
+
|
208 |
+
petfinder_results = search_pets(params)
|
209 |
+
rescuegroups_results = search_rescuegroups_pets(params)
|
210 |
+
|
211 |
+
combined_pets = []
|
212 |
+
|
213 |
+
if petfinder_results and 'animals' in petfinder_results:
|
214 |
+
for pet in petfinder_results['animals']:
|
215 |
+
pet['source'] = 'Petfinder'
|
216 |
+
combined_pets.append(pet)
|
217 |
+
if rescuegroups_results:
|
218 |
+
normalized = normalize_rescuegroups_data(rescuegroups_results)
|
219 |
+
combined_pets.extend(normalized)
|
220 |
+
|
221 |
+
if combined_pets:
|
222 |
+
st.session_state.search_results = {'animals': combined_pets}
|
223 |
+
st.session_state.page = 1
|
224 |
+
st.success(f"Found {len(combined_pets)} pets from both sources!")
|
225 |
+
else:
|
226 |
+
st.error("No pets found. Try adjusting your filters.")
|
227 |
+
|
228 |
+
|
229 |
+
|
230 |
# Function to search pets
|
231 |
def search_pets(params):
|
232 |
token = get_access_token()
|