首页 > 编程问答 >在 Rust 中嵌入 Python 来调用外部 Python 库

在 Rust 中嵌入 Python 来调用外部 Python 库

时间:2024-08-09 04:28:24浏览次数:17  
标签:python rust

我正在尝试学习如何将 Python 嵌入到 Rust 应用程序中。出于学习目的,我想创建一个运行永远循环的 Rust 脚本/应用程序。该循环会休眠设定的时间间隔,醒来后,它使用 Python requests 库从互联网时间服务器获取当前时间。虽然这不是一个实际应用程序,但我的目标是了解如何从 Rust 调用外部 Python 库。

我的最终目标是看看是否可以将 Python BACnet 堆栈集成到 Rust 应用程序中。

我的设置

  • main.rs
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
use std::thread;
use std::time::Duration;

fn main() -> PyResult<()> {
    // Safely acquire the GIL and run the Python code
    Python::with_gil(|py| {
        // Print the version of Python being used
        py.run("import sys; print('Python version:', sys.version)", None, None)?;

        // Import the requests library in Python
        let requests = py.import("requests")?;

        loop {
            // Sleep for 10 seconds
            thread::sleep(Duration::from_secs(10));

            // Execute the Python code to get the current time from a time server
            let locals = [("requests", requests)].into_py_dict(py);
            let time_response: String = py.eval(
                r#"
                import requests
                response = requests.get('http://worldtimeapi.org/api/timezone/Etc/UTC')
                response.json()['datetime']
                "#,
                None,
                Some(locals)
            )?.extract()?;

            // Print the time received from the server
            println!("Current UTC Time: {}", time_response);
        }

        Ok(())
    })
}
  • Cargo.toml
[package]
name = "rust_python_time_fetcher"
version = "0.1.0"
edition = "2021"

[dependencies]
pyo3 = { version = "0.21.2", features = ["extension-module"] }

[build-dependencies]
pyo3-build-config = "0.21.2"
  • build_with_python.sh
#!/bin/bash

# Activate the virtual environment
source env/bin/activate

# Get the path to the Python interpreter
PYTHON=$(which python3)

# Get the Python version
PYTHON_VERSION=$($PYTHON -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')")

# Set the path to the Python interpreter
export PYO3_PYTHON="$PYTHON"

# Set the paths for Python libraries and include files
export LD_LIBRARY_PATH="$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))"):$LD_LIBRARY_PATH"
export LIBRARY_PATH="$($PYTHON -c "import sysconfig; print(sysconfig.get_config_var('LIBDIR'))"):$LIBRARY_PATH"
export PYTHONPATH="$($PYTHON -c "import site; print(site.getsitepackages()[0])"):$PYTHONPATH"

# Include and lib directories might vary based on how Python was installed or the distro specifics
export CFLAGS="$($PYTHON -c "import sysconfig; print('-I' + sysconfig.get_paths()['include'])")"
export LDFLAGS="$($PYTHON -c "import sysconfig; print('-L' + sysconfig.get_config_var('LIBDIR'))")"

# Now try running Cargo build again
cargo build

# Print Python version and path
$PYTHON --version
which $PYTHON

# Print Python includes and libs
$PYTHON-config --includes
$PYTHON-config --libs

问题

当我尝试使用 Cargo build 构建项目时,遇到以下错误:

> cargo build
   Compiling pyo3-build-config v0.21.2
error: failed to run custom build command for `pyo3-build-config v0.21.2`                                                     

Caused by:
  process didn't exit successfully: `C:\Users\bbartling\Desktop\rust_python_time\target\debug\build\pyo3-build-config-6b34c9835096c15d\build-script-build` (exit code: 1)
  --- stdout
  cargo:rerun-if-env-changed=PYO3_CONFIG_FILE
  cargo:rerun-if-env-changed=PYO3_NO_PYTHON
  cargo:rerun-if-env-changed=PYO3_ENVIRONMENT_SIGNATURE
  cargo:rerun-if-env-changed=PYO3_PYTHON
  cargo:rerun-if-env-changed=VIRTUAL_ENV
  cargo:rerun-if-env-changed=CONDA_PREFIX
  cargo:rerun-if-env-changed=PATH

  --- stderr
  error: no Python 3.x interpreter found

我遇到了什么尝试过

我创建了一个 build_with_python.sh 在rasp pi上运行的脚本来正确设置环境,包括激活虚拟环境并设置Python库和包含文件的必要路径。但是,我仍然面临同样的错误。

问题

  • 如何正确配置我的 Rust 项目以识别和使用虚拟环境中的 Python 解释器和库?
  • 我需要执行任何其他步骤吗如何确保 pyo3 crate 可以找到并使用 Python 解释器?

在 Cargo 构建过程中遇到的错误“error: no Python 3.x interpreter found”表示 pyo3-build-config crate 无法找到的 Python 解释器。即使在 build_with_python.sh 脚本中设置了虚拟环境,这种情况也会发生,因为它没有以 pyo3-build-config 使用的方式传递环境。

可以通过几种方法来解决此问题:

1. 使用 PYO3_PYTHON 环境变量

这是推荐的方法。可以在运行 Cargo 命令之前设置 PYO3_PYTHON 环境变量来指定要使用的 Python 解释器。

export PYO3_PYTHON="/path/to/your/virtualenv/bin/python" 
cargo build

