pythonrequestkivyurlrequest

Python/Kivy 2.1.0: how to access body of URL request


Hope you all doing fine. I am new here and hopefully you might help me. Developing my first Python mobile app right now and using Kivy 2.1.0 for this. Unfortunately I am blocked in Kivy which seems to be too easy in pure Python development.

My goal: accessing the body of an URL HTTP request so that I can work with the resulting string of that body. I want to compary if the string contains "STATE=ON" or "STATE=OFF"

response of my desination URL gives back: ControlSTATE=ON (or optional STATE=OFF, depending on the current WIfi Switch status)

the solution in Python (without Kivy):

import requests
   x = requests.get('URLofYourChoise)   
   print(x.text)

And this works (tested!)

the solution in Kivy should look sth. like this:

from kivy.network.urlrequest import UrlRequest
   body = UrlRequest(' URLofYourChoise  ')
   print(body.text)

And this does not work :(

But what can I do with "body"? Where is the content from the HTTP response?

While watching in debug modus on my variable body, I can find the desired response in: body → _queue → 0 → 2:

Debug inspected variable 'status'

I read the Kivy documentation, but honestly I think I have a lack of knowledge somewhere.

Hopefully you are able to solve my problem :) Thank you in advance!

I tried to read the Kivy URLrequest documentation in order to understand the available properties

I tried to use the Python request library → not possible as the application builder (GitHub → Repository → Actions) throws an error because of this


Solution

  • UrlRequest uses an async method. You have to define callback function to be called when response will be retrieved. Here you have same code:

    from kivy.app import App
    from kivy.network.urlrequest import UrlRequest
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.textinput import TextInput
    
    class Application(App):
    
        def build(self):
            root_layout = BoxLayout()
            label = TextInput()
            root_layout.ids['content'] = label
            root_layout.add_widget(label)
            return root_layout
    
        def request_callback(self, req, result):
            print(f'HttpStatus: {req.resp_status}')
            print(f'Response Headers: {req.resp_headers}')
            print(f'Response: {result}')
    
            self.root.ids.content.text += f'HttpStatus: {req.resp_status}\n\n'
            self.root.ids.content.text += f'Response Headers: {req.resp_headers}\n\n'
            self.root.ids.content.text += f'Response: {result}\n'
            self.root.ids.content.cursor = 0, 0
    
        def on_start(self):
            UrlRequest('http://neverssl.com', self.request_callback, debug=True)
    
    Application().run()
    

    If you want to use it in synchronous way you may use wait method like this:

    from kivy.app import App
    from kivy.network.urlrequest import UrlRequest
    from kivy.uix.boxlayout import BoxLayout
    from kivy.uix.textinput import TextInput
    
    class Application(App):
    
        def build(self):
            root_layout = BoxLayout()
            label = TextInput()
            root_layout.ids['content'] = label
            root_layout.add_widget(label)
            return root_layout
    
        def on_start(self):
            req = UrlRequest('http://neverssl.com', debug=True)
            req.wait()
    
            print(f'HttpStatus: {req.resp_status}')
            print(f'Response Headers: {req.resp_headers}\n\n')
            print(f'Response: {req.result}\n')
    
            self.root.ids.content.text += f'HttpStatus: {req.resp_status}\n\n'
            self.root.ids.content.text += f'Response Headers: {req.resp_headers}\n\n'
            self.root.ids.content.text += f'Response: {req.result}\n'
    
    Application().run()