Python Forum
Error loading location on openweathermap via API with Kivy
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Error loading location on openweathermap via API with Kivy
#1
Dear all,
I am following the examples reported in Phillips' manual 'creating apps in Kivy' (O'Reilly); exercise 2-10 is related to using API to query OpenWeatherMap: by typing a city's name in the search box, a list of cities should appear in the main box. The example is given with 'Vancouver'.

However, when I type it, either nothing or an error occurs. I have two series of files: mine and those I downloaded from the book's website. The kivy file itself is exactly the same and goes like this:

AddLocationForm:

<AddLocationForm>:
    orientation: "vertical"
    search_input: search_box 
    search_results: search_results_list
    BoxLayout:
        height: "40dp"
        size_hint_y: None
        TextInput:
            id: search_box 
            size_hint_x: 50
        Button:
            text: "Search"
            size_hint_x: 25
            on_press: root.search_location()
        Button:
            text: "Current Location"
            size_hint_x: 25
    ListView:
        id: search_results_list
        item_strings: []
The python file from the book runs like this:
from kivy.network.urlrequest import UrlRequest
import json

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty


class AddLocationForm(BoxLayout):
    search_input = ObjectProperty()
    search_results = ObjectProperty()

    def search_location(self):
        search_template = "http://api.openweathermap.org/data/2.5/find?q={}&type=like" 
        search_url = search_template.format(self.search_input.text)
        request = UrlRequest(search_url, self.found_location)

    # BEGIN SEARCHLOCATION
    def found_location(self, request, data):
        data = json.loads(data.decode()) if not isinstance(data, dict) else data # <1>
        cities = ["{} ({})".format(d['name'], d['sys']['country']) 
            for d in data['list']]
        self.search_results.item_strings = cities  # <2>
    # END SEARCHLOCATION


class WeatherApp(App):
    pass

if __name__ == '__main__':
	WeatherApp().run()
When I run this file, I type 'Vancouver', press the SEARCH button and nothing happens. This should work because it is the example given.

I thought the proplem was with the API, perhaps the website has changed syntax recently (the book is dated 2014). So I opened an account with OpenWeatherMap, got a unique key that here I am anonymizing with 'XXX', added the line print("You searched for: '{}'".format(self.search_input.text)) to check if the input is properly taken and added a shebang for launching the file from terminal:

#!/usr/bin/python3

"""
main for kivy
"""

from kivy.network.urlrequest import UrlRequest
import json

from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty

# API variables
API_key = "XXX"
base_url = "http://api.openweathermap.org/data/2.5/weather?"


class AddLocationForm(BoxLayout):
  search_input = ObjectProperty()
  
  def search_location(self):
    search_template = base_url + "appid=" + API_key + "&q={}"
    search_url = search_template.format(self.search_input.text)
    request = UrlRequest(search_url, self.found_location)
    print("You searched for: '{}'".format(self.search_input.text))
    
  def found_location(self, request, data):
    data = json.loads(data.decode()) if not isinstance(data, dict) else data # <1>
    cities = ["{} ({})".format(d['name'], d['sys']['country']) 
        for d in data['list']]
    self.search_results.item_strings = cities


class WeatherApp(App):
  pass


if __name__ == '__main__':
  WeatherApp().run()
When I try this, I get these error:
Error:
You searched for: 'Vancouver' Traceback (most recent call last): File "<ipython-input-1-d7e4d412339a>", line 1, in <module> runfile('/home/gigiux/Documents/main.py', wdir='/home/gigiux/Documents') File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 705, in runfile execfile(filename, namespace) File "/usr/lib/python3/dist-packages/spyder/utils/site/sitecustomize.py", line 102, in execfile exec(compile(f.read(), filename, 'exec'), namespace) File "/home/gigiux/Documents/main.py", line 40, in <module> WeatherApp().run() File "/usr/lib/python3/dist-packages/kivy/app.py", line 826, in run runTouchApp() File "/usr/lib/python3/dist-packages/kivy/base.py", line 502, in runTouchApp EventLoop.window.mainloop() File "/usr/lib/python3/dist-packages/kivy/core/window/window_sdl2.py", line 727, in mainloop self._mainloop() File "/usr/lib/python3/dist-packages/kivy/core/window/window_sdl2.py", line 460, in _mainloop EventLoop.idle() File "/usr/lib/python3/dist-packages/kivy/base.py", line 337, in idle Clock.tick() File "/usr/lib/python3/dist-packages/kivy/clock.py", line 581, in tick self._process_events() File "kivy/_clock.pyx", line 384, in kivy._clock.CyClockBase._process_events File "kivy/_clock.pyx", line 414, in kivy._clock.CyClockBase._process_events File "kivy/_clock.pyx", line 412, in kivy._clock.CyClockBase._process_events File "kivy/_clock.pyx", line 167, in kivy._clock.ClockEvent.tick File "/usr/lib/python3/dist-packages/kivy/network/urlrequest.py", line 460, in _dispatch_result func(self, data) File "/home/gigiux/Documents/main.py", line 31, in found_location for d in data['list']] KeyError: 'list'
What am I getting wrong?

