Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Python module in Rust

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for dv dv
June 08, 2017
180

Python module in Rust

Avatar for dv

dv

June 08, 2017
Tweet

Transcript

  1. Who am I • Software Engineer @ Deep Sentinel (My

    First Job !) • Last Year: First try for CAS, SymPy with codegen • GitHub: @wdv4758h
  2. Documentation for Crates You can build your docs by cargo

    doc API doc with your docstring autogen for your crates: https://docs.rs/
  3. Lower Level ... Wait ! It doesn't look like that

    low level !? I pick what I want to show you :P
  4. Python Code • Pure Python Code • Python Code +

    Binary built from (C/C++/…) • Python Code + Other Language's Code
  5. ctypes • pip • IPython • PyInstaller • SymPy •

    prompt_toolkit • ... Cases CPython Extension • NumPy • Pillow • simplejson • TensorFlow • psutil • ... CFFI • Cryptography • psycopg2cffi • pyzmq • ...
  6. ctypes - quick view import ctypes from ctypes import c_char_p

    , c_void_p lib = ctypes.cdll.LoadLibrary("pycontw.so") lib.hello_world.argtypes = (c_void_p,) lib.hello.argtypes = (c_char_p,) lib.hello.restypes = c_char_p
  7. CFFI - quick view from cffi import FFI ffi =

    FFI() lib = ffi.dlopen("pycontw.so") ffi.cdef(""" void hello_world(); char* hello(const char* name); """)
  8. CPython Extension - simple call path import Find <modulename>.so POSIX

    dlsym PyModule_Create() PyInit_<modulename>()
  9. CPython Extension - quick view static PyMethodDef pycontw_methods[] = {

    {"hello_world", hello_world, METH_VARARGS, NULL}, {"hello", hello, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} };
  10. CPython Extension - quick view static PyModuleDef pycontw_module = {

    PyModuleDef_HEAD_INIT, "pycontw", "PyCon TW 2017", -1, pycontw_methods, NULL, NULL, NULL, NULL };
  11. CPython Extension - build from distutils.core import setup, Extension module1

    = Extension('pycontw', sources = ['cpython-extension-sample.c']) setup(name = 'pycontw', version = '1.0', description = 'This is a demo package', ext_modules = [module1])
  12. CPython + Rust: by ctypes or CFFI extern "C" fn

    myfunc() { println!("It's PyCon TW 2017 !!!"); }
  13. CPython + Rust: by ctypes or CFFI • ctypes: use

    it like C • CFFI: provide a C header for Rust code
  14. rust-cpython - quick view // things like Python "import" #[macro_use]

    extern crate cpython; use cpython::{PyObject, PyResult, Python};
  15. rust-cpython - quick view fn hello(_: Python, name: &str) ->

    PyResult<String> { Ok(format!("It's PyCon TW 2017, hello {} !!!", name)) }
  16. rust-cpython - quick view py_module_initializer!(pycontw, initpycontw, PyInit_pycontw, |py, m| {

    m.add(py, "__doc__", "PyCon TW 2017")?; m.add(py, "hello", py_fn!(py, hello(name: &str)))?; m.add(py, "hello_world", py_fn!(py, hello_world()))?; Ok(()) });
  17. rust-cpython - Cargo.toml [package] name = "pycontw" version = "0.1.0"

    [lib] name = "pycontw" crate-type = ["cdylib"] [dependencies] cpython = { version = "0.1.0", features = ["extension-module"] }
  18. setuptools-rust - setup.py from setuptools import setup from setuptools_rust import

    RustExtension setup( name='pycontw', version='2017', rust_extensions=[RustExtension('pycontw', './Cargo.toml')], packages=['pycontw'], # Rust extensions are not zip safe, just like C extensions zip_safe=False, )
  19. Dropbox Brotli in Rust - src/lib.rs extern crate brotli as

    _brotli; use _brotli::enc::reader::CompressorReader; py_module_initializer!(pycontw, initpycontw, PyInit_pycontw, |py, m| { m.add(py, "brotli", py_fn!(py, brotli(data: Vec<u8>)))?; Ok(()) });
  20. Dropbox Brotli in Rust - src/lib.rs fn brotli(_: Python, data:

    Vec<u8>) -> PyResult<Vec<u8>> { let quality = 5_u32; let lg_window_size = 20_u32; let mut enc_data = vec![]; let mut reader = CompressorReader::new(data.as_slice(), 4096, quality, lg_window_size); let _ = reader.read_to_end(&mut enc_data); Ok(enc_data) }
  21. Future Work • Build module by CI for multiple platforms

    • Cross Compile module • More complete Python & Rust integration • ...