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