I’m making a Python gui project using Tkinter module. The main problem is that I’ve searched multiple times, but can’t find a website for a free api. Many websites are saying to use OpenWeatherMap api but it is not working for me.
My code was :
from tkinter import *
import tkinter as tk
from geopy.geocoders import Nominatim
from tkinter import ttk, messagebox
from timezonefinder import TimezoneFinder
from datetime import datetime
import requests
import pytz
import json
root = Tk()
root.title("Weather")
root.geometry("900x500+300+200")
root.config(bg = "lightgrey")
root.resizable(True, False)
# search box
Search_image = PhotoImage(file = "Copy of search.png")
myimage = Label(image = Search_image)
myimage.place(x = 20, y = 20)
def getWeather():
city = textfield.get()
geolocator = Nominatim(user_agent = "geopiExercises")
location = geolocator.geocode(city)
obj = TimezoneFinder()
result = obj.timezone_at(lng = location.longitude, lat = location.latitude)
home = pytz.timezone(result)
local_time = datetime.now(home)
current_time = local_time.strftime("%I:%M:%p")
print(current_time)
clock.config(text = current_time)
name.config(text = "CURRENT TIME")
textfield = tk.Entry(root, justify = "center", width = 22,font = ("poppins",25,"bold" ), bg = "#404040", border = 0, fg = "white")
textfield.place(x = 54, y = 40)
textfield.focus()
city = textfield.get()
api_key = "my api key"
api = "https://api.openweathermap.org/data/3.0/onecall?" + city + "&appid=my api key"
json_data = requests.get(api)
response = json_data.json()
condition = response['weather'][0]['main']
description = response['weather'][0]['description']
temp = int(response['main']['temp']-273.15)
pressure = response['main']['pressure']
humidity = response['main']['humidity']
wind = response['wind']['speed']
print(response)
textfield.delete(1.0, END)
Search_icon = PhotoImage(file = "Copy of search_icon.png")
myimage2 = Button(image = Search_icon,borderwidth = 0,cursor = "hand2", bg = "#404040", command = getWeather )
myimage2.place(x = 380, y = 33)
#logo
Logo_image = PhotoImage(file = "logo.png")
myimage3 = Label(image = Logo_image)
myimage3.place(x = 150, y = 100)
# Bottom box
Frame_image = PhotoImage(file = "Copy of box.png")
myimage4 = Label(image = Frame_image)
myimage4.pack(padx = 5, pady = 5, side = BOTTOM)
# time
name = Label(root, font = ("arial",15 , "bold"))
name.place(x = 30, y = 100)
clock = Label(root, font = ("Helvetica", 20,"bold"))
clock.place(x = 30, y = 120)
# Label
label1 = Label(root, text = "WIND", font = ("Helvetica",15,"bold"), fg = "white", bg = "#1ab5ef")
label1.place(x = "120", y = "400")
label2 = Label(root, text = "HUMIDITY", font = ("Helvetica",15,"bold"), fg = "white", bg = "#1ab5ef")
label2.place(x = "250", y = "400")
label3 = Label(root, text = "CONDITION", font = ("Helvetica",15,"bold"), fg = "white", bg = "#1ab5ef")
label3.place(x = "430", y = "400")
label4 = Label(root, text = "PRESSURE", font = ("Helvetica",15,"bold"), fg = "white", bg = "#1ab5ef")
label4.place(x = "650", y = "400")
t = Label(font = ("arial", 70, "bold"), fg = "#ee666d")
t.place(x = 400, y = 150 )
c = Label(font = ("arial", 15, "bold"))
c.place(x = 400, y = 250 )
t.config(text = (temp, "°"))
c.config(text = (condition, "|", "FEELS", "LIKE", temp, "°"))
w = Label(text = "...", font = ("arial", 20, "bold"), bg = "#1ab5ef")
w.place(x = 130 , y = 430)
w2 = Label(text = "...", font = ("arial", 20, "bold"), bg = "#1ab5ef")
w2.place(x = 280 , y = 430)
w3 = Label(text = "...", font = ("arial", 20, "bold"), bg = "#1ab5ef")
w3.place(x = 450 , y = 430)
w4 = Label(text = "...", font = ("arial", 20, "bold"), bg = "#1ab5ef")
w4.place(x = 670 , y = 430)
root.mainloop()
The error I get after executing the above code is:
Traceback (most recent call last):
File "C:UsersHaniaDesktoppppWeatherApp.py", line 53, in <module>
condition = response['weather'][0]['main']
KeyError: 'weather'
I think that the code is perfectly fine and the error is related to the api. Please suggest what to do.
Thanks in advance.
2
Answers
The problem with your code is that the api is requested before you enter a value for the text field. As
lat
andlon
are required parameter for the OpenWeather API, you getError 400
as a response (see here)Try this minimal example of what you are trying to achieve
In your script. You had like this:
Your place() isn’t appropriately laid out.
You had too many Tkinter widgets. So you can reduce the number of widgets. It is up to you.
Don’t use this https://api.openweathermap.org/data/3.0/onecall? It asking for:
Notice. you cannot run on fly like this without create function:
It doesn’t do work.
So Here is the code:
Screenshot:
Btw, if you want to all widgets, Then comment out.
It will look like this: