Tauri Plugin Python

repository·main·Indexed 41 days ago

https://github.com/marcomq/tauri-plugin-python

A plugin for Tauri v2 that allows developers to use Python as a backend. It supports both full CPython via PyO3 for library compatibility (e.g., numpy, pandas) and a lightweight Rust-based interpreter via RustPython for single-binary deployment. The plugin provides a bridge between the Rust-based Tauri core and Python logic, enabling Python functions to be called from the JavaScript frontend.

Tokens
8.8K
Snippets
31
Records
47
Agent score
48%

What's inside Tauri Plugin Python

  1. Choosing an interpreter: PyO3 vs. RustPython

    main

    The plugin supports two backends. Choosing the right one depends on your compatibility and deployment requirements.

    PyO3 / CPython (Default)

    • Pros: Full library compatibility (supports C extensions like numpy, pandas); fast performance.
    • Cons: Requires libpython to be available on the target machine; more complex deployment.
    • Best for: Applications requiring heavy data science libraries or complex Python ecosystems.

    RustPython

    • Pros: Trivial deployment (single self-contained binary); no Python installation required on the target.
    • Cons: Limited compatibility (pure-Python only); missing/incomplete standard library modules; slower performance.
    • Best for: Simple logic, fast prototyping, or when a single binary is a priority.
  2. Security considerations for Tauri Plugin Python

    main

    By default, the plugin is restricted to prevent arbitrary code execution:

    • Function Registration: Python functions can only be called if they are registered from Rust during plugin initialization.
    • runPython command: This command (which allows injecting Python code directly via JavaScript) is disabled by default via permissions.
    • register command: This command (which allows adding new callable functions from JavaScript) is disabled by default.

    Recommendation: Ensure your user interface is not accessible via a network URL in production to prevent unauthorized code injection.

  3. Quick Start with the Plain JavaScript Example

    main

    To run the provided Vanilla JavaScript example, follow these steps in order:

    1. Prerequisites: Ensure you have rust, python, and nodeJs installed.
    2. Base Setup: Navigate to the project root and install/build the plugin dependencies:
      cd ../../
      npm install
      npm run build
    3. Example Setup: Navigate to the example directory and start the app:
      cd examples/plain-javascript
      npm install
      npm run tauri dev

    To run on iOS:

    1. Initialize the iOS project files:
      npx @tauri-apps/cli plugin ios init
    2. Start the application in development mode:
      npm run tauri ios dev
    # Base path setup
    cd ../../
    npm install
    npm run build
    
    # Example path setup
    cd examples/plain-javascript
    npm install
    npm run tauri dev
  4. Debug Python call errors in the frontend

    main

    When a Python call fails, the plugin returns the error as a rejected promise. You should wrap your calls in a try...catch block to capture the Python error message or traceback.

    In development builds (tauri dev), the plugin also prints the full Python traceback to stderr, prefixed with [tauri-plugin-python]. In release builds, errors are not logged to the terminal to prevent leaking information to end users.

    try {
      await call.greet_python("input value");
    } catch (err) {
      console.error(err); // contains the Python error message / traceback
    }
  5. Deploying PyO3 with libpython

    main

    Since PyO3 uses a shared libpython by default, deployment requires providing the library on the target machine.

    Recommended Approaches:

    1. Ship the venv: Include the .venv folder as a Tauri resource so libpython is bundled with your app.
    2. Static Embedding: Use PyOxidizer to embed libpython statically into your binary.

    Example: Static Embedding with PyOxidizer:

    1. Install: pip install pyoxidizer.
    2. Generate artifacts: pyoxidizer generate-python-embedding-artifacts src-tauri/target/pyembed.
    3. Update Cargo config to point to the generated file:
    # src-tauri/.cargo/config.toml
    PYO3_CONFIG_FILE = { value = "target/pyembed/pyo3-build-config-file.txt", relative = true }
    pyoxidizer generate-python-embedding-artifacts src-tauri/target/pyembed
    # src-tauri/.cargo/config.toml
    PYO3_CONFIG_FILE = { value = "target/pyembed/pyo3-build-config-file.txt", relative = true }
  6. Manually add the Python Plugin to an existing Tauri application

    main

    If you are not using the provided template, follow these steps to integrate the Python plugin into your Tauri project:

    1. Rust Dependencies: Add tauri-plugin-python to your Cargo.toml.
    2. JavaScript Dependencies: Add tauri-plugin-python-api to your package.json.
    3. Permissions: In src-tauri/capabilities/default.json, update the permissions array to include "python:default".
    4. Python Logic: Define your Python functions in src-tauri/src-python/main.py (e.g., def greet_python(...):).
    5. Plugin Initialization: In src-tauri/src/lib.rs, initialize the plugin with your exported functions:
      .plugin(tauri_plugin_python::init(["greet_python"]))
    6. Frontend Integration:
      • Include the plugin script in your index.html:
        <script type="module" src="/tauri-plugin-python-api/index.iife.js" defer></script>
      • Register the Python functions in your JavaScript code:
        registerJs("greet_python");
      • Call the functions using the call object:
        call.greet_python(...args);
    // src-tauri/src/lib.rs
    .plugin(tauri_plugin_python::init(["greet_python"]))
    <!-- index.html -->
    <script type="module" src="/tauri-plugin-python-api/index.iife.js" defer></script>
    // JavaScript usage
    registerJs("greet_python");
    call.greet_python(...args);
  7. Quick start with Tauri Plugin Python (PyO3)

    main

    To quickly integrate Python into an existing Tauri v2 application using the default PyO3 backend, follow these steps:

    1. Install the plugin: Run npm run tauri add python.
    2. Create your Python logic: Create src-tauri/src-python/main.py. You must define the _tauri_plugin_functions list to make functions callable from the UI.
    3. Configure bundling: Add the Python directory to your tauri.conf.json resources so it is included in the production build.
    4. Call from Frontend: Use callFunction from tauri-plugin-python-api to invoke your Python functions.
    npm run tauri add python
    # src-tauri/src-python/main.py
    _tauri_plugin_functions = ["greet_python"]
    
    def greet_python(name):
        return f"Hello {name} from Python"
    // tauri.conf.json
    "bundle": { "resources": ["src-python/"] }
    import { callFunction } from 'tauri-plugin-python-api'
    console.log(await callFunction("greet_python", ["world"])) // "Hello world from Python"
  8. Deploy Python resources in Tauri

    main

    The file src-python/main.py is required. All Python files must be included in the Tauri resource configuration (tauri.conf.json). Your bundled resource layout must mirror your local layout so that Python imports resolve correctly.

    You can define resources as a list or a source→target map in tauri.conf.json:

    "bundle": { "resources": ["src-python/"] }
    "bundle": {
      "resources": ["src-python/"]
    }
  9. Deploying with PyO3 / CPython

    main

    PyO3 requires a libpython to be available at runtime. The plugin does not have a setting to point to a Python installation; instead, the OS dynamic loader finds libpython via standard search paths (rpath, LD_LIBRARY_PATH, etc.) based on how the plugin was linked at build time.

    Deployment Options

    1. Ship the shared libpython: Identify which version your binary is linked against (using otool -L on macOS or ldd on Linux) and bundle that library next to your executable.
    2. Build against an embeddable Python: Use a standalone Python distribution (like python-build-standalone) at build time via PYO3_CONFIG_FILE, then bundle that Python as a resource.

    Note: Bundling a venv (src-python/.venv) only adds site-packages to sys.path; it does not provide libpython.

  10. Manual installation of Tauri Plugin Python

    main

    If you prefer not to use the tauri add command, you can install the plugin manually:

    1. Add Rust dependency: $ cargo add tauri-plugin-python.
    2. Add JS dependency: $ npm install tauri-plugin-python-api.
    3. Configure Permissions: Add "python:default" to the permissions array in src-tauri/capabilities/default.json.
    4. Initialize in Rust: In src-tauri/src/lib.rs, add .plugin(tauri_plugin_python::init_and_register(vec!["your_function_name"])) to your tauri::Builder.
    5. Frontend Usage:
      • For modern JS: Use import { call, registerJs } from 'tauri-plugin-python-api'.
      • For Vanilla JS: Access via window.__TAURI__.python.
    // src-tauri/src/lib.rs
    tauri::Builder::default()
        .plugin(tauri_plugin_python::init_and_register(vec!["greet_python"]))
    import { call, registerJs } from 'tauri-plugin-python-api'
    registerJs("greet_python");
    console.log(await call.greet_python("input value"));