MarceloBoy MarceloBoy - 4 months ago 72
Python Question

Python / Kivy - UrlRequest results

i'm strugling with this for some time now and couldn't find a solution.

So i was studying Python and Kivy with the "Creating Apps in Kivy" from Dusty Phillips.
It's a simple weather app and when i try to get data from openweathermap.com, the UrlRequest function doesn't work as it should. I'm pretty new to kivy and python and such but as i see, the function must call the "found_location" method with two arguments: request and result (a list got from the url).
If i access the url from my browser, i get the right results, but back to python, the 'results' came as NONE.

Here's the code with some prints for debug:

from kivy.app import App
#kivy.require("1.9.1")
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.network.urlrequest import UrlRequest

class AddLocationForm(BoxLayout):
search_input = ObjectProperty()
search_results = ObjectProperty()
def search_location(self):

search_template = "api.openweathermap.org/data/2.5/forecast/daily?APPID=ef4f6b76310abad083b96a45a6f547be&q=" + "{}"
search_url = search_template.format(self.search_input.text)
print search_url
request = UrlRequest(search_url, self.found_location)
print request
print "Result: ", request.result

def found_location(self, request, data):
print request
print data
data = json.loads(data.decode()) if not isinstance(data, dict) else data
cities = ["{} ({})".format(d['name'], d['sys']['country'])
for d in data['list']]
print cities
self.search_results.item_strings = cities
print "DONE"

class WeatherApp(App):
pass


if __name__ == '__main__':
WeatherApp().run()


And here the console:

[INFO ] [OSC ] using <multiprocessing> for socket
[INFO ] [Base ] Start application main loop
[INFO ] [GL ] NPOT texture support is available
api.openweathermap.org/data/2.5/forecast/daily?APPID=ef4f6b76310abad083b96a45a6f547be&q=London
<UrlRequest(Thread-1, started daemon 139654193755904)>
Result: None


As you can see, it's passing the correct URL and in browser i got the right results, but the "found_location" method is never called and in python the request.results = None

What am i doing wrong?

Hope you guys can understand my question. Thanks for the help and sorry for the english.

Answer

The problem here is that you print the result before its downloaded successfully.

Also remember to put "http://" infront of the link string.

Remember, that the url is loaded asyncronically. As it says in the docs on UrlRequest

You can use the UrlRequest to make asynchronous requests on the web and get the result when the request is completed. The spirit is the same as the XHR object in Javascript.

Thats why you want to use the on_success parameter in UrlRequest

I will make an example for you.

from kivy.app import App
#kivy.require("1.9.1")
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.network.urlrequest import UrlRequest

class MyWidget(BoxLayout):
    def __init__(self,**kwargs):
        super(MyWidget,self).__init__(**kwargs)
        search_url = "http://api.openweathermap.org/data/2.5/forecast/daily?APPID=ef4f6b76310abad083b96a45a6f547be&q=new%20york"
        print search_url
        self.request = UrlRequest(search_url, self.res)
        print self.request
        print "Result: before success", self.request.result,"\n"


    def res(self,*args):
        print "Result: after success", self.request.result


class MyApp(App):
    def build(self):
        return MyWidget()


if __name__ == '__main__':
    MyApp().run()