Apr-14-2019, 02:40 PM
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:
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
Thank you
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