Skip to content

Handle rxcpp observables in Python.

rxcpp::observable<T> is the main mechanism all asynchronous calls use in this project. Enabling the use of these asynchronous APIs in Python requires some kind of interactions with these objects.

This Merge Request introduces a new opaque object (vtkPythonObservableWrapper<T>) that allows to pass an rxcpp::observable around when working in Python.

Assuming the return type already appear in vtkPythonObservableWrapper instantiations (so that the wrapping tools are aware of it) one needs just to add a macro to enable wrapping of a method that returns an observable:

class vtkPVPythonApplication:
{
...
    rxcpp::observable<vtkTypeUInt32> CreateBuiltinSession();
    // expose the observable to Python :
    VTK_REMOTING_MAKE_PYTHON_OBSERVABLE(vtkTypeUInt32, CreateBuiltinSession());
};

The generated code is then used to convert the single value observable to a asyncio.Future in Python:

App = asyncCore.vtkPVPythonApplication()
sessionId = await asyncCore.vtkPythonObservableWrapperUtilities.GetFuture(App.CreateBuiltinSession())

This allows to create Python APIs similar to the ones discussed in https://discourse.paraview.org/t/paraview-async-servermanager-api-for-python/9570

As an example see the test introduced in this MR:

import asyncio

from parat.pythonApplication import PythonApplication


async def main():
    app = PythonApplication()
    session = await app.initialize() # Create a session with the ....
    print(session)
    await asyncio.sleep(0.5)

    await app.finalize()


asyncio.run(main())

Multiple value observables will be handled similarly but in a separate merge request.

Merge request reports