我正在尝试学习如何将 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