Adding Maturin/PyO3 to an existing Python Click CLI #5139
-
Hello, I am writing my first Python/Rust module, though I’ve messed with some Rust code before, and I’m not fully understanding how to link the Python and Rust modules to each other. I am adding Rust bindings via Maturin and PyO3 to an existing Python project (PR: seanome/kmerseek#19) My old directory structure in the working Python package looked like this ( environment.yml
environment_mac_arm64.yml
environment_no_versions.yml
LICENSE
Makefile
pyproject.toml
src
├── __init__.py
├── kmerseek
│ ├── __init__.py
│ ├── entity.py
│ ├── extract_kmers.py
│ ├── index.py
│ ├── logging.py
│ ├── main.py
│ ├── query.py
│ ├── search.py
│ ├── sig2kmer.py
│ ├── sketch.py
│ └── uniprot.py
└── python
└── kmerseek
└── __pycache__
├── __init__.cpython-313.pyc
├── entity.cpython-313.pyc
├── extract_kmers.cpython-313.pyc
├── index.cpython-313.pyc
├── logging.cpython-313.pyc
├── main.cpython-313.pyc
├── query.cpython-313.pyc
├── search.cpython-313.pyc
├── sig2kmer.cpython-313.pyc
├── sketch.cpython-313.pyc
└── uniprot.cpython-313.pyc
target
tests This package runs on the command line through a [Click](https://click.palletsprojects.com/en/stable/)-based CLI, where the old [project]
name = "kmerseek"
version = "0.1.0"
description = "Efficient protein domain annotation search with reduced amino acid k-mers"
authors = [{ name = "Olga Botvinnik", email = "[email protected]" }]
dependencies = [
"sourmash",
"sourmash_plugin_branchwater",
"polars",
"click",
"pandas",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project.scripts]
kmerseek = "kmerseek.main:cli"
To add Rust functionality, I manually copied in a Cargo.lock
Cargo.toml
environment.yml
environment_mac_arm64.yml
environment_no_versions.yml
LICENSE
Makefile
pyproject.toml
src
├── python
│ ├── __init__.py
│ └── kmerseek
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-313.pyc
│ │ ├── entity.cpython-313.pyc
│ │ ├── extract_kmers.cpython-313.pyc
│ │ ├── index.cpython-313.pyc
│ │ ├── logging.cpython-313.pyc
│ │ ├── main.cpython-313.pyc
│ │ ├── query.cpython-313.pyc
│ │ ├── search.cpython-313.pyc
│ │ ├── sig2kmer.cpython-313.pyc
│ │ ├── sketch.cpython-313.pyc
│ │ └── uniprot.cpython-313.pyc
│ ├── entity.py
│ ├── extract_kmers.py
│ ├── index.py
│ ├── logging.py
│ ├── main.py
│ ├── query.py
│ ├── search.py
│ ├── sig2kmer.py
│ ├── sketch.py
│ └── uniprot.py
└── rust
└── [lib.rs](http://lib.rs/)
target
tests The use pyo3::prelude::*;
/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
/// A Python module implemented in Rust.
#[pymodule]
fn kmerseek(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
Ok(())
} And the new [project]
name = "kmerseek"
version = "0.1.0"
requires-python = ">=3.8"
description = "Efficient protein domain annotation search with reduced amino acid k-mers"
authors = [{ name = "Olga Botvinnik", email = "[email protected]" }]
classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"License :: OSI Approved :: MIT License",
"License :: OSI Approved :: Apache Software License",
]
dependencies = [
"sourmash",
"sourmash_plugin_branchwater",
"polars",
"click",
"pandas",
]
scripts.kmerseek = "kmerseek.main:cli"
[build-system]
requires = ["maturin>=1.8,<2.0"]
build-backend = "maturin"
[tool.maturin]
python-source = "src/python/kmerseek"
features = ["pyo3/extension-module"]
python-packages = ["kmerseek.main", "kmerseek.entity"] What I am missing is, how can I get my old modules and CLI back working in tandem with this new Rust implementation? My tests are currently showing that (kmerseek-dev)
Mon 12 May - 11:53 ~/code/kmerseek origin ☊ main ✔
make test
zsh: correct 'test' to 'tests' [nyae]? n
rm -rf tests/testdata/fasta/*sig.zip*
rm -rf tests/testdata/fasta/*manysketch.csv
pytest
========================================== test session starts ===========================================
platform darwin -- Python 3.13.1, pytest-8.3.4, pluggy-1.5.0
rootdir: /Users/olga/code/kmerseek
configfile: pyproject.toml
collected 0 items / 3 errors
================================================= ERRORS =================================================
_________________________________ ERROR collecting tests/test_entity.py __________________________________
ImportError while importing test module '/Users/olga/code/kmerseek/tests/test_entity.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
../../anaconda3/envs/kmerseek-dev/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_entity.py:6: in <module>
from kmerseek.entity import KmerseekEntity
E ModuleNotFoundError: No module named 'kmerseek.entity'
__________________________________ ERROR collecting tests/test_index.py __________________________________
ImportError while importing test module '/Users/olga/code/kmerseek/tests/test_index.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
../../anaconda3/envs/kmerseek-dev/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_index.py:5: in <module>
from kmerseek.main import cli
E ModuleNotFoundError: No module named 'kmerseek.main'
_________________________________ ERROR collecting tests/test_search.py __________________________________
ImportError while importing test module '/Users/olga/code/kmerseek/tests/test_search.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
../../anaconda3/envs/kmerseek-dev/lib/python3.13/importlib/__init__.py:88: in import_module
return _bootstrap._gcd_import(name[level:], package, level)
tests/test_search.py:6: in <module>
from kmerseek.main import cli
E ModuleNotFoundError: No module named 'kmerseek.main'
======================================== short test summary info =========================================
ERROR tests/test_entity.py
ERROR tests/test_index.py
ERROR tests/test_search.py
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 3 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
=========================================== 3 errors in 1.48s ============================================
make: *** [test] Error 2 Here is the use pyo3::prelude::*;
/// Formats the sum of two numbers as string.
#[pyfunction]
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
/// A Python module implemented in Rust.
#[pymodule]
fn kmerseek(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
Ok(())
} If I import (kmerseek-dev) (base)
✘ Mon 12 May - 11:33 ~/code/kmerseek origin ☊ olgabot/add-rust-maturin 1●
python
Python 3.13.1 | packaged by conda-forge | (main, Jan 13 2025, 09:45:31) [Clang 18.1.8 ] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import kmerseek
>>> dir(kmerseek)
['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'kmerseek', 'sum_as_string'] What am I missing? Do I need to add something to the Warmest, |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I think you might need [tool.maturin]
python-source = "src/python/kmerseek" to be corrected to [tool.maturin]
python-source = "src/python" |
Beta Was this translation helpful? Give feedback.
I think you might need
to be corrected to