How to implement "from docx import Document" using pyo3 crate

Here is the python code, which runs well in python command environment.

from docx import Document

def test():
    document = Document('my.docx')
    return "ok"

test()

Error occurs when I call the test fun in Rust code

use pyo3::prelude::*;

fn test_pyo3()->PyResult<()> {
    Python::with_gil(|py|{
        py.import_bound("docx")?;
        let code = r#"
def test():
    document = Document('my.docx')
    return "ok"
"#;
        let mod_code = PyModule::from_code_bound(py, code, "", "")?;
        let fun = mod_code.getattr("test")?;
        let r = fun.call0()?;
        let r: String = r.extract()?;
        println!("return = {}",r);
        Ok(())
    })
}

The error is below:

Error: PyErr { type: <class 'NameError'>, value: NameError("name 'Document' is not defined"), traceback: Some(<traceback object at 0x000002A746614AC0>) } 

Then, how do we write the code correctly?

import_bound has acted like the Python statement import docx.

You can change the embedded Python code to match the code you've tested in the interpreter, and it'll do what you want:

use pyo3::prelude::*;

fn test_pyo3()->PyResult<()> {
    Python::with_gil(|py|{
        py.import_bound("docx")?;
        let code = r#"
from docx import Document

def test():
    document = Document('my.docx')
    return "ok"
"#;
        let mod_code = PyModule::from_code_bound(py, code, "", "")?;
        let fun = mod_code.getattr("test")?;
        let r = fun.call0()?;
        let r: String = r.extract()?;
        println!("return = {}",r);
        Ok(())
    })
}
2 Likes

Thanks, the code you provided works well. :v: