I am trying to execute a python async function in an actix web socket.
I was able to figure out how to execute a sync function and send the response back to the web socket. However, I am unable to do the same with the async functions.
Here is my approach below:
Ok(ws::Message::Text(text)) => {
// need to also passs this text as a param
let handler_function = &self.router.get("message").unwrap().0;
let _number_of_params = &self.router.get("message").unwrap().1;
println!("{:?}", handler_function);
match handler_function {
PyFunction::SyncFunction(handler) => Python::with_gil(|py| {
let handler = handler.as_ref(py);
// call execute function
let op = handler.call0().unwrap();
let op: &str = op.extract().unwrap();
return ctx.text(op);
// return ctx.text(op);
}),
PyFunction::CoRoutine(handler) => {
let fut = Python::with_gil(|py| {
let handler = handler.as_ref(py);
Ok(pyo3_asyncio::tokio::into_future(handler.call0().unwrap()))
})
.unwrap();
let fut = actix::fut::wrap_future::<_, Self>(fut.unwrap());
ctx.spawn(fut);
return ctx.text("Async Functions are not supported in WS right now.");
}
}
}
I am getting the following error:
error[E0271]: type mismatch resolving `<FutureWrap<impl futures_util::Future+std::marker::Send, MyWs> as ActorFuture<MyWs>>::Output == ()`
--> src/web_socket_connection.rs:88:29
|
88 | ctx.spawn(fut);
| ^^^^^ expected enum `Result`, found `()`
|
= note: expected enum `Result<pyo3::Py<pyo3::PyAny>, pyo3::PyErr>`
found unit type `()`
error: aborting due to previous error> ] 226/227: robyn
Do let me know if you would require any more details from me.
NEW_APPRROACH
I made some progress and took a new approach where I wrapped the python function inside an async function.
Ok(ws::Message::Text(text)) => {
// need to also passs this text as a param
let handler_function = &self.router.get("message").unwrap().0;
let _number_of_params = &self.router.get("message").unwrap().1;
println!("{:?}", handler_function);
match handler_function {
PyFunction::SyncFunction(handler) => Python::with_gil(|py| {
let handler = handler.as_ref(py);
// call execute function
let op = handler.call0().unwrap();
let op: &str = op.extract().unwrap();
return ctx.text(op);
// return ctx.text(op);
}),
PyFunction::CoRoutine(handler) => {
println!("{:?}", handler);
println!("Async functions are not supported in WS right now.");
let fut = Python::with_gil(|py| {
let handler = handler.as_ref(py);
pyo3_asyncio::tokio::into_future(handler.call0().unwrap()).unwrap()
});
let f = async move {
let output = fut.await.unwrap();
Python::with_gil(|py| {
let contents: &str = output.extract(py).unwrap();
println!("{:?}", contents);
});
};
let fut = actix::fut::wrap_future::<_, Self>(f);
// fut.spawn(self);
ctx.spawn(fut);
return ctx.text("Async Functions are not supported in WS right now.");
}
}
}
But now, I am getting an error that the coroutine was never awaited
Async functions are not supported in WS right now.
thread 'actix-rt|system:0|arbiter:0' panicked at 'called `Result::unwrap()` on an `Err` value: PyErr { type: <class 'RuntimeError'>, value: RuntimeError('no running event loop'), traceback: None }', src/web_socket_connection.rs:85:88
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
sys:1: RuntimeWarning: coroutine 'connect' was never awaited