Skip to content

Commit de5cb78

Browse files
committed
read python variable with "." notation & make it possible to register js function without server invokation
1 parent d999aa1 commit de5cb78

3 files changed

Lines changed: 45 additions & 18 deletions

File tree

examples/plain-javascript/src/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ async function greet_rust() {
99
outputEl.textContent = await invoke("greet_rust", { name: inputField.value });
1010
}
1111
async function greet_python() {
12-
outputEl.textContent = await tauri.python.call.greet_python( inputField.value );
12+
outputEl.textContent = await tauri.python.call.greet_python(inputField.value);
1313
}
1414

1515
window.addEventListener("DOMContentLoaded", () => {

guest-js/index.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@ export async function runPython(code: string): Promise<string> {
1919
}
2020

2121
/**
22+
* Regeisters function on server and makes it available via `call.{jsFunctionName}`
2223
* @param {string} pythonFunctionCall - The python function call, can contain one dot
2324
* @param {number} [numberOfArgs] - Number of arguments, used for validation in pythons, use -1 to ignore this value
2425
* @param {string} [jsFunctionName] - Name that is used in javscript: "call.jsFunctionName". Must not contain dots.
2526
*/
26-
export async function registerFunction(pythonFunctionCall: string, numberOfArgs?: number, jsFunctionName?: string): Promise<string> {
27-
if (jsFunctionName === undefined) {
28-
jsFunctionName = pythonFunctionCall;
29-
}
27+
export async function registerFunction(
28+
pythonFunctionCall: string,
29+
numberOfArgs?: number,
30+
jsFunctionName?: string): Promise<string> {
3031
if (numberOfArgs !== undefined && numberOfArgs < 0) {
3132
numberOfArgs = undefined;
3233
}
@@ -35,29 +36,50 @@ export async function registerFunction(pythonFunctionCall: string, numberOfArgs?
3536
pythonFunctionCall,
3637
numberOfArgs
3738
},
38-
}).then((r:any) => {
39-
call[jsFunctionName] = function (...args: any[]) { return callFunction(pythonFunctionCall, args) };
39+
}).then((r: any) => {
40+
registerJsOnly(pythonFunctionCall, jsFunctionName);
4041
return r.value;
4142
});
4243
}
4344

45+
46+
47+
/**
48+
* No server invokation - assumes that function has already been registered server-side
49+
* Makes function available as `call.{jsFunctionName}`
50+
* @param {string} pythonFunctionCall - The python function call, can contain one dot
51+
* @param {string} [jsFunctionName] - Name that is used in javscript: "call.jsFunctionName". Must not contain dots.
52+
*/
53+
export async function registerJsOnly(pythonFunctionCall: string, jsFunctionName?: string) {
54+
if (jsFunctionName === undefined) {
55+
jsFunctionName = pythonFunctionCall.replace(".", "_");
56+
}
57+
call[jsFunctionName] = function (...args: any[]) { return callFunction(pythonFunctionCall, args) };
58+
}
59+
60+
/**
61+
* calling previously registered function
62+
*/
4463
export async function callFunction(functionName: string, args: any[]): Promise<string> {
4564
return invoke<{ value: string }>('plugin:python|call_function', {
4665
payload: {
4766
functionName,
4867
args,
4968
},
50-
}).then((r:any) => {
69+
}).then((r: any) => {
5170
return r.value;
5271
});
5372
}
5473

74+
/**
75+
* read variable name directly from python
76+
*/
5577
export async function readVariable(value: string): Promise<string> {
5678
return invoke<{ value: string }>('plugin:python|read_variable', {
5779
payload: {
5880
value,
5981
},
60-
}).then((r:any) => {
82+
}).then((r: any) => {
6183
return r.value;
6284
});
6385
}

src/py_lib.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,20 @@ pub fn call_function(payload: RunRequest) -> PyResult<Py<PyAny>> {
117117
pub fn read_variable(payload: StringRequest) -> PyResult<String> {
118118
marker::Python::with_gil(|py| -> PyResult<String> {
119119
let globals = GLOBALS.lock().unwrap().clone_ref(py).into_bound(py);
120-
match globals.get_item(&payload.value) {
121-
Ok(opt_res) => match opt_res {
122-
Some(res) => Ok(res.to_string()),
123-
_ => Err(pyo3::exceptions::PyException::new_err(format!(
124-
"{} not set",
125-
payload.value
126-
))),
127-
},
128-
Err(err) => Err(err),
120+
121+
let var_dot_split: Vec<&str> = payload.value.split(".").collect();
122+
let var = globals.get_item(&var_dot_split[0])?;
123+
if let Some(var) = var {
124+
if var_dot_split.len() > 1 {
125+
Ok(var.getattr(var_dot_split.get(1).unwrap())?.to_string())
126+
} else {
127+
Ok(var.to_string())
128+
}
129+
} else {
130+
Err(pyo3::exceptions::PyException::new_err(format!(
131+
"{} not set",
132+
&payload.value
133+
)))
129134
}
130135
})
131136
}

0 commit comments

Comments
 (0)