Skip to content

Commit 9fef457

Browse files
committed
add rustpython
1 parent c480d14 commit 9fef457

11 files changed

Lines changed: 299 additions & 150 deletions

File tree

Cargo.toml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "tauri-plugin-python"
3-
version = "0.2.1"
3+
version = "0.3.0"
44
authors = [ "Marco Mengelkoch" ]
55
description = "A tauri 2 plugin to use python code in the backend."
66
keywords = ["rust", "python", "tauri", "gui"]
@@ -16,8 +16,19 @@ repository = "https://github.com/marcomq/tauri-plugin-python"
1616
tauri = { version = "2" }
1717
serde = { version = "1", features = ["derive"] }
1818
thiserror = "2"
19-
pyo3 = { version = "0.23.3", features=["auto-initialize", "abi3-py39", "generate-import-lib"] }
2019
lazy_static = "1.5.0"
20+
pyo3 = { version = "0.23.3", features=["auto-initialize", "abi3-py39", "generate-import-lib"], optional = true }
21+
rustpython-pylib = { version = "0.4.0" }
22+
rustpython-stdlib = { version = "0.4.0", features = ["threading"] }
23+
rustpython-vm = { version = "0.4.0", features = [
24+
"importlib",
25+
"serde",
26+
"threading",
27+
] }
28+
serde_json = "1.0.136"
2129

2230
[build-dependencies]
2331
tauri-plugin = { version = "2", features = ["build"] }
32+
33+
[features]
34+
pyo3 = ["dep:pyo3"]

examples/plain-javascript/src-tauri/tauri.conf.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
"bundle": {
2323
"active": true,
2424
"targets": "all",
25+
"resources": [
26+
"src-python/**/*"
27+
],
2528
"icon": [
2629
"icons/32x32.png",
2730
"icons/128x128.png",

package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "tauri-plugin-python-api",
3-
"version": "0.2.1",
3+
"version": "0.3.0",
44
"author": "Marco Mengelkoch",
5-
"description": "",
5+
"description": "Javascript package for tauri 2 python plugin.",
66
"type": "module",
77
"types": "./dist-js/index.d.ts",
88
"main": "./dist-js/index.cjs",
@@ -22,6 +22,15 @@
2222
"prepublishOnly": "pnpm build",
2323
"pretest": "pnpm build"
2424
},
25+
"repository": {
26+
"type": "git",
27+
"url": "git+https://github.com/marcomq/tauri-plugin-python.git"
28+
},
29+
"license": "MIT",
30+
"homepage": "https://github.com/marcomq/tauri-plugin-python#readme",
31+
"bugs": {
32+
"url": "https://github.com/marcomq/tauri-plugin-python/issues"
33+
},
2534
"dependencies": {
2635
"@tauri-apps/api": ">=2.0.0-beta.6"
2736
},

src/commands.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,26 @@ pub(crate) async fn run_python<R: Runtime>(
1414
app: AppHandle<R>,
1515
payload: StringRequest,
1616
) -> Result<StringResponse> {
17-
app.python().run_python(payload)
17+
app.run_python(payload)
1818
}
1919
#[command]
2020
pub(crate) async fn register_function<R: Runtime>(
2121
app: AppHandle<R>,
2222
payload: RegisterRequest,
2323
) -> Result<StringResponse> {
24-
app.python().register_function(payload)
24+
app.register_function(payload)
2525
}
2626
#[command]
2727
pub(crate) async fn call_function<R: Runtime>(
2828
app: AppHandle<R>,
2929
payload: RunRequest,
3030
) -> Result<StringResponse> {
31-
app.python().call_function(payload)
31+
app.call_function(payload)
3232
}
3333
#[command]
3434
pub(crate) async fn read_variable<R: Runtime>(
3535
app: AppHandle<R>,
3636
payload: StringRequest,
3737
) -> Result<StringResponse> {
38-
app.python().read_variable(payload)
38+
app.read_variable(payload)
3939
}

src/desktop.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ use tauri::{plugin::PluginApi, AppHandle, Runtime};
99
use crate::py_lib;
1010

1111
/// Access to the python plugin APIs.
12+
pub struct Python<R: Runtime>(AppHandle<R>);
1213

1314
pub fn init<R: Runtime, C: DeserializeOwned>(
1415
app: &AppHandle<R>,
1516
_api: PluginApi<R, C>,
16-
) -> crate::Result<crate::Python<R>> {
17-
py_lib::init_python()?;
18-
Ok(crate::Python(app.clone()))
17+
) -> crate::Result<Python<R>> {
18+
py_lib::init_python().unwrap();
19+
Ok(Python(app.clone()))
1920
}

src/error.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Licensed under MIT License, see License file for more details
44
// git clone https://github.com/marcomq/tauri-plugin-python
55

6+
#[cfg(feature = "pyo3")]
67
use pyo3::PyErr;
78
use serde::{ser::Serializer, Serialize};
89

@@ -33,16 +34,20 @@ impl From<&str> for Error {
3334
}
3435
}
3536

