Strategy for creating Python bindings to a rust library

I'd like to provide Python binding for a rust library. However, I want my rust library to remain a rust library. For example, I'd like my methods to return rust types rather than PyResult<PyObject>. I want a rust programmer to feel the library is just as any other rust code.

This brings me to the conclusion I have to create a separate crate with my binding code; am I right? Or is there a simpler way? I'm afraid making bindings for all my classes will require a lot of code. I'd probably need to wrap any of my structs into another, Python-friendly struct and implement delegations to methods. I've already did something similar for a C++ library. That time however the lue-up layer was automatically generated by pybind.

Could you point me an example library that is implemented that way, where I could see how it's done?

Check out PyO3's relevant documentation.

Thanks, I found there references to quite complex crates that indeed separate python bindings from their main rust library.