3 Ways to Implement Network Requests in Pyodide
Tags: python, pyodide, http, programming
Published: 2022-07-17 01:14:44

## Question

I mentioned an [Online Python Tool](https://lwebapp.com/en/post/python-online) before, and the core technology is to use a tool called [Pyodide](https://github.com/pyodide/pyodide) library, which can make Python run on web pages, but I found in the learning process that not all Python built-in libraries or extension libraries can run, such as `requests` is not supported.

According to the discussion under this [issue](https://github.com/pyodide/pyodide/issues/398#issuecomment-873312724), `requests` relies on `Lib/http.client.py` which relies on `Lib/sockets.py` which relies on `socketmodule.c` which needs `<sys/socket.h>`. Emscripten provides `<sys/socket.h>` support but if we used this, then the http requests would only work if we used them with a custom server that accepts web socket connections (or proxied all requests through such a server that could forward the requests as true http requests). So that wouldn't be ideal.

So if your local Python program uses the `requests` method, when switching to our online Python tool to run, you need to update the usage of network requests. Here we briefly introduce the three methods of network request.

## Solution

### 1. http.open_url

Fetches a given URL synchronously.

```python
import pyodide
print(pyodide.http.open_url('https://mocki.io/v1/d4867d8b-b5d5-4a48-a4ab-79131b5809b8').read())
```

Online Demo: [Python Playground - http.open_url](<https://lwebapp.com/en/python-playground?code=import%20pyodide%0Aprint(pyodide.http.open_url('https%3A%2F%2Fmocki.io%2Fv1%2Fd4867d8b-b5d5-4a48-a4ab-79131b5809b8').read())>)

### 2. http.pyfetch

Fetch the url and return the response.

```python
import pyodide

async def get_data():
    response = await pyodide.http.pyfetch('https://mocki.io/v1/d4867d8b-b5d5-4a48-a4ab-79131b5809b8')
    data = await response.json()
    print(data)

get_data()
```

Online Demo: [Python Playground - http.pyfetch](<https://lwebapp.com/en/python-playground?code=import%20pyodide%0A%0Aasync%20def%20get_data()%3A%0A%20%20%20%20response%20%3D%20await%20pyodide.http.pyfetch('https%3A%2F%2Fmocki.io%2Fv1%2Fd4867d8b-b5d5-4a48-a4ab-79131b5809b8')%0A%20%20%20%20data%20%3D%20await%20response.json()%0A%20%20%20%20print(data)%0A%0Aget_data()>)

This method is recommended for obtaining image data

```python
# request image
response = await pyodide.http.pyfetch('https://gcore.jsdelivr.net/gh/openHacking/static-files@main/img/16576149784751657614977527.png')
# Return the response body as a bytes object
image_data = await response.bytes()
```

Detailed reference case: [Python Image to ASCII Online](https://lwebapp.com/en/post/python-image-to-ascii)

### 3. fetch in js module

Pyodide wraps the js API, and uses the native js fetch API to implement network requests

```python
import json
from js import fetch, JSON

async def get_data():
    response = await fetch('https://mocki.io/v1/d4867d8b-b5d5-4a48-a4ab-79131b5809b8',{'method':'GET'})
    data = await response.json()
    print(JSON.stringify(data))

await get_data()
```

Online Demo: [Python Playground - js fetch](<https://lwebapp.com/en/python-playground?code=import%20json%0Afrom%20js%20import%20fetch%2CJSON%0A%0Aasync%20def%20get_data()%3A%0A%20%20%20%20response%20%3D%20await%20fetch('https%3A%2F%2Fmocki.io%2Fv1%2Fd4867d8b-b5d5-4a48-a4ab-79131b5809b8'%2C%7B'method'%3A'GET'%7D)%0A%20%20%20%20data%20%3D%20await%20response.json()%0A%20%20%20%20print(JSON.stringify(data))%0A%0Aawait%20get_data()>)

## Conclusion

The above are the three network request methods commonly used in Pyodide that I have summarized. There may be many shortcomings. If you have a better method, please share it.

## Reference

- [3 Ways to Implement Network Requests in Pyodide](https://lwebapp.com/en/post/pyodide-fetch)
- [pyodide python api](https://pyodide.org/en/stable/usage/api/python-api.html)
- [pyodide.http.open_url](https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.open_url)
- [pyodide.http.pyfetch](https://pyodide.org/en/stable/usage/api/python-api.html#pyodide.http.pyfetch)
- [pyodide.runPythonAsync](https://pyodide.org/en/stable/usage/api/js-api.html?highlight=fetch#pyodide.runPythonAsync)
- [pyodide - requests module is not available #398](https://github.com/pyodide/pyodide/issues/398)