Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,61 +1,126 @@
|
|
1 |
-
from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
|
2 |
import datetime
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
|
|
6 |
from tools.final_answer import FinalAnswerTool
|
7 |
-
|
8 |
from Gradio_UI import GradioUI
|
9 |
|
10 |
-
#
|
11 |
-
|
12 |
-
|
13 |
-
#Keep this format for the description / args / args description but feel free to modify the tool
|
14 |
-
"""A tool that does nothing yet
|
15 |
-
Args:
|
16 |
-
arg1: the first argument
|
17 |
-
arg2: the second argument
|
18 |
-
"""
|
19 |
-
return "What magic will you build ?"
|
20 |
|
21 |
@tool
|
22 |
-
def
|
23 |
-
"""
|
24 |
Args:
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
26 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
try:
|
28 |
-
#
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
except Exception as e:
|
34 |
-
return f"Error fetching
|
35 |
|
36 |
|
37 |
-
final_answer = FinalAnswerTool()
|
38 |
|
39 |
-
|
40 |
-
# model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
|
41 |
|
42 |
model = HfApiModel(
|
43 |
-
max_tokens=2096,
|
44 |
-
temperature=0.5,
|
45 |
-
model_id='Qwen/Qwen2.5-Coder-32B-Instruct'
|
46 |
-
custom_role_conversions=None,
|
47 |
)
|
48 |
|
49 |
-
|
50 |
-
# Import tool from Hub
|
51 |
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
|
52 |
|
53 |
-
with open("prompts.yaml",
|
54 |
prompt_templates = yaml.safe_load(stream)
|
55 |
-
|
56 |
agent = CodeAgent(
|
57 |
model=model,
|
58 |
-
tools=[final_answer],
|
59 |
max_steps=6,
|
60 |
verbosity_level=1,
|
61 |
grammar=None,
|
@@ -65,5 +130,6 @@ agent = CodeAgent(
|
|
65 |
prompt_templates=prompt_templates
|
66 |
)
|
67 |
|
68 |
-
|
69 |
-
GradioUI(agent)
|
|
|
|
1 |
+
from smolagents import CodeAgent, DuckDuckGoSearchTool, HfApiModel, load_tool, tool
|
2 |
import datetime
|
3 |
import requests
|
4 |
import pytz
|
5 |
import yaml
|
6 |
+
import os
|
7 |
from tools.final_answer import FinalAnswerTool
|
|
|
8 |
from Gradio_UI import GradioUI
|
9 |
|
10 |
+
# Fetch USGS API credentials from environment variables (set in Hugging Face Spaces secrets)
|
11 |
+
USGS_USERNAME = os.getenv("USGS_USERNAME")
|
12 |
+
USGS_TOKEN = os.getenv("USGS_TOKEN")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
@tool
|
15 |
+
def fetch_landsat_image(lat_min: float, lon_min: float, lat_max: float, lon_max: float, start_date: str, end_date: str) -> str:
|
16 |
+
"""Fetches download URLs for all available Landsat images from USGS M2M API and returns them as clickable HTML links.
|
17 |
Args:
|
18 |
+
lat_min: Minimum latitude of the bounding box
|
19 |
+
lon_min: Minimum longitude of the bounding box
|
20 |
+
lat_max: Maximum latitude of the bounding box
|
21 |
+
lon_max: Maximum longitude of the bounding box
|
22 |
+
start_date: Start date in 'YYYY-MM-DD' format
|
23 |
+
end_date: End date in 'YYYY-MM-DD' format
|
24 |
"""
|
25 |
+
if not USGS_USERNAME or not USGS_TOKEN:
|
26 |
+
return "<p>Error: USGS_USERNAME or USGS_TOKEN not set in environment variables.</p>"
|
27 |
+
|
28 |
+
service_url = "https://m2m.cr.usgs.gov/api/api/json/stable/"
|
29 |
+
|
30 |
+
def send_request(url, data, api_key=None):
|
31 |
+
json_data = json.dumps(data)
|
32 |
+
headers = {'X-Auth-Token': api_key} if api_key else {}
|
33 |
+
response = requests.post(url, json_data, headers=headers)
|
34 |
+
output = response.json()
|
35 |
+
if output.get('errorCode'):
|
36 |
+
return f"Error: {output['errorCode']} - {output['errorMessage']}"
|
37 |
+
return output['data']
|
38 |
+
|
39 |
try:
|
40 |
+
# Step 1: Authenticate
|
41 |
+
login_payload = {'username': USGS_USERNAME, 'token': USGS_TOKEN}
|
42 |
+
api_key = send_request(service_url + "login-token", login_payload)
|
43 |
+
if not api_key or isinstance(api_key, str) and "Error" in api_key:
|
44 |
+
return "<p>Authentication failed. Check username and token in secrets.</p>"
|
45 |
+
|
46 |
+
# Step 2: Search scenes
|
47 |
+
spatial_filter = {
|
48 |
+
'filterType': "mbr",
|
49 |
+
'lowerLeft': {'latitude': lat_min, 'longitude': lon_min},
|
50 |
+
'upperRight': {'latitude': lat_max, 'longitude': lon_max}
|
51 |
+
}
|
52 |
+
temporal_filter = {'start': start_date, 'end': end_date}
|
53 |
+
search_payload = {
|
54 |
+
'datasetName': 'landsat_ot_c2_l1',
|
55 |
+
'spatialFilter': spatial_filter,
|
56 |
+
'temporalFilter': temporal_filter,
|
57 |
+
'maxResults': 50,
|
58 |
+
'sortField': 'cloudCover',
|
59 |
+
'sortDirection': 'ASC'
|
60 |
+
}
|
61 |
+
scenes = send_request(service_url + "scene-search", search_payload, api_key)
|
62 |
+
if isinstance(scenes, str) and "Error" in scenes:
|
63 |
+
return f"<p>{scenes}</p>"
|
64 |
+
if not scenes['results']:
|
65 |
+
return "<p>No Landsat scenes found for the given area and time range.</p>"
|
66 |
+
|
67 |
+
# Step 3: Get download options
|
68 |
+
entity_ids = [scene['entityId'] for scene in scenes['results']]
|
69 |
+
download_options_payload = {
|
70 |
+
'datasetName': 'landsat_ot_c2_l1',
|
71 |
+
'entityIds': entity_ids
|
72 |
+
}
|
73 |
+
download_options = send_request(service_url + "download-options", download_options_payload, api_key)
|
74 |
+
if isinstance(download_options, str) and "Error" in download_options:
|
75 |
+
return f"<p>{download_options}</p>"
|
76 |
+
|
77 |
+
# Step 4: Request downloads
|
78 |
+
downloads = [opt for opt in download_options if opt['available']]
|
79 |
+
if not downloads:
|
80 |
+
return "<p>No available downloads for these scenes.</p>"
|
81 |
+
|
82 |
+
label = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
83 |
+
download_request_payload = {
|
84 |
+
'downloads': [{'entityId': opt['entityId'], 'productId': opt['id']} for opt in downloads],
|
85 |
+
'label': label
|
86 |
+
}
|
87 |
+
request_results = send_request(service_url + "download-request", download_request_payload, api_key)
|
88 |
+
if isinstance(request_results, str) and "Error" in request_results:
|
89 |
+
return f"<p>{request_results}</p>"
|
90 |
+
|
91 |
+
# Step 5: Generate HTML with clickable links
|
92 |
+
urls = [download['url'] for download in request_results['availableDownloads']]
|
93 |
+
if not urls:
|
94 |
+
return "<p>No download URLs immediately available. Try again later.</p>"
|
95 |
+
|
96 |
+
html_output = f"<p>Found {len(urls)} available Landsat scenes:</p><ul>"
|
97 |
+
for i, (scene, url) in enumerate(zip(scenes['results'][:len(urls)], urls)):
|
98 |
+
html_output += f'<li>Cloud Cover: {scene["cloudCover"]}% - <a href="{url}" target="_blank">Download Scene {i+1}</a></li>'
|
99 |
+
html_output += "</ul>"
|
100 |
+
return html_output
|
101 |
+
|
102 |
except Exception as e:
|
103 |
+
return f"<p>Error fetching Landsat images: {str(e)}</p>"
|
104 |
|
105 |
|
|
|
106 |
|
107 |
+
final_answer = FinalAnswerTool()
|
|
|
108 |
|
109 |
model = HfApiModel(
|
110 |
+
max_tokens=2096,
|
111 |
+
temperature=0.5,
|
112 |
+
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
|
113 |
+
custom_role_conversions=None,
|
114 |
)
|
115 |
|
|
|
|
|
116 |
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
|
117 |
|
118 |
+
with open("prompts.yaml", "r") as stream:
|
119 |
prompt_templates = yaml.safe_load(stream)
|
120 |
+
|
121 |
agent = CodeAgent(
|
122 |
model=model,
|
123 |
+
tools=[fetch_landsat_image, final_answer],
|
124 |
max_steps=6,
|
125 |
verbosity_level=1,
|
126 |
grammar=None,
|
|
|
130 |
prompt_templates=prompt_templates
|
131 |
)
|
132 |
|
133 |
+
# Launch Gradio UI
|
134 |
+
interface = GradioUI(agent)
|
135 |
+
interface.launch(share=True) # 'share=True' for public link in Spaces
|