I am trying to run a simple pyodide example, but am not too familiar with javascript or pyodide and am not sure why the output is undefined. The statement is executed fine as I can see the correct output in the console log, but I cannot assign the output to the document.
here is the code
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
window.languagePluginUrl = 'https://cdn.jsdelivr.net/pyodide/v0.17.0a2/full/';
</script>
<script src="https://cdn.jsdelivr.net/pyodide/v0.17.0a2/full/pyodide.js"></script>
</head>
<body>
<p>You can execute any Python code. Just enter something in the box below and click the button.</p>
<textarea id='code' style='width: 50%;' rows='10'>print('hello')</textarea>
<button onclick='evaluatePython()'>Run</button>
<br>
<br>
<div>
Output:
</div>
<textarea id='output' style='width: 50%;' rows='3' disabled></textarea>
<script>
const output = document.getElementById("output");
const code = document.getElementById("code");
// show output
function addToOutput(s) {
output.value = s;
}
function evaluatePython() {
let output = pyodide.runPythonAsync(code.value)
.then(output => addToOutput(output))
.catch((err) => { addToOutput(err)});
}
</script>
</body>
</html>
I was loosely following the alternative example from here -- https://pyodide.org/en/stable/using_pyodide_from_javascript.html
Basically, you can implement your own function for printing. However, if you want to use exactly print
you can override the function from JS.
Update: Pyodide v0.21.0
pyodide.globals.set('print', s => console.log(s))
This will replace the python function print
with the JS console.log
const output = document.getElementById("output");
const code = document.getElementById("code");
async function evaluatePython() {
// load imports if there are any
await pyodide.loadPackagesFromImports(code.value)
addToOutput(pyodide.runPython(code.value))
}
// show output
function addToOutput(s) {
output.value = s;
}
let pyodide;
// init pyodide
(async () => { // enable await
pyodide = await loadPyodide();
// override default print behavior
pyodide.globals.set('print', s => console.log(s))
})() // call the function immediately
<script src="https://cdn.jsdelivr.net/pyodide/v0.21.0/full/pyodide.js"></script>
<p>You can execute any Python code. Just enter something in the box below and click the button.</p>
<textarea id='code' style='width: 50%;' rows='10'>print('hello')</textarea>
<button onclick='evaluatePython()'>Run</button>
<br>
<br>
<div>
Output:
</div>
<textarea id='output' style='width: 50%; margin-bottom: 100px;' rows='3' disabled></textarea>
More examples can be found here.
Old answer (related to Pyodide v0.15.0)
languagePluginLoader.then(()=>{
pyodide.globals.print = s => s
})
which does nothing but returns the input parameter, since its output will then be written to the container (.then(output => addToOutput(output))
). Of course, you can implement any custom behavior, such as writing the input to a container directly.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
window.languagePluginUrl = 'https://cdn.jsdelivr.net/pyodide/v0.17.0a2/full/';
</script>
<script src="https://cdn.jsdelivr.net/pyodide/v0.17.0a2/full/pyodide.js"></script>
</head>
<body>
<p>You can execute any Python code. Just enter something in the box below and click the button.</p>
<textarea id='code' style='width: 50%;' rows='10'>print('hello')</textarea>
<button onclick='evaluatePython()'>Run</button>
<br>
<br>
<div>
Output:
</div>
<textarea id='output' style='width: 50%;' rows='3' disabled></textarea>
<script>
const output = document.getElementById("output");
const code = document.getElementById("code");
// show output
function addToOutput(s) {
output.value = s;
}
function evaluatePython() {
let output = pyodide.runPythonAsync(code.value)
.then(output => addToOutput(output))
.catch((err) => { addToOutput(err)});
}
languagePluginLoader.then(()=>{
// override default print behavior
pyodide.globals.print = s => s
})
</script>
</body>
</html>