Thank you
Reply
#2
print data to find out what it contains because it has no key 'list'
Reply
#3
I can't print data: it does not come out in the python file but I think is defined via json after querying the openweather site. In theory the line cities = ["{} ({})".format(d['name'], d['sys']['country']) for d in data['list']] should print a list of cities similar to the query typed in the search box, so there are two hits for Vancouver, on in the US and one in Canada. The IDE is also flagging the variable request in search_location because it is never used.
Reply
#4
data = json.loads(data.decode()) if not isinstance(data, dict) else data # <1>
Print(type(data), data)
to find out what it is and what it contains.
Reply
#5
I changed the function is:
  def found_location(self, request, data):
    data = json.loads(data.decode()) if not isinstance(data, dict) else data 
    print(type(data), data)
    cities = ["{} ({})".format(d['name'], d['sys']['country']) for d in data['list']] 
    self.search_results.item_strings = cities
The result is:
You searched for: 'Vancouver'
<class 'dict'> {'coord': {'lon': -122.67, 'lat': 45.63}, 'weather': [{'id': 500, 'main': 'Rain', 'description': 'light rain', 'icon': '10d'}], 'base': 'stations', 'main': {'temp': 292.03, 'pressure': 1023, 'humidity': 55, 'temp_min': 289.15, 'temp_max': 294.26}, 'visibility': 16093, 'wind': {'speed': 1.5, 'deg': 360}, 'rain': {'1h': 0.25}, 'clouds': {'all': 40}, 'dt': 1555614246, 'sys': {'type': 1, 'id': 5321, 'message': 0.0088, 'country': 'US', 'sunrise': 1555593581, 'sunset': 1555642796}, 'id': 5814616, 'name': 'Vancouver', 'cod': 200}
Traceback (most recent call last): ... etc
Reply
#6
That shows the available dictionary keys of which 'list' is not one of them.
Output:
dict_keys(['coord', 'weather', 'base', 'main', 'visibility', 'wind', 'rain', 'clouds', 'dt', 'sys', 'id', 'name', 'cod'])
there are dictionaries in the dictionary but they don't have 'list' as a key either.
Output:
{'base': 'stations', 'clouds': {'all': 40}, 'cod': 200, 'coord': {'lat': 45.63, 'lon': -122.67}, 'dt': 1555614246, 'id': 5814616, 'main': {'humidity': 55, 'pressure': 1023, 'temp': 292.03, 'temp_max': 294.26, 'temp_min': 289.15}, 'name': 'Vancouver', 'rain': {'1h': 0.25}, 'sys': {'country': 'US', 'id': 5321, 'message': 0.0088, 'sunrise': 1555593581, 'sunset': 1555642796, 'type': 1}, 'visibility': 16093, 'weather': [{'description': 'light rain', 'icon': '10d', 'id': 500, 'main': 'Rain'}], 'wind': {'deg': 360, 'speed': 1.5}}
Reply
#7
Ok, but how do I get 'Vancouver, US' and Vancouver, CA' as expected?
I changed the line cities = ["{} ({})".format(d['name'], d['sys']['country']) for d in data['list']] to cities = ["{} ({})".format(d['name'], d['sys']['country']) for d in list['data']] thinking that perhaps it was a typo in the book. The result was:

cities = ["{} ({})".format(d['name'], d['sys']['country']) for d in list['data']]

TypeError: 'type' object is not subscriptable
Reply
#8
The results you have are for Vancouver, US itself not a list of the various Vancouver
you have
https://openweathermap.org/city/5814616
not
https://openweathermap.org/find?q=Vancouver
Reply
#9
The query should be, according to my update (which I used as a patch but might be simply wrong):
API_key = "XXX"
base_url = "http://api.openweathermap.org/data/2.5/weather?"
search_template = base_url + "appid=" + API_key + "&q={}"
According to the manual, it should be:
search_template = "http://api.openweathermap.org/data/2.5/find?q={}&type=like" 
By running your listing https://openweathermap.org/find?q=Vancouver, I get:
File "/home/gigiux/Documents/main.py", line 30, in found_location
    data = json.loads(data.decode()) if not isinstance(data, dict) else data

AttributeError: 'str' object has no attribute 'decode'
Is this getting closer?
Reply
#10
I found an errata for the manual at: https://www.oreilly.com/catalog/errata.c...6920032595: the search_template object should be "http://api.openweathermap.org/data/2.5/find?q={}&type=like&APPID="+ appidkey where appidkey is the ID given upon registration. But even with this update, which is similar to what I have done, the thing does not work.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Error when running kivy on python janeik 8 2,058 Jun-16-2023, 10:58 PM
Last Post: janeik
  Error loading Trelby.py blackclover 3 2,518 Jan-05-2021, 10:08 PM
Last Post: blackclover
  import error (unknown location) pseudo 1 10,779 Nov-14-2019, 11:47 PM
Last Post: pseudo
  kivy - packaging touchtracer syntax error cram 2 2,553 Oct-14-2019, 08:30 PM
Last Post: cram
  Getting error while loading excel(.xlsx) file using openpyxl module shubhamjainj 1 8,979 Mar-01-2019, 01:05 PM
Last Post: buran
  error creating new object after loading pickled objects from file arogers 2 3,443 Feb-02-2019, 10:43 AM
Last Post: Larz60+
  PyQt5 No Error But GUI Window Not Loading digitalmatic7 1 4,240 Nov-21-2017, 05:23 PM
Last Post: digitalmatic7
  Error while loading the csv file Analyst 3 10,235 Oct-18-2017, 07:07 AM
Last Post: Analyst
  'NoneType' object has no attribute error, when using Kivy Screens chelovek 3 11,073 Feb-05-2017, 05:37 AM
Last Post: chelovek

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020