1

I try to fetch data from my api in python using pyscript. Following the pyscript documentation I use the async keyword on my main function and use asyncio.ensure_future to execute it, everything before the first await work but not the await keyword and any other line of code after it.

This is my code:

async def request(url: str,
                  method: str = "GET",
                  body: Optional[str] = None,
                  headers: Optional[dict[str, str]] = None,
                  **fetch_kwargs: Any) -> FetchResponse:
    kwargs = {
        "method": method,
        "mode": "no-cors"
    }  # CORS: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
    if body and method not in ["GET", "HEAD"]:
        kwargs["body"] = body
    if headers:
        kwargs["headers"] = headers
    kwargs.update(fetch_kwargs)

    response = await pyfetch(url, **kwargs)
    return response

async def get_barycenter(
        filename: str,
        base_url: str = "http://localhost:8001") -> dict[str, Any] | None:
    headers = {"Content-type": "application/json"}
    response = await request(f"{base_url}/barycenter/?image_name={filename}",
                             headers=headers)
    body = await response.json()
    if body.status != 200:
        return None
    return body.msg

async def main():
    print('start')
    test = await get_barycenter("img.jpg")
    print(test)
    print("end")


asyncio.ensure_future(main())

The result is only the print of start and nothing else no print of test are even "end". I tested the API the data is visible in Insomnia and I set up correctly the cors Policy.

  • You aren't running the event loop, you're just creating an asyncio Task. This script doesn't actually do anything. But it's close: just replace `ensure_future` with `run` and something should happen. The function asyncio.run will start the execution of an asyncio program and will not return until the main function is complete. – Paul Cornelius Feb 17 '23 at 15:28
  • 1
    @PaulCornelius this is incorrect in the context of PyScript (though accurate in the context of 'typical' Python) - the `run` function does not act as expected in PyScript, `ensure_future()` or `create_task()` should be used instead. – Jeff Glass Feb 17 '23 at 15:36

1 Answers1

0

Part of the issue here is an existing issue in PyScript where exceptions raised in Coroutines aren't displayed on the page. To help with this for now, I would recommend adding the following snippet before your request function:

import js

def handler(loop, context):
    js.console.error(context.message)
    raise(context.exception)

pyscript.loop.set_exception_handler(handler)

This way, exceptions raised in coroutines are displayed in the browser's console log.

What the root issue of the the fetch request is I couldn't say, but at least this will get errors displaying and help you troubleshoot. For example, when I run your code, I see:

GET http://localhost:8001/barycenter/?image_name=img.jpg net::ERR_CONNECTION_REFUSED

Since I don't have a local server running - hopefully the errors that appear for you are more helpful.

Jeff Glass
  • 622
  • 1
  • 8
  • I tried to put the pyscript.loop.set_execption_handler(handler) before the prin("start") in the main function there is no new message in the console log; if I put it before the asyncio.ensure.future(main), the pyiodide runtime just loads without finishing. – Samuel Diop Feb 27 '23 at 10:48
  • You'll want it to be outside of your main() function, so it's set up before main in scheduled. Putting it just beneath the imports is what I tested with, and it worked. – Jeff Glass Feb 27 '23 at 19:21
  • So I tried your code sample, and when I shut down my server, I had the same error message as you indeed, but if I have my server running no errors are displayed in the console. My best guess is there is no error, but if that is the case, why did the main function never finish its execution? I also tried to raise an error from python similar to [this issue](https://github.com/pyscript/pyscript/issues/1137#issue-1559924446), but I put the raise keyword before any await, and nothing appears in the browser or console. – Samuel Diop Feb 28 '23 at 08:29