i wanted to know how to use python script with tauri app, i tried a few things but failed i try to take an input from the user using html tag then want to pass it to python and then after the python code does the adding wanted to display the result back in the html page, i got confused how to communicate the two of them(python and javascript) i saved my python script in the same directory as the html but when i click the button there is not response,
this is my python script
num1 = int(sys.argv[1])
num2 = int(sys.argv[2])
result = num1 + num2
print(str(result))
and this is the html part
<html>
<head>
<meta charset="UTF-8">
<title>My Tauri App</title>
</head>
<body>
<label for="num1">Enter number 1:</label>
<input type="number" id="num1">
<label for="num2">Enter number 2:</label>
<input type="number" id="num2">
<button id="addBtn">Add Numbers</button>
<div id="result"></div>
<script>
const { spawn } = require('child_process');
const addBtn = document.getElementById('addBtn');
const num1Input = document.getElementById('num1');
const num2Input = document.getElementById('num2');
const resultDiv = document.getElementById('result');
addBtn.addEventListener('click', () => {
const num1 = parseInt(num1Input.value);
const num2 = parseInt(num2Input.value);
const python = spawn('python', ['add_numbers.py', num1.toString(), num2.toString()]);
python.stdout.on('data', data => {
const result = data.toString().trim();
resultDiv.textContent = `Result: ${result}`;
});
python.stderr.on('data', error => {
console.error(error.toString());
});
});
</script>
</body>
</html>
i saved my python script in the same directory as the html but when i click the button there is not response,
I am building an app utilising Tauri, Python and React. You can spawn the python instance as a "sidecar" as they're called in the Tauri platform.
Tauri offers several ways to communicate between tauri-sidecar & tauri-react frontend.
You may find documentation on embedding binaries as a sidecar to the Tauri app here; https://tauri.app/v1/guides/building/sidecar/
Once you build your python script into a standalone executable using PyInstaller, you can place it in your project folder, and then initiate that as a sidecar executable.
Once you initiate the sidecar; at the very simplest, you can listen to the stdout of the python executable, from the tauri app.
let (mut rx, mut child) = Command::new_sidecar("pythonexecutablename")
.expect("failed to create `pythonexecutablename` binary command")
.spawn()
.expect("Failed to spawn sidecar");
tauri::async_runtime::spawn(async move {
let main_window = app.get_window("main").unwrap();
while let Some(event) = rx.recv().await {
if let CommandEvent::Stdout(line) = event {
println!("Output from sidecar command: {}", line);
if line.contains("MESSAGE:STARTED") {
main_window
.emit("sidecar-ready", Some(()))
.expect("failed to emit event");
}
main_window
.emit("message", Some(format!("'{}'", line)))
.expect("failed to emit event");
child.write("message from Rust\n".as_bytes()).unwrap();
}
}
});
In a similar fashion, you can also communicate between the React app and the Tauri app as well.
import { emit, listen } from "@tauri-apps/api/event";
import { invoke } from "@tauri-apps/api/tauri";
invoke("is_app_ready").then((message) => {
console.log("RN - tauri app responded : ", message);
if (message === true) {
// Call listenUp when sidecar is ready
initiateListening();
} else {
const handler = listen("sidecar-ready", (event) => {
initiateListening();
});
}
});
I personally wouldn't depend heavily on the specialised communication interface provided by the Tauri API, because you never know when you may switch your UI layer, or have another user interface for the backend, so once I complete the initialisation and initial handshake, I start an SSE endpoint (server-side sent events) directly to the python backend. Then listen to that from the react app.
There is also now tauri-plugin-python to run python code in the tauri backend. This doesn't spawn a new python process on each click but creates a RustPython / PyO3 python interpreter in tauri, which then parses and executes the python code during runtime. The python process doesn't end on each click, so you can also use persistent globals in your python code.
This mostly simplifies python usage in tauri. You don't need to touch any rust code anymore, you just need to have rust&npm installed so you can compile your tauri app. To create a new tauri project using python, you can just use the tauri cli to add the python interpreter.
npm create tauri-app@latest #make sure you use tauri 2
cd tauri-app
npx @tauri-apps/cli add python
# modify src/index.html and add src-tauri/src-python/main.py
npm install
npm run tauri dev
<!-- src/index.html -->
<html>
<head>
<meta charset="UTF-8">
<title>My Tauri App</title>
</head>
<body>
<label for="num1">Enter number 1:</label>
<input type="number" id="num1">
<label for="num2">Enter number 2:</label>
<input type="number" id="num2">
<button id="addBtn">Add Numbers</button>
<div id="result"></div>
<script>
// this should be moved to a main.js file
const tauri = window.__TAURI__;
let num1Input;
let num2Input;
let resultDiv;
async function add_numbers() {
let num1 = parseInt(num1Input.value);
let num2 = parseInt(num2Input.value);
resultDiv.textContent = `Result: ` + await tauri.python.callFunction("add_numbers", [num1, num2]);
}
window.addEventListener("DOMContentLoaded", () => {
num1Input = document.querySelector("#num1");
num2Input = document.querySelector("#num2");
resultDiv = document.querySelector("#result");
document.querySelector("#addBtn").addEventListener("click", (e) => {
add_numbers();
e.preventDefault();
});
});
</script>
</body>
</html>
# src-tauri/src-python/main.py
_tauri_plugin_functions = ["add_numbers"] # allow function(s) to be callable from UI
print("initialized python")
def add_numbers(num1, num2):
result = str(num1 + num2)
print(result)
return "from python: " + result
Disclaimer: I am the author of the python plugin.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With