How can I do HTTP POST requests on Pyodide
Asked Answered
P

3

6

In pyodide, it is not support the requests module so to fetch the data from api we used open_url and how can we use the api for post the Data using pyodide

Powerless answered 11/11, 2020 at 15:16 Comment(0)
I
7

Update: Pyodide v0.21.2

It is currently impossible to use the requests since sockets are not available in Pyodide.

However, you can use JS Fetch API direct form Python code. To do this, you must import window object from js module. Here is a live demo:

(async () => { // enable await
  // init pyodide
  let pyodide = await loadPyodide();
  // import window object
  pyodide.runPython('from js import window')
  // fetch json
  let result = await pyodide.runPythonAsync("window.fetch('http://karay.me/truepyxel/test.json')")
  // result is now a response object
  console.log(result)
  // convert response to json
  let data = await result.json()
  console.log(data)
  alert(data.msg)
})() // call the function immediately
<script src="https://cdn.jsdelivr.net/pyodide/v0.21.2/full/pyodide.js"></script>

More details here.


Pyodide v0.15.0

let python_code = `
from js import window

def fetch():
  window.fetch('http://karay.me/truepyxel/test.json').then(lambda resp: resp.json()).then(lambda jsoh: show_result(jsoh))
  
def show_result(data):
  div = window.document.createElement('div')
  #insert into body as a first child
  window.document.body.prepend(div)
  div.innerHTML=window.JSON.stringify(data)
`

// init environment
languagePluginLoader
// then run Python code
  .then(() => pyodide.runPythonAsync(python_code));
<!DOCTYPE html>
<html>
<head>
<script src="https://pyodide-cdn2.iodide.io/v0.15.0/full/pyodide.js"></script>
</head>
<body>
<button onclick='pyodide.globals.fetch()'>Fetch</button>
</body>
</html>
Incompliant answered 12/11, 2020 at 12:50 Comment(0)
T
3

The requests module is currently not supported in pyodide because it relies on sockets which are not implemented in the WebAssembly browser VM.

You can however, make POST calls using Web APIs in pyodide. Below is an example using XMLHttpRequest

from js import XMLHttpRequest, Blob
import json

data = {"a": 1}

req = XMLHttpRequest.new()
req.open("POST", "https://httpbin.org/anything", False)
blob = Blob.new([json.dumps(data)], {type : 'application/json'})
req.send(blob)
str(req.response)

In the future it's possible that some of the classical HTTP client modules might be patched to use Web APIs in pyodide (cf pyodide#140).

Tabitha answered 11/11, 2020 at 15:46 Comment(4)
How can I install that js module? It's not this one I think pypi.org/project/javascript?Ious
It's provided by Pyodide, you don't need to install it, it's available by default there. So if you use anything that uses Pyodide: PyScript, JupyterLite etc you will have it. If you use a different wasm build of Python then this module won't exist, and you will not be able to use it.Tabitha
Thanks @rth! Perhaps this question is too broad for a comment here, but if I want to test this code locally, how would I do that? I installed pyodide with pip install pyodide-py, but that doesn't seem to allow me to import js.Ious
Actually you should install pyodide >=v0.25.0a2, that and later version should just work with requests, so you would no longer need the explicitly import the js module for this functionality. About things not being quite identical with installing pyodide-py outside of the browser, yes that's expected and unfortunately a limitation of that apporachTabitha
R
2

As already mentioned we cannot use requests, so you can use javascript fetch to perform the POST operation, the sample snippet will work with pydiode and pyscript (async format), this same code can be written in sync-fashion using add_done_callback

import asyncio
from js import console, fetch

async def post_data():
    response = await fetch('http://example.com/test',{'method':'POST'})
    json = await response.json()
    console.log('json', json)
    return json

await post_data()
Rollicking answered 2/5, 2022 at 8:28 Comment(2)
Which module is that js? I don't think it's this one pypi.org/project/javascript ?Ious
Given this is in Pyodide, it's the one that enables you to use js from the global scope (ie in the browser/runtime). See here: pyodide.org/en/stable/usage/api/python-api.htmlEllora

© 2022 - 2024 — McMap. All rights reserved.