|
1 | 1 | # async_py |
2 | 2 |
|
3 | | -A Rust library for calling Python code asynchronously using `pyo3` and `tokio`. |
| 3 | +A Rust library for calling Python code asynchronously using [pyo3](https://github.com/PyO3/pyo3) and [tokio](https://tokio.rs/). |
4 | 4 |
|
5 | | -This library provides a `PyRunner` that runs a Python interpreter in a dedicated background thread. Global variables will be kept and stored in this runner. |
6 | | -You can send Python code to this executor from any async Rust task, and it will be executed without blocking your application. |
| 5 | +This library provides a `PyRunner` that runs a Python interpreter in a dedicated |
| 6 | +background thread. Global variables are preserved within the runner's scope. |
| 7 | +You can send Python code to this executor from any async Rust task, |
| 8 | +and it will be executed without blocking your application. |
7 | 9 |
|
8 | | -Due to the Python global interpreter lock (GIL), there will not be any multithreading. If one python |
| 10 | +Due to the Python Global Interpreter Lock (GIL), you cannot run Python code simultaneously. If one Python |
9 | 11 | task is performing a computation or a sleep, no other task can access the interpreter. |
10 | 12 |
|
11 | | -Using multiple `PyRunner` does not allow multithreading, due to the architecture |
12 | | -of python. But you can isolate your global variables by using multiple runners. |
| 13 | +Using multiple `PyRunner` instances does not enable simultaneous Python code execution due to the GIL. |
| 14 | +However, it does allow you to isolate global variables between different runners. |
13 | 15 |
|
14 | 16 | ## Usage |
15 | 17 |
|
16 | 18 | Add `async_py` to your `Cargo.toml`: |
17 | 19 |
|
18 | 20 | ```toml |
19 | 21 | [dependencies] |
20 | | -async_py = { git = "..." } # Or path, or crates.io version |
| 22 | +async_py = { git = "https://github.com/marcomq/async_py" } # Or path, or crates.io version |
21 | 23 | tokio = { version = "1", features = ["full"] } |
22 | 24 | ``` |
23 | 25 |
|
@@ -48,3 +50,24 @@ def greet(name): |
48 | 50 | println!("{}", result2.as_str().unwrap()); // Prints: Hello World! Called 2 times from Python. |
49 | 51 | } |
50 | 52 | ``` |
| 53 | +### Using a venv |
| 54 | +It is generally recommended to use a venv to install pip packages. |
| 55 | +While you cannot switch the interpreter version with this crate, you can use an |
| 56 | +existing venv to load installed packages. |
| 57 | + |
| 58 | +```rust |
| 59 | +let runner = PyRunner::new(); |
| 60 | +runner.set_venv(&Path::new("/path/to/venv")).await?; |
| 61 | +``` |
| 62 | + |
| 63 | +### rustpython |
| 64 | +PyO3 has usually the best compatibility for python packages. |
| 65 | +But if you want to use python on android, wasm, or if you don't want to use any |
| 66 | +external library, you can use [rustpython](https://github.com/RustPython/RustPython). |
| 67 | +Keep in mind that some essential packages like `os` are missing on rustpython. |
| 68 | + |
| 69 | +Cargo.toml |
| 70 | +```toml |
| 71 | +[dependencies] |
| 72 | +async_py = { features = ["rustpython"] } |
| 73 | +``` |
0 commit comments