My goal: Create a flake.nix
with a Rust binary that will import a Python module called osc
(I want to call Python code from Rust).
My problem: Resulting Rust binary does not see a Python module. Even though it is included in the buildInputs
section. What’s even weirder, a devShell
has an identical buildInputs
section and imports osc
perfectly:
Console output
[username@host]$ nix develop
[devShell@host]$ python -c "import osc"
[devShell@host]$ nix run
["/nix/store/rgmy7k7c7yrv2f67ijdjawc66kazwrkh-python3-3.11.11", "/nix/store/rgmy7k7c7yrv2f67ijdjawc66kazwrkh-python3-3.11.11"]
Succesfully imported osc!
[devShell@host]$ exit
[username@host]$ nix run
["/nix/store/rgmy7k7c7yrv2f67ijdjawc66kazwrkh-python3-3.11.11", "/usr"]
thread 'main' panicked at src/main.rs:17:6:
called `Result::unwrap()` on an `Err` value: PyErr { type: <class 'ModuleNotFoundError'>, value: ModuleNotFoundError("No module named 'osc'"), traceback: None }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
My flake.nix file
{
description = "";
inputs = {
nixpkgs.url = "nixpkgs/nixos-24.11";
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
nixpkgs-unstable,
flake-utils,
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
pkgs-unstable = nixpkgs-unstable.legacyPackages.${system};
python = pkgs.python311;
pythonEnv = python.withPackages (
ps: with ps; [
osc
]
);
buildInputs = [
python
pythonEnv
];
in
rec {
formatter = pkgs.nixfmt-rfc-style;
devShells.default = pkgs.mkShell {
inherit buildInputs;
};
packages.default = pkgs-unstable.rustPlatform.buildRustPackage rec {
pname = "devaur";
version = "0.1.0";
cargoLock.lockFile = ./Cargo.lock;
src = ./.;
inherit buildInputs;
nativeBuildInputs = with pkgs; [
python
];
};
}
);
}
My src/main.rs
use pyo3::prelude::*;
#[tokio::main]
async fn main() {
Python::with_gil(|py| {
let site = PyModule::import(py, "site")?;
let prefixes = site.getattr("PREFIXES")?.extract::<Vec<String>>()?;
println!("{:?}", prefixes);
let _ = PyModule::import(py, "osc")?;
println!("\nSuccesfully imported osc!\n");
Ok::<(), PyErr>(())
})
.unwrap();
}
My Cargo.toml
[package]
name = "devaur"
description = ""
version = "0.1.0"
edition = "2024"
[dependencies]
tokio = { version = "1.44.1", features = ["full"] }
pyo3 = { version = "0.24.0", features = ["auto-initialize"] }
I am completely lost. From what I understand, osc
might be present during the runtime of the Rust binary. Please help :(