|  | 
| 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