确保将 /path/to/your/virtualenv/bin/python 替换为的虚拟环境中 Python 解释器的实际路径。

2. 在 pyo3/build.rs 文件中设置解释器

如果的项目需要更精细地控制 Python 解释器的选择,可以在项目根目录中创建一个 pyo3/build.rs 文件。在这个文件中,可以使用 pyo3_build_config crate 提供的函数来设置解释器。

use pyo3_build_config::InterpreterConfig;

fn main() {
    let mut cfg = InterpreterConfig::new();
    cfg.interpreter_path("/path/to/your/virtualenv/bin/python")
        .unwrap();
    cfg.write_pyo3_config("pyo3").unwrap();
}

同样,将 /path/to/your/virtualenv/bin/python 替换为的 Python 解释器的实际路径。

关于 build_with_python.sh 脚本

不需要使用单独的脚本设置环境变量。可以直接在运行 Cargo 命令之前设置它们,或者将它们添加到的 .bashrc .zshrc 文件中以永久设置它们。

其他建议

  • 确保的虚拟环境已激活,并且可以从终端运行 python 命令来启动正确的解释器。
  • 可以使用 which python 命令检查当前使用的 Python 解释器的路径。
  • 可以查看 pyo3 crate 的文档以获取有关配置和使用的更多信息:https://pyo3.rs/v0.21.2/building_and_distribution.html

通过这些方法之一设置 Python 解释器后,的 Cargo 构建应该可以成功找到并链接到想要的 Python 解释器和库。

标签:python,rust
From: 78500757

相关文章

  • 如何从我的 Python 应用程序更新我的 Facebook Business 令牌?
    我有一个使用FacebookBusiness库的Python应用程序。因此,我需要使用Facebook提供的令牌来访问我的见解并操纵它们。但是,这个令牌有一个很长的到期日期,但我想知道是否有办法自动更新这个令牌在我的应用程序中,这样它就不会停止运行。当然可以!你可以使用Facebook提......
  • 哪种编程语言更适合学习数据结构和算法:C++、Java 还是 Python?
    作为一名工程专业的学生,​​我正在尝试决定使用哪种编程语言来学习数据结构和算法(DSA)。我正在考虑C++,它提供高性能和强大的标准模板库,但对于初学者来说可能很复杂。Java具有强大的语法和内置集合,使DSA概念更容易掌握,尽管我不确定它与C++相比的性能。Python以其简单性和......
  • 同时运行多个异步阻塞函数 - Python
    我是Python和协程的新手,我正在尝试利用Python的asyncio库来并行处理阻塞函数。我正在使用python3.8.6。我有一个阻塞函数,它从数组输入中接收不同的输入,我需要每个输入的阻塞函数同时运行。我已经尝试过,但它们似乎仍然按顺序运行:asyncdefmain():tasks=[asyncio......
  • 使用两个连接的字符串调用变量 Python
    抱歉缺乏细节,因为我是python的初学者:c1=c2=c3=c4=c5=Falsex=int(input("Enteranumber1-5:"))ifx>5orx<1:print("Yournumbermustbebetween1and5")else:"c",x=True第8行是连接2个字符串的地方。我不确定......
  • 测试Python中是否存在可执行文件?
    在Python中,有没有一种可移植且简单的方法来测试可执行程序是否存在?简单我的意思是类似which命令的东西,这将是完美的。我不想手动搜索PATH或涉及尝试使用Popen&al执行它并查看它是否失败(这就是我现在正在做的事情,但想象它是launchmissiles)......
  • Python 和 Excel:将数据放入另一个函数中,然后从中获取信息
    我正在尝试将温度/压力数据放入蒸汽表以获得过热焓数据。我已经成功地获取了数据并将其放入Excel文件中,然后它为我提取了焓数据。问题是,当我将温度和压力数据放入蒸汽表时,它实际上并没有进行双重插值,因此焓(H)值实际上从未改变ng。我最终只得到了蒸汽数据中给出......
  • Python 类型提示:显式排除无效的重载组合?
    我有一个带有两个参数的函数,每个参数都可以采用两种类型之一。四个成对组合中的三个有效,但第四个无效。我想找到一种方法来键入提示此场景,可以检查这些类型,但不一定每次调用foo()时都必须编写代码来检查无效情况。有没有办法可以改进foo()、bar()或两......
  • 我在制作 python 语音应用程序时遇到错误
    我编写了一个语音聊天应用程序代码,但是当我们运行此代码并加入语音频道时,我收到照片中的错误错误1错误2这是我的代码;客户端代码:importtkinterastkfromtkinterimportmessageboximportpyaudioimportsocketimportthreadingimporttimeHOST=......
  • pyocr,一个超酷的Python库!
    pyocr是一个用于光学字符识别(OCR)的Python库,它提供了一个简单的接口,允许开发者将图片中的文本提取出来。这个库是对Tesseract-OCR的封装,使得在Python环境中使用OCR技术变得更加便捷。如何安装pyocr首先,要使用pyocr库,您需要安装它。可以使用pip包管理工具来进......
  • pattern,一款超牛的Python库
    在程序开发中,处理文本数据和进行自然语言处理是常见需求。pattern是一个强大的Python库,专为文本分析而设计,提供了丰富的功能,包括自然语言处理、数据挖掘和网络分析等。它简单易用,让程序员能够快速实现复杂的文本处理任务。如何安装pattern在开始使用pattern库之前,首先......