File size: 4,725 Bytes
e4fce57
 
 
6c28af3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4fce57
6c28af3
e4fce57
6c28af3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4fce57
 
 
 
6c28af3
 
e4fce57
 
 
 
6c28af3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
e4fce57
6c28af3
e4fce57
6c28af3
 
 
 
 
 
 
 
e4fce57
6c28af3
e4fce57
 
 
 
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
import gradio as gr
import requests

# 1. Helper function to decode WMO Weather Codes into human-readable text
def get_weather_description(code):
    # WMO Weather interpretation codes (WW)
    codes = {
        0: ("β˜€οΈ", "Clear sky"),
        1: ("🌀️", "Mainly clear"),
        2: ("β›…", "Partly cloudy"),
        3: ("☁️", "Overcast"),
        45: ("🌫️", "Fog"),
        48: ("🌫️", "Depositing rime fog"),
        51: ("🌦️", "Light Drizzle"),
        53: ("🌦️", "Moderate Drizzle"),
        55: ("🌧️", "Dense Drizzle"),
        61: ("β˜”", "Slight Rain"),
        63: ("β˜”", "Moderate Rain"),
        65: ("β›ˆοΈ", "Heavy Rain"),
        71: ("🌨️", "Slight Snow"),
        73: ("🌨️", "Moderate Snow"),
        75: ("❄️", "Heavy Snow"),
        80: ("🌧️", "Slight Rain Showers"),
        81: ("🌧️", "Moderate Rain Showers"),
        82: ("β›ˆοΈ", "Violent Rain Showers"),
        95: ("⚑", "Thunderstorm"),
        96: ("⚑", "Thunderstorm with slight hail"),
        99: ("⚑", "Thunderstorm with heavy hail"),
    }
    return codes.get(code, ("❓", "Unknown"))

# 2. Main Function to fetch data
def get_weather_data(city_name):
    if not city_name:
        return "Please enter a city name.", "", "", "", ""

    try:
        # Step A: Geocoding (Convert City Name to Latitude/Longitude)
        geo_url = "https://geocoding-api.open-meteo.com/v1/search"
        geo_params = {"name": city_name, "count": 1, "language": "en", "format": "json"}
        
        geo_res = requests.get(geo_url, params=geo_params).json()
        
        if not geo_res.get("results"):
            return f"❌ Could not find city: '{city_name}'", "-", "-", "-", "-"

        location = geo_res["results"][0]
        lat = location["latitude"]
        lon = location["longitude"]
        city_display = f"{location['name']}, {location.get('country', '')}"

        # Step B: Get Weather Data (Current conditions)
        # We request: temp, relative humidity, apparent temp (feels like), weather code, wind speed
        weather_url = "https://api.open-meteo.com/v1/forecast"
        weather_params = {
            "latitude": lat,
            "longitude": lon,
            "current": ["temperature_2m", "relative_humidity_2m", "apparent_temperature", "weather_code", "wind_speed_10m"],
            "wind_speed_unit": "kmh"
        }

        w_res = requests.get(weather_url, params=weather_params).json()
        current = w_res["current"]

        # Step C: Format Data
        temp = f"{current['temperature_2m']}Β°C"
        feels_like = f"{current['apparent_temperature']}Β°C"
        humidity = f"{current['relative_humidity_2m']}%"
        wind = f"{current['wind_speed_10m']} km/h"
        
        icon, description = get_weather_description(current["weather_code"])
        status_text = f"{icon} {description}"
        
        # Return all values to fill the UI boxes
        return f"πŸ“ Weather in {city_display}", temp, feels_like, status_text, f"πŸ’§ Humidity: {humidity} | πŸ’¨ Wind: {wind}"

    except Exception as e:
        return f"⚠️ Error: {str(e)}", "-", "-", "-", "-"

# 3. Build the Professional UI using Blocks
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    
    gr.Markdown(
        """
        # 🌍 Global Weather Tracker
        ### Real-time weather data powered by Open-Meteo
        """
    )
    
    with gr.Row():
        with gr.Column(scale=1):
            city_input = gr.Textbox(
                label="Search City", 
                placeholder="Type city name (e.g. Lahore, Tokyo)...", 
                lines=1
            )
            search_btn = gr.Button("Get Weather", variant="primary")
        
        with gr.Column(scale=2):
            # Header for the result
            location_output = gr.Markdown("### πŸ“ Enter a city to begin")
            
            with gr.Row():
                temp_output = gr.Textbox(label="Temperature", value="-")
                feels_output = gr.Textbox(label="Feels Like", value="-")
            
            with gr.Row():
                condition_output = gr.Textbox(label="Condition", value="-")
                details_output = gr.Textbox(label="Details", value="-")

    # Connect the button to the function
    search_btn.click(
        fn=get_weather_data,
        inputs=city_input,
        outputs=[location_output, temp_output, feels_output, condition_output, details_output]
    )
    
    # Allow pressing "Enter" to search
    city_input.submit(
        fn=get_weather_data,
        inputs=city_input,
        outputs=[location_output, temp_output, feels_output, condition_output, details_output]
    )

if __name__ == "__main__":
    demo.launch()