Cookiecutter template for building and releasing Python packages with a Rust binary module. Supports Linux, macOS and Windows.
Rust is a new systems programming language that is comparable in speed with C/C++; but it also has lots of nice modern features like memory safety, a package manager, and a sophisticated type system.
Like C/C++, Rust can be called from Python. The goal of the project is to make it easy to start a Python project that includes a binary module written in Rust. A very important goal of the project is that it be able to produce a binary distribution (Wheel) which will not require the end user to actually compile the Rust code themselves.
A binary wheel is produced for Linux and OSX by TravisCI. A windows wheel is built for Windows with appveyor.
An exmple project made by this cookiecutter can be seen on github at rust_pypi_example. In the example I wrote a cli in Python that interops via CFFI with a Rust binary. I used a tool called setuptools-rust which enables setuptools to handle compiling just like it would with C.
The binary wheels can be seen on Pypi at pypi-rust-pypi-example. You should be able to install the package on your platform with:
pip install rust_pypi_example # test if a number is prime rust_pypi_example 13
Please create an issue if you encounter any problems and include details about your platform.
- manylinux_X86_64 and manylinux_i686
- macOS/OSX
- Windows
- manylinuyx support - see https://github.com/pypa/manylinux
- Testing setup performed via
python setup.py test
for eitherunittest
orpy.test
- TravisCI: Ready for Travis Continuous Integration testing
- Tox testing: Setup to easily test for Python 2.6, 2.7, 3.3, 3.4, 3.5
- Sphinx docs: Documentation ready for generation with, for example, ReadTheDocs
- Bumpversion: Pre-configured version bumping with a single command
- Auto-release to PyPI when you push a new tag to master (optional)
- Command line interface using Click (optional)
Install the latest Cookiecutter if you haven't installed it yet (this requires Cookiecutter 1.4.0 or higher):
pip install -U cookiecutter
Generate a Python package project:
cookiecutter https://github.com/mckaymatt/cookiecutter-pypackage-rust-cross-platform-publish.git
Cookiecutter will prompt you to answer some questions about the project you want to create. After you finish answering the promps, the new project will be made.
This depends on you having virtualenv
, and the Rust compiler. Get the Rust compiler from Rustup. Linux/macOS
users will also need Make
.
Linux/macOS
The entire local process of building and testing (including creating and activating a virtualenv) is conducted by a single Make command:
# cd to new project. The default name is rust_pypi_example cd rust_pypi_example make local-test
I will note that the virtualenv created by Make seems to have some issues if you try to activate it. If you want to work interactivly you should build your own virtualenv and use that instead.
Windows
The Makefile workflow doesn't quite work on Windows yet, but it's still pretty easy
to get going. You basically make a virtualenv, install the dev dependencies and run python setup.py test|install|bdist_wheel|develop
depending on what you want to do.
Go into the directory that Cookiecutter just created (default is rust_pypi_example) and perform your first build locally with:
# make a virtualenv and activate it pip install -U pip pip install -r requirements_dev.txt python setup.py build_ext # compile ext python setup.py test # test python setup.py bdist_wheel # to make the wheel. Always build_ext first
W00t. You just tested, compiled and packaged you're first Python wheel with a Rust module.
- Create a repo for your new project locally and push it to GitHub.
- Add the repo to your TravisCI account.
- Install the dev requirements into a virtualenv. (
pip install -r requirements_dev.txt
) - Run the script travis_pypi_setup.py to encrypt your PyPI password in Travis config and activate automated deployment on PyPI when you push a new tag to master branch.
- Add the repo to your ReadTheDocs account + turn on the ReadTheDocs service hook.
- Release your package by pushing a new tag to master.
- Add a requirements.txt file that specifies the packages you will need for your project and their versions. For more info see the pip docs for requirements files.
- Activate your project on pyup.io.
If you don't run build_ext before bdist_wheel, the resulting wheel will not have the shared library compiled by Cargo. In other words:
# This alone will make a defective wheel python setup.py bdist_wheel # this will work python setup.py build_ext python setup.py bdist_wheel
[ ] source distributions.
For more details, see the cookiecutter-pypackage tutorial.