pyo3-asyncio
pyo3-asyncio copied to clipboard
"not currently running on a Tokio 0.2.x runtime."
🐛 Bug Reports
When reporting a bug, please provide the following information. If this is not a bug report you can just discard this template.
🌍 Environment
- Your operating system and version: Windows 11
- Your python version: 3.10
- How did you install python (e.g. apt or pyenv)? Did you use a virtualenv?: virtualenv
- Your Rust version (
rustc --version
): 1.64.0 - Your PyO3 version: 0.19
- Have you tried using latest PyO3 master (replace
version = "0.x.y"
withgit = "https://github.com/awestlake87/pyo3-asyncio")?
: yep
💥 Reproducing
Please provide a minimal working example. This means both the Rust code and the Python.
Please also write what exact flags are required to reproduce your results.
toml:
[dependencies]
async-std = "1.12.0"
futures = "0.3.28"
pyo3 = { version = "0.19", features = ["extension-module"] }
pyo3-asyncio = { git = "https://github.com/awestlake87/pyo3-asyncio", features = ["async-std-runtime"] }
reqwest = "0.11.18"
tokio = { version = "1.29.1", features = ["full"]}
yahoo-finance = "0.3.0"
rust:
#[pyfunction]
fn call_test(py: Python<'_>) -> PyResult<&PyAny> {
pyo3_asyncio::async_std::future_into_py(py, async move {
test().await;
Ok(Python::with_gil(|py| py.None()))
})
}
async fn test() {
let data = history::retrieve_interval("AAPL", Interval::_6mo)
.await
.unwrap();
for bar in &data {
println!(
"Apple hit an intraday high of ${:.2} on {}.",
bar.high,
bar.datetime().format("%b %e %Y")
);
}
}
/// A Python module implemented in Rust.
#[pymodule]
fn yahoofetcher(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(call_test, m)?)?;
Ok(())
}
py:
import asyncio
import yahoofetcher
async def main():
await yahoofetcher.call_test()
if __name__ == "__main__":
asyncio.run(main())
I get this error:
thread 'async-std/runtime' panicked at 'not currently running on a Tokio 0.2.x runtime.', C:\Users\maxim\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-0.2.25\src\runtime\handle.rs:118:28
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
File "c:\code\yahoofetcher\src\main.py", line 8, in <module>
asyncio.run(main())
File "C:\Users\maxim\AppData\Local\Programs\Python\Python310\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\Users\maxim\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 641, in run_until_complete
return future.result()
File "c:\code\yahoofetcher\src\main.py", line 5, in main
await yahoofetcher.call_test()
pyo3_asyncio.RustPanic: rust future panicked
any help would be appreciated, thanks!
For clarification, I merely copied from the tutorial, am I doing something wrong?
You have to be consistent with your runtimes. I think the libraries you are trying to use are built to work with tokio, but you are using the async-std runtime.
You'll either have to use the tokio example code or use a tokio compatibility feature in async-std.
Could you maybe rewrite my code quickly so it uses tokio? I tried a plethora of different ways and kept getting the same error...
Ah yep, you're right. Apparently this yahoo finance library is pretty old, so it's using a 0.2 version of tokio's API. Tokio's runtime doesn't support these older libraries out of the box.
Luckily however, there's a pretty nice solution to this. You can wrap your future in a tokio_compat_02
compatibility layer, and then it should work!
Cargo.toml
[lib]
name = "yahoofetcher"
crate-type = ["cdylib"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
futures = "0.3.28"
pyo3 = { version = "0.19", features = ["extension-module"] }
# Added tokio-runtime feature
pyo3-asyncio = { version = "0.19", features = ["tokio-runtime"] }
reqwest = "0.11.18"
tokio = { version = "1.29.1", features = ["full"]}
# Added tokio-compat-02 crate
tokio-compat-02 = "0.2.0"
yahoo-finance = "0.3.0"
lib.rs
use pyo3::prelude::*;
// import the FutureExt trait to enable .compat() usage
use tokio_compat_02::FutureExt;
use yahoo_finance::{history, Interval, Timestamped};
#[pyfunction]
fn call_test(py: Python<'_>) -> PyResult<&PyAny> {
// Changed to pyo3_asyncio::tokio::future_into_py
pyo3_asyncio::tokio::future_into_py(py, async move {
test().await;
Ok(Python::with_gil(|py| py.None()))
})
}
async fn test() {
// Added a .compat() to convert the future into a tokio 0.2-compatible future
let data = history::retrieve_interval("AAPL", Interval::_6mo)
.compat()
.await
.unwrap();
for bar in &data {
println!(
"Apple hit an intraday high of ${:.2} on {}.",
bar.high,
bar.datetime().format("%b %e %Y")
);
}
}
/// A Python module implemented in Rust.
#[pymodule]
fn yahoofetcher(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(call_test, m)?)?;
Ok(())
}
Basically, any time the yahoo finance library gives you a future to work with, you first call .compat()
on it to allow it to work with the modern Tokio API.
I also updated pyo3-asyncio to 0.19 since it's out now.
LMK if this works for you!
Hey,
Sorry for the late response, I was busy with work...
Yes, this does work! Unfortunately I'll have to abandon this though as the yahoo finance library isn't really up-to-date anymore and the only option would be writing something myself - I'll have to think about that
Anyways, thank you again!