Rust PyO3 - How to execute a script with unknown module imports?

315 views Asked by At

I would like to execute a function in a Python module using Rust. This module can have imports, which are unknown at programming time.

Example of a file to be run:


import testmod

def main():
    print("Hello World!")
    testmod.test_fun()
    return 0

I would like a way to pass a file to PyO3 and have it resolve and import all the dependencies specified in the file. It seems like something that should be in the PyO3 package, but I could not find any documentation online.

Right now I am using this code, which does not work because the Python modules are not executing according to their dependency relationships:

pub fn python(args: &WatchCommand) -> PyResult<()> {
    let main = std::fs::canonicalize(&args.main)?;
    let parent = main.parent().unwrap();
    debug!("Loading Python Module...");
    // Load file contents
    let file_contents = std::fs::read_to_string(&args.main)?;
    // Run Python Code
    Python::with_gil(|py| -> PyResult<()> {
        // Load modules in the same folder
        debug!("Search Folder: {:?}", parent);
        for entry in WalkDir::new(&parent) {
            match entry {
                Ok(res) => {
                    if res.path().is_file() && res.path().extension().unwrap_or_default() == "py" {
                        debug!("Loading module: {:?}", res.path());
                        let file_content = std::fs::read_to_string(res.path())?;
                        let name = res.path().file_stem().unwrap().to_str().unwrap();
                        PyModule::from_code(py, &file_content, name, name)?;
                    }
                }
                Err(e) => error!("Error loading module: {}", e),
            }
        }
        let main = PyModule::from_code(py, &file_contents, "main.py", "main");
        // Build arguments
        let args = ();
        // let kwargs = [("slope", 0.2)].into_py_dict(py);clap
        let result: i16 = main?.getattr("main")?.call(args, None)?.extract()?;
        Ok(())
    })
}

This results in the following output:

DEBUG Loading Python Module...
DEBUG Search Folder: "..."
DEBUG Loading module: "...\main.py"
ERROR Error running python code: ModuleNotFoundError: No module named 'testmod'

Any help is greatly appreciated,

Riccardo

0

There are 0 answers