Skip to content

Commit c5b8536

Browse files
authored
Merge pull request #2 from marcomq/rustpython
Using Rustpython instead of Pyo3 for easier android / ios deployment
2 parents 90229ab + 81d5d06 commit c5b8536

18 files changed

Lines changed: 434 additions & 189 deletions

File tree

Cargo.toml

Lines changed: 14 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,20 @@ 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+
# default = ["pyo3"] # enable to use pyo3 instead of rustpython
35+
pyo3 = ["dep:pyo3"]

README.md

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,66 @@
11
# Tauri Plugin Python
22

33
This [tauri](https://v2.tauri.app/) plugin is supposed to make it easy to use Python as backend code.
4-
It uses [PyO3](https://pyo3.rs) to call python from rust.
4+
It uses [RustPython](https://github.com/RustPython/RustPython) as interpreter to call python from rust.
5+
RustPython doesn't require python to be installed on the target platform and makes it
6+
therefore easy to deploy your production binary. Unfortunately, it has some
7+
compatibility issues and is slower than PyO3/CPython. [PyO3](https://pyo3.rs) is also supported as optional Cargo feature for desktop applications.
8+
PyO3 uses CPython as interpreter and therefore has a much better compatibility for python libraries.
9+
It isn't used as default as it requires to make libpython available for the target platform,
10+
which can be complicated, especially for mobile targets.
11+
512
The plugin reads by default the file `src-tauri/src-python/main.py` during
6-
startup and runs it immediately. Python functions are then registered during initialization
13+
startup and runs it immediately. Make sure to add all your python source as tauri resource,
14+
so it is shipped together with your productioon binaries. Python functions are all registered during plugin initialization
715
and can get called during application workflow.
816

917

1018
| Platform | Supported |
1119
| -------- | --------- |
1220
| Linux ||
1321
| Windows ||
14-
| macOS ||
15-
| Android | not yet |
16-
| iOS | not yet |
22+
| MacOS ||
23+
| Android | not yet |
24+
| iOS |* |
25+
26+
`*` Linux, Windows and MacOS support PyO3 and RustPython as interpreter. Android and IOS
27+
currently only supports RustPython.
28+
Android and iOS might also be able to run PyO3 in theory but require to have CPython
29+
to be compiled for the target platform. I still need to figure out how to
30+
cross compile python and PyO3 for iOS and Android. Ping me if you know how to do that.
1731

1832
You can use this plugin for fast prototypes or for production code.
1933
It might be possible that you want to use some python library or code that
2034
is not available for rust yet.
2135
In case that you want to ship production software packages, you just need
22-
to make sure to also ship the python code and python interpreter.
23-
24-
Android and iOS are possible in theory but I still need to figure out how to
25-
cross compile python and PyO3 for iOS and android.
26-
27-
Also, this plugin hasn't been optimized yet for production binaries.
28-
The target platform therefore either needs to have libpython installed
29-
or you manually need to ship the shared libs together with the installer package.
36+
to make sure to also ship the python code. If you use PyO3, you also need to ship libpython too.
3037

3138
## Example app
3239

3340
There is a sample Desktop application for Windows/Linux/MacOS using this plugin and vanilla
34-
Javascript in [examples/plain-javascript](https://github.com/marcomq/tauri-plugin-python/tree/main/examples/plain-javascript)
41+
Javascript in [examples/plain-javascript](https://github.com/marcomq/tauri-plugin-python/tree/main/examples/plain-javascript).
42+
43+
44+
## Add the plugin to an existing tauri application
3545

36-
## Manual plugin installation / usage
3746

3847
These steps assume that you already have a basic tauri application available. Alternatively, you can immediately start with the example application.
3948

49+
- run `npm run tauri add python`
50+
- add `src-tauri/src-python/main.py` and modify it acording to your needs, for example add `def greet_python(intput): return str(input) + " from python"`
51+
- modify `src-tauri/src/lib.rs` and change `.plugin(tauri_plugin_python::init())` to `.plugin(tauri_plugin_python::init(["greet_python"]))`; make sure you list all python functions you
52+
want to call
53+
- add `"bundle": {"resources": [ "src-python/**/*"],` to `tauri.conf.json` so that python files are bundled with your application
54+
- add the plugin in your js, so
55+
- add `import { callFunction } from 'tauri-plugin-python-api'`
56+
- add `outputEl.textContent = await callFunction("greet_python", [value])` to get the output of the python function `greet_python` with parameter of js variable `value`
57+
58+
Check the examples for alternative function calls and code sugar.
59+
60+
Tauri events and calling js from python is currently not supported yet. You would need to use rust for that.
61+
62+
## Alternative manual plugin installation
63+
4064
- `$ cargo add tauri-plugin-python`
4165
- `$ npm install tauri-plugin-python-api`
4266
- modify `permissions:[]` in src-tauri/capabilities/default.json and add "python:default"
@@ -76,9 +100,9 @@ The included resources can be configurable in the `tauri.conf.json` file.
76100
Check the tauri and PyO3 documentation for additional info.
77101

78102
## Security considerations
79-
Generally, this plugin has been created by "security by default" concept. Python functions can only be called if registered from rust.
103+
Generally, this plugin has been created by "security by default" concept. Python functions can only be called if registered from rust during plugin initialization.
80104

81-
Keep in mind that this plugin can make it possible to run arbitrary python code.
105+
Keep in mind that this plugin could make it possible to run arbitrary python code.
82106
It is therefore highly recommended to **make sure the user interface is not accessible by a network URL** in production.
83107

84108
The "runPython" command is disabled by default via permissions. If enabled, it is possible to

examples/plain-javascript/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ and Vanilla Javascript
1010
- run `npm install` in the example path (`cd examples/plain-javascript`)
1111
- run `npm run tauri dev` to start the application
1212

13+
To run this sample app on iOS:
14+
- run `npx @tauri-apps/cli plugin ios init` to init ios project files
15+
- run `npm run tauri ios dev` to start the application on iOS in develop mode
16+
1317
## Manual modifications on default template to add plugin:
1418
- add `tauri-plugin-python` to Cargo.toml
1519
- add `tauri-plugin-python-api` to package.json
1620
- modify `permissions:[]` in src-tauri/capabilities/default.json and add "python:default"
1721
- modify `src-tauri/src-python/main.py` and add python code, for example `def greet_python(..`
18-
- add `.plugin(tauri_plugin_python::init())` to `src-tauri/src/lib.rs`
22+
- add `.plugin(tauri_plugin_python::init(["greet_python"]))` to `src-tauri/src/lib.rs`
1923
- include javascript for python plugin in the index.html file for example by adding `<script type="module" src="/tauri-plugin-python-api/index.iife.js" defer></script>`
20-
- register python functions in javascript by calling `registerFunction("greet_python");`
24+
- register python functions in javascript by calling `registerJs("greet_python");`
2125
- calling python function by calling `call.greet_python(...)`
2226

2327
## Recommended IDE Setup

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",

ios/.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
/*.xcodeproj
5+
xcuserdata/
6+
DerivedData/
7+
.swiftpm/config/registries.json
8+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
9+
.netrc
10+
Package.resolved

ios/Package.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// swift-tools-version:5.3
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "tauri-plugin-python",
8+
platforms: [
9+
.macOS(.v10_13),
10+
.iOS(.v13),
11+
],
12+
products: [
13+
// Products define the executables and libraries a package produces, and make them visible to other packages.
14+
.library(
15+
name: "tauri-plugin-python",
16+
type: .static,
17+
targets: ["tauri-plugin-python"]),
18+
],
19+
dependencies: [
20+
.package(name: "Tauri", path: "../.tauri/tauri-api")
21+
],
22+
targets: [
23+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
24+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
25+
.target(
26+
name: "tauri-plugin-python",
27+
dependencies: [
28+
.byName(name: "Tauri")
29+
],
30+
path: "Sources")
31+
]
32+
)

ios/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Tauri Plugin python
2+
3+
A description of this package.

ios/Sources/ExamplePlugin.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import SwiftRs
2+
import Tauri
3+
import UIKit
4+
import WebKit
5+
6+
class PingArgs: Decodable {
7+
let value: String?
8+
}
9+
10+
class ExamplePlugin: Plugin {
11+
}
12+
13+
@_cdecl("init_plugin_python")
14+
func initPlugin() -> Plugin {
15+
return ExamplePlugin()
16+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import XCTest
2+
@testable import ExamplePlugin
3+
4+
final class ExamplePluginTests: XCTestCase {
5+
func testExample() throws {
6+
let plugin = ExamplePlugin()
7+
}
8+
}

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
},

0 commit comments

Comments
 (0)