Making the Python requests module work in Pyodide
05 Nov 2021Update 2023-04-21: Everything here describes a hacky solution. The same has now been done properly by the pyodide_http
project.
The Pyodide project compiles the CPython interpreter and a collection of popular libraries to the browser. This is done using emscripten and results in Javascript and WebAssembly packages. This means you get an almost complete Python distribution, that can run completely in the browser.
Pure Python packages are also pip-installable in Pyodide, but these packages might not be usable if they (indirectly)
depend on one of the unsupported Python standard libraries.
This has the result that you can’t do a lot of network-related things. Anything that
depends on importing socket
or the http
library will not work. Because of this, you can’t use the popular library
requests
yet.
The project’s roadmap has
plans for adding this networking support,
but this might not be ready soon.
Therefore I created an alternative requests
module specifically for Pyodide, which bridges the requests
API and makes
JavaScript XMLHttpRequest
s. I’m currently developing it in a fork at
bartbroere/requests#1
.
Helping hands are always welcome!
Since most browsers have strong opinions on what a request should look like in terms of included headers and cookies,
this new version of requests
will not always do what the normal requests
does. This can be a feature instead of a bug.
For example, if the browser already has an authenticated session to an API, you could automatically send authenticated requests
from your Python code.
This is the end result, combined with some slightly dirty hacks (in python3.9.js
) to make the script MIME type text/x-python
evaluate automatically:
<script src="https://pypi.bartbroe.re/python3.9.js"></script>
<script type="text/x-python">
from pprint import pprint
import requests
pprint(requests.get('https://httpbin.org/get', params={'key': 'value'}).json())
pprint(requests.get('https://httpbin.org/post', data={'key': 'value'}).json())
</script>
Hopefully, my requests
module will not have a long life, because the Pyodide project has plans to make a more sustainable solution.
Until then, it might be a cool hack to support the up to 34K libraries that depend on requests
in the Pyodide interpreter.