Super-Space-WX / app.py
nakas's picture
Update app.py
217e5a5 verified
raw
history blame
4.25 kB
"""
Radar Data Downloader via Gradio
==================================
This script mimics part of Supercell Wx’s functionality by downloading the latest
radar data file (Level 2 or Level 3) from public AWS S3 buckets. It uses boto3 in unsigned mode,
so no AWS credentials or API keys are required. The Gradio interface lets you select the
data type, radar station, and date (in UTC) to download a file.
"""
import datetime
import io
import boto3
from botocore import UNSIGNED
from botocore.client import Config
import gradio as gr
def fetch_latest_radar_data(radar_type, station, date_str):
"""
Downloads the latest radar data file from the appropriate S3 bucket.
Parameters:
radar_type (str): Either "Level 2" or "Level 3".
station (str): Radar station identifier (e.g. "KTLX").
date_str (str): Date string in the format "YYYY-MM-DD". If blank, uses current UTC date.
Returns:
str: A text summary including the S3 key, file size, last modified date,
and a hex preview of the first 64 bytes of the file.
"""
# Parse the date (default to current UTC if empty)
if not date_str.strip():
date_obj = datetime.datetime.utcnow()
else:
try:
date_obj = datetime.datetime.strptime(date_str, "%Y-%m-%d")
except ValueError:
return "Error: Date must be in YYYY-MM-DD format."
year = date_obj.strftime("%Y")
month = date_obj.strftime("%m")
day = date_obj.strftime("%d")
# Choose the appropriate bucket based on radar type.
if radar_type == "Level 2":
bucket_name = "noaa-nexrad-level2"
# For Level 2, the folder structure is: YYYY/MM/DD/STATION/
prefix = f"{year}/{month}/{day}/{station.upper()}/"
elif radar_type == "Level 3":
bucket_name = "unidata-nexrad-level3"
# For Level 3, the structure is similar.
prefix = f"{year}/{month}/{day}/{station.upper()}/"
else:
return "Error: Invalid radar type selected."
# Create an S3 client with unsigned requests.
s3 = boto3.client('s3', config=Config(signature_version=UNSIGNED))
try:
response = s3.list_objects_v2(Bucket=bucket_name, Prefix=prefix)
except Exception as e:
return f"Error accessing bucket: {e}"
if 'Contents' not in response:
return f"No data found for station {station.upper()} on {date_str} in {radar_type}."
# Sort objects by LastModified and choose the latest file.
objects = response['Contents']
objects_sorted = sorted(objects, key=lambda x: x['LastModified'])
latest_object = objects_sorted[-1]
file_key = latest_object['Key']
file_size = latest_object['Size']
last_modified = latest_object['LastModified']
# Download the file into a BytesIO buffer.
buffer = io.BytesIO()
try:
s3.download_fileobj(bucket_name, file_key, buffer)
except Exception as e:
return f"Error downloading file: {e}"
buffer.seek(0)
# Read a short preview (first 64 bytes) and convert to hex.
data_preview = buffer.read(64)
hex_preview = data_preview.hex()
# Return a summary of the downloaded file.
summary = (
f"Downloaded file: {file_key}\n"
f"Size: {file_size} bytes\n"
f"Last Modified (UTC): {last_modified}\n"
f"Hex preview (first 64 bytes):\n{hex_preview}"
)
return summary
# Create the Gradio interface.
interface = gr.Interface(
fn=fetch_latest_radar_data,
inputs=[
gr.inputs.Radio(choices=["Level 2", "Level 3"], label="Radar Data Type"),
gr.inputs.Textbox(label="Radar Station (e.g. KTLX)", default="KTLX"),
gr.inputs.Textbox(label="Date (YYYY-MM-DD)", default=datetime.datetime.utcnow().strftime("%Y-%m-%d"))
],
outputs="text",
title="Radar Data Downloader",
description=(
"This tool downloads the latest radar data file from public AWS S3 buckets "
"used by Supercell Wx. Choose a radar data type (Level 2 or Level 3), enter a "
"radar station (e.g. KTLX), and a date (UTC). In future iterations, you can add "
"visualization using OpenStreetMap (which requires no API keys)."
)
)
if __name__ == "__main__":
interface.launch()