36-
impl From<Error> for PyErr {
37-
fn from(error: Error) -> Self {
38-
pyo3::exceptions::PyValueError::new_err(error.to_string())
37+
#[cfg(not(feature = "pyo3"))]
38+
impl From<rustpython_vm::PyRef<rustpython_vm::builtins::PyBaseException>> for Error {
39+
fn from(error: rustpython_vm::PyRef<rustpython_vm::builtins::PyBaseException>) -> Self {
40+
let msg = format!("{:?}", &error);
41+
println!("error: {}", &msg);
42+
std::io::Error::new(std::io::ErrorKind::Other, msg).into()
3943
}
4044
}
4145

46+
#[cfg(feature = "pyo3")]
4247
impl From<PyErr> for Error {
4348
fn from(error: PyErr) -> Self {
4449
let msg = error.to_string();
45-
println!("{}", &msg);
50+
println!("error: {}", &msg);
4651
std::io::Error::new(std::io::ErrorKind::Other, msg).into()
4752
}
4853
}

src/lib.rs

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
// git clone https://github.com/marcomq/tauri-plugin-python
55

66
use tauri::{
7-
plugin::{Builder, TauriPlugin}, AppHandle, Manager, Runtime
7+
plugin::{Builder, TauriPlugin},
8+
Manager, Runtime,
89
};
910

10-
pub use models::*;
11-
1211
#[cfg(desktop)]
1312
mod desktop;
1413
#[cfg(mobile)]
@@ -17,21 +16,50 @@ mod mobile;
1716
mod commands;
1817
mod error;
1918
mod models;
19+
#[cfg(not(feature = "pyo3"))]
2020
mod py_lib;
21+
#[cfg(feature = "pyo3")]
22+
mod py_lib_pyo3;
2123

2224
pub use error::{Error, Result};
25+
use models::*;
2326

24-
pub struct Python<R: Runtime>(AppHandle<R>);
27+
#[cfg(desktop)]
28+
use desktop::Python;
29+
#[cfg(mobile)]
30+
use mobile::Python;
2531

2632
/// Extensions to [`tauri::App`], [`tauri::AppHandle`] and [`tauri::Window`] to access the python APIs.
2733
pub trait PythonExt<R: Runtime> {
2834
fn python(&self) -> &Python<R>;
35+
fn run_python(&self, payload: StringRequest) -> crate::Result<StringResponse>;
36+
fn register_function(&self, payload: RegisterRequest) -> crate::Result<StringResponse>;
37+
fn call_function(&self, payload: RunRequest) -> crate::Result<StringResponse>;
38+
fn read_variable(&self, payload: StringRequest) -> crate::Result<StringResponse>;
2939
}
3040

3141
impl<R: Runtime, T: Manager<R>> crate::PythonExt<R> for T {
3242
fn python(&self) -> &Python<R> {
3343
self.state::<Python<R>>().inner()
3444
}
45+
fn run_python(&self, payload: StringRequest) -> crate::Result<StringResponse> {
46+
py_lib::run_python(payload)?;
47+
Ok(StringResponse { value: "Ok".into() })
48+
}
49+
fn register_function(&self, payload: RegisterRequest) -> crate::Result<StringResponse> {
50+
py_lib::register_function(payload)?;
51+
Ok(StringResponse { value: "Ok".into() })
52+
}
53+
fn call_function(&self, payload: RunRequest) -> crate::Result<StringResponse> {
54+
let py_res = py_lib::call_function(payload)?;
55+
Ok(StringResponse {
56+
value: py_res.to_string(),
57+
})
58+
}
59+
fn read_variable(&self, payload: StringRequest) -> crate::Result<StringResponse> {
60+
let py_res = py_lib::read_variable(payload)?;
61+
Ok(StringResponse { value: py_res })
62+
}
3563
}
3664

3765
/// Initializes the plugin.
@@ -50,30 +78,9 @@ pub fn init<R: Runtime>(python_functions: Vec<&'static str>) -> TauriPlugin<R> {
5078
let python = desktop::init(app, api)?;
5179
app.manage(python);
5280
for function_name in python_functions {
53-
py_lib::register_function_str(function_name.into(), None)?;
81+
py_lib::register_function_str(function_name.into(), None).unwrap();
5482
}
5583
Ok(())
5684
})
5785
.build()
5886
}
59-
60-
impl<R: Runtime> Python<R> {
61-
pub fn run_python(&self, payload: StringRequest) -> crate::Result<StringResponse> {
62-
py_lib::run_python(payload)?;
63-
Ok(StringResponse { value: "Ok".into() })
64-
}
65-
pub fn register_function(&self, payload: RegisterRequest) -> crate::Result<StringResponse> {
66-
py_lib::register_function(payload)?;
67-
Ok(StringResponse { value: "Ok".into() })
68-
}
69-
pub fn call_function(&self, payload: RunRequest) -> crate::Result<StringResponse> {
70-
let py_res = py_lib::call_function(payload)?;
71-
Ok(StringResponse {
72-
value: py_res.to_string(),
73-
})
74-
}
75-
pub fn read_variable(&self, payload: StringRequest) -> crate::Result<StringResponse> {
76-
let py_res = py_lib::read_variable(payload)?;
77-
Ok(StringResponse { value: py_res })
78-
}
79-
}

src/mobile.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@ tauri::ios_plugin_binding!(init_plugin_python);
1919
pub fn init<R: Runtime, C: DeserializeOwned>(
2020
_app: &AppHandle<R>,
2121
api: PluginApi<R, C>,
22-
) -> crate::Result<crate::Python<R>> {
22+
) -> crate::Result<Python<R>> {
2323
#[cfg(target_os = "android")]
2424
let handle = api.register_android_plugin("com.plugin.python.application", "ExamplePlugin")?;
2525
#[cfg(target_os = "ios")]
2626
let handle = api.register_ios_plugin(init_plugin_python)?;
2727
py_lib::init_python()?;
28-
Ok(crate::Python(handle))
28+
Ok(Python(handle))
2929
}
30+
31+
pub struct Python<R: Runtime>(PluginHandle<R>);

src/models.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// Licensed under MIT License, see License file for more details
44
// git clone https://github.com/marcomq/tauri-plugin-python
55

6-
use pyo3::IntoPyObject;
76
use serde::{Deserialize, Serialize};
87

98
#[derive(Debug, Deserialize, Serialize)]
@@ -12,7 +11,10 @@ pub struct StringRequest {
1211
pub value: String,
1312
}
1413

15-
#[derive(Debug, Serialize, Deserialize, IntoPyObject)]
14+
#[cfg(feature = "pyo3")]
15+
#[derive(Debug, Serialize, Deserialize, pyo3::IntoPyObject)]
16+
#[cfg(not(feature = "pyo3"))]
17+
#[derive(Debug, Serialize, Deserialize)]
1618
#[serde(untagged)]
1719
pub enum JsMany {
1820
Bool(bool),
@@ -23,6 +25,9 @@ pub enum JsMany {
2325
FloatVec(Vec<f64>),
2426
}
2527

28+
#[cfg(not(feature = "pyo3"))]
29+
use serde_json::Value as JsMany;
30+
2631
#[derive(Debug, Deserialize, Serialize)]
2732
#[serde(rename_all = "camelCase")]
2833
pub struct RegisterRequest {

0 commit comments

Comments
 (0)