Spaces:
Sleeping
Sleeping
| import openai | |
| import gradio as gr | |
| import os | |
| import requests | |
| from datetime import datetime, timedelta | |
| # β API keys | |
| openai.api_key = os.getenv("OPENAI_API_KEY") | |
| OWM_API_KEY = os.getenv("OPENWEATHER_API_KEY") | |
| # β GPT-based Weather Response | |
| def weather_response(top_city, custom_city, user_query): | |
| city = custom_city.strip() if custom_city and custom_city.strip() != "" else top_city | |
| if not city or not user_query: | |
| return "β Please enter both a city and a weather question." | |
| prompt = f""" | |
| You are a friendly Gulf-region weather assistant. Answer this user query: '{user_query}' in {city}. | |
| Include temperature, advice, and 2+ relevant emojis (π‘οΈ, βοΈ, π§οΈ, etc.). | |
| """ | |
| try: | |
| response = openai.ChatCompletion.create( | |
| model="gpt-4o", | |
| messages=[ | |
| {"role": "system", "content": "You are a cheerful Gulf weather bot with emojis."}, | |
| {"role": "user", "content": prompt} | |
| ] | |
| ) | |
| return response.choices[0].message["content"].strip() | |
| except Exception as e: | |
| return f"β οΈ OpenAI Error: {e}" | |
| # β Tomorrow's Forecast (Real) | |
| def forecast_tomorrow(top_city, custom_city): | |
| city = custom_city.strip() if custom_city and custom_city.strip() != "" else top_city | |
| if not city: | |
| return "β Please select or enter a city." | |
| try: | |
| url = f"http://api.openweathermap.org/data/2.5/forecast?q={city}&appid={OWM_API_KEY}&units=metric" | |
| response = requests.get(url) | |
| data = response.json() | |
| tomorrow = data['list'][8] # ~24 hours later | |
| date = datetime.fromtimestamp(tomorrow['dt']).strftime("%A, %B %d") | |
| desc = tomorrow['weather'][0]['description'].title() | |
| temp = tomorrow['main']['temp'] | |
| humidity = tomorrow['main']['humidity'] | |
| wind = tomorrow['wind']['speed'] | |
| return f"""π **Forecast for {city.title()} β {date}** | |
| - π‘οΈ Temp: {temp}Β°C | |
| - π¬οΈ Wind: {wind} m/s | |
| - π§ Humidity: {humidity}% | |
| - π€οΈ Condition: {desc} | |
| Stay safe and enjoy your day! βοΈ | |
| """ | |
| except Exception as e: | |
| return f"β οΈ Could not fetch weather data: {str(e)}" | |
| # β 5-Day Forecast (Real) | |
| def forecast_week(top_city, custom_city): | |
| city = custom_city.strip() if custom_city and custom_city.strip() != "" else top_city | |
| if not city: | |
| return "β Please select or enter a city." | |
| try: | |
| url = f"http://api.openweathermap.org/data/2.5/forecast?q={city}&appid={OWM_API_KEY}&units=metric" | |
| response = requests.get(url) | |
| data = response.json() | |
| if "list" not in data: | |
| return f"β οΈ Error from OpenWeather: {data.get('message', 'No data returned')}" | |
| forecasts = data["list"] | |
| forecast_msg = f"π **5-Day Forecast for {city.title()}**\n\n" | |
| used_days = set() | |
| for entry in forecasts: | |
| dt = datetime.fromtimestamp(entry["dt"]) | |
| day = dt.strftime("%A, %B %d") | |
| if day in used_days: | |
| continue | |
| temp = entry["main"]["temp"] | |
| desc = entry["weather"][0]["description"].title() | |
| humidity = entry["main"]["humidity"] | |
| wind = entry["wind"]["speed"] | |
| forecast_msg += f"π **{day}**\nπ€οΈ {desc}\nπ‘οΈ {temp}Β°C | π§ {humidity}% | π¬οΈ {wind} m/s\n\n" | |
| used_days.add(day) | |
| if len(used_days) == 5: | |
| break | |
| if not used_days: | |
| return "β οΈ Could not extract 5-day forecast. Try again later." | |
| return forecast_msg.strip() | |
| except Exception as e: | |
| return f"β οΈ Forecast error: {str(e)}" | |
| # β City List | |
| gulf_cities = [ | |
| "Dubai", "Abu Dhabi", "Doha", "Riyadh", "Jeddah", "Muscat", | |
| "Kuwait City", "Manama", "Amman", "Beirut", "Baghdad" | |
| ] | |
| # β UI | |
| with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as app: | |
| gr.Markdown(""" | |
| <h2 style='text-align: center;'>π <b>Real-Time Weather Bot - Powered by OpenWeather</b> π</h2> | |
| <p style='text-align: center;'>Ask questions or get actual forecasts β¬οΈ</p> | |
| """) | |
| with gr.Row(): | |
| with gr.Column(): | |
| top_city = gr.Dropdown(choices=gulf_cities, label="Top Gulf Cities", value=None,allow_custom_value=True ) | |
| custom_city = gr.Textbox(label="Or enter a city not listed") | |
| with gr.Column(): | |
| query = gr.Textbox(label="Ask a Weather Question (GPT)", placeholder="e.g., Is it hot in Muscat?") | |
| result = gr.Textbox(label="π€οΈ Weather Update", lines=10, interactive=False) | |
| with gr.Row(): | |
| submit_btn = gr.Button("π¦οΈ GPT Answer") | |
| tomorrow_btn = gr.Button("βοΈ Real Tomorrow Forecast") | |
| week_btn = gr.Button("π Real 5-Day Forecast") | |
| clear_btn = gr.Button("π§Ή Clear All") | |
| submit_btn.click(fn=weather_response, inputs=[top_city, custom_city, query], outputs=result) | |
| tomorrow_btn.click(fn=forecast_tomorrow, inputs=[top_city, custom_city], outputs=result) | |
| week_btn.click(fn=forecast_week, inputs=[top_city, custom_city], outputs=result) | |
| clear_btn.click(fn=lambda: ("", "", "", ""), inputs=[], outputs=[top_city, custom_city, query, result]) | |
| app.launch() | |