Search code examples
pythonasynchronouspyscript

Pyscript async requests need force wait for the data


I am following the requests tutorial on pyscript here: https://docs.pyscript.net/latest/tutorials/requests.html I am not familiar with asyncio and there is no fuller Pyscript impementation to guide my needs on waiting for a request to complete and return data. Reading up on asyncio has not helped me so far.

I sucessfully get data from the server. I need a way to force wait until the data is obtained from the server.

async def get_tp_data():
    # request() is a wrapper for pyfetch - see https://docs.pyscript.net/latest/tutorials/requests.html
    response = await request("https: the server site)", method="GET")
    #print(f"GET request=> status:{response.status}"), json:{await response.json()}")
    tp_response = await response.json()
    tp_expansion = tp_response['expansion']
    tp_extension = tp_expansion['extension']
    tp_contains = tp_expansion['contains']
    print(tp_expansion['contains'])  # Sucessfully gets the data
    return await tp_contains

tp_contains = asyncio.create_task(get_tp_data())

def run_comparison(*ags, **kws):
    # Code here is called by index.html button press, this works
    # Do stuff with tp_contains

Solution

  • From the syntax and the fact that you mention asyncio and use the response object, I'm guessing you're following the other HTTP requests tutorial from the PyScript docs. The one you linked uses the pyodide-http package to patch the the requests package, and does not require asyncio. I think the tutorial you linked is actually the better route for small API requests that are unlikely to block for long, since it avoids the need for asyncio.

    By utilizing pyodide_http.patch_all(), the requests package mostly just works. Here's a slimmed-down version of your code, using an API-testing endpoint:

    <!-- index.html -->
    <py-config>
        packages = ["requests", "pyodide-http"]
    </py-config>
    
    <py-script src="demo.py"></py-script>
    <button py-click="run_comparison()">Get and Print Data</button>
    
    #demo.py
    import pyodide_http
    import requests
    
    # Patch the Requests library so it works with Pyscript
    pyodide_http.patch_all()
    
    def get_tp_data():
        response = requests.get("https://reqres.in/api/users?page=2")
        return response.json()
    
    def run_comparison(*ags, **kws):
        json_data = get_tp_data()
    
        #Do something interesting with the data
        print(f"The highest id is {max(item['id'] for item in json_data['data'])}")