Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python / Kivy - UrlRequest results

Tags:

python

kivy

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.

like image 703
MarceloBoy Avatar asked Oct 29 '22 23:10

MarceloBoy


1 Answers

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()
like image 199
el3ien Avatar answered Nov 18 '22 01:11

el3ien