Python Bindings
cellular_raza
was designed such that it can be used as a numerical backend for python
applications.
We use pyo3
to automatically generate these bindings and install the
resulting package in a local virtual environment.
In the past we have created multiple projects where we used python bindings to create one concise
package (cr_mech_coli,
cr_trichome).
It is also possible to distribute such a package on pypy.org.
cellular_raza-template-pyo3
We provide the template repository
cellular_raza-template-pyo3 which
makes it easy to get started with a new mixed Rust-Python project with cellular_raza
.
Layout
- cellular_raza_template_pyo3.pyi
- init.py
-
-
- Makefile
- conf.py
- index.rst
- make.bat
- references.bib
- requirements.txt
- basic.py
- lib.rs
README.md
file.The source code of this project is split between the src
and cellular_raza_template_pyo3
folders.
Python Files
The cellular_raza_template_pyo3
folder is named identically to the project and should be renamed
to the new project name.
It contains all python source code and is structured like a python project together with the
requirements.txt
and pyproject.toml
files.
The latter contains additional information for maturin which we
use for building and publishing.
pyproject.toml
|
|
Within the cellular_raza_template_pyo3
folder is a *.pyi
stub file which
provide type information about the objects generated by pyo3
.
Unfortunately it is currently not possible to automatically generate these files (see
github.com/PyO3/pyo3/issues/2454).
Rust Files
The src
folder contains all code written in Rust.
Together with the Cargo.toml
file it acts as a regular Rust-Cargo project.
It exports functions and classes inside a module from the lib.rs
file.
|
|
The name of this module should also be changed when building a new project.
Functions and object need to be annotated with the #[pyfunction]
and #[pyclass]
derive macros
respectively.
See the documentation of pyo3
.
|
|
options="{"hl_lines" "51-53"}"
|
|
Docs
The docs
folder contains files for generating documentation with
sphinx.
It integrates well within these projects and can be configured very freely.
Since we aim to provide a python package in the end, we will have to adapt the same approach in
writing docstrings for our Rust-based code.
|
|
Simulation Flow
The overall structure of this template project is similar to that of the
getting-started guide.
We define an Agent
struct and derive its properties from already existing building blocks.
|
|
All settings required to run a new simulation are stored in the SimulationSettings
struct.
|
|
This information is then used to initialize all agents and the simulation domain within the
run_simulation
function.
run_simulation
|
|
This functionality is then exported as python functions.
|
|
For now, the adjoining python code in ./cellular_raza_template_pyo3
is empty and only re-exports
these objects and functions.
Troubleshooting & Caveats
pyo3
Versions
The pyo3
version which we are using in our project and that of cellular_raza
needs to match.
Otherwise compilation of the project will fail.
Generics
Since pyo3
does not support generics, we can not expose any classes that use generics directly.
If we wish to use any class with generics, we need to write wrappers around them.
Docstrings and LSP
Sphinx inspects the generated python object itself while most language servers rely on the inline
docstrings from the python source code or *.pyi
stub files.
This means that the documentation of our python code which comes from Rust will show the contents
of docstrings given in src/...
while the syntax highlighting and completion will show the
content of the stub file cellular_raza_template_pyo3/cellular_raza_template_pyo3.pyi
.