In reality, it seems like the python developers and toolchain are embracing rust enough to reduce the benefits to a new alternative.
For instance, checkout Llama-node https://github.com/Atome-FE/llama-node for an involved Rust-based NodeJS extension. Python has PyO3, a Rust-Python extension toolset: https://github.com/PyO3/pyo3.
They can help you leverage your Rust for writing cool new stuff.
Things have arguably become even nicer (although slightly more divergent between the two) since then: Python's `Optional[T]` can now be written as `T | None`, and the core container types can now be annotated directly (e.g. `List[T]` becomes `list[T]`).
Combined via pyO3[1], Python and Rust are a real joy to write together.
[1] https://github.com/PyO3/pyo3
[2] https://safjan.com/rustification-of-python/#drawbacks-and-co...
[1]: https://github.com/PyO3/pyo3
[2]: https://github.com/PyO3/maturin
[3]: https://github.com/PyO3/maturin#examples
How did they verify that the new code was conformant with the old app's behavior/logic?
> To make matters worse, we would discover issues only after deploying (or in production!) due to Python’s run time nature.
I don't want to infer too much, but this makes it sound like perhaps they didn't have a very robust set of E2E/Acceptance tests, which would make a full-cutover migration scary to me. If you're finding Python bugs only after deploy, how can you find the inevitable rewritten-Rust-code incompatibilities before deploying/production?
I've been digging into Rust/Python interop recently using https://github.com/PyO3/pyo3 and maturin, and this points to an interesting migration strategy; PyO3 makes it quite easy to write a Python module in Rust, or even call back and forth between them, so you could gradually move code from Python to Rust. A migration path to full-Rust might be:
1. Incrementally replace all your fast-path C/C++ code with Rust, still having Python call these compiled modules. End-state: You now have a Python/Rust project instead of Python/C/C++.
2. Gradually grow the surface area of your Rust packages, moving logic from Python into Rust. Your existing Python tests can still run, and your existing entrypoints are the same Python.
3. At some point, you presumably need to cut over the entrypoint layer (the API?) to use pure Rust, instead of Python. This should be a much less scary migration since both versions are calling into the same underlying Rust library code. Depending on your architecture, if you have an API Gateway you can split your service backends to migrate one endpoint at a time to the new Rust API service, while keeping the old Python API service around to fail back to. (They are using k8s so you can do this with your Ingress for example).
I'm interested in others' experiences with Rust/Python interop, are there any rough edges worth knowing about?
I would enjoy writing Rust for Python even more if I could compile and run Rust straight from the same Jupyter notebooks that I prototype my Python code with.
I can't speak for Rubyists, but I find it a very strong complementary skill to Python, as it allows for writing things that are impractical in Python. And Rust feels friendlier as a Python-complement than C. Especially parallel C.
Receiving a compiler error in Rust is more appealing to me than debugging a segfault or race condition in C, especially since Rust will always tell me when one exists. Or more importantly, I can feel comfortable pushing new fast low-level code to production knowing it's not a risk. There's no ambiguity. "fearless concurrency" is not just a buzzword, it's partly what makes Rust fun and practical (for me). As well as the incredibly-fast start-up time of my Rust code compared to Python.
It is also appealing for Python programmers because of the increasingly-decent support for mixing the two languages without overhead, including publishing pure-Rust packages as python modules^1
I agree.
Python is an awesome high level interface to low level libraries and algorithms. As which it became even more appealing since you can write your low level code in Rust and call it from Python via PyO3 [0].
https://github.com/tildeio/helix https://github.com/PyO3/pyo3 https://github.com/kyren/rlua https://github.com/neon-bindings/neon
I've mainly been looking at these resources:
https://github.com/rochacbruno/rust-python-example
Though I have not done rust <-> python in real practice
Pyo3 library gives you ability to work both diractions. Call python code from rust and call rust code from python.