Closed TanjaBayer closed 4 years ago
After looking a bit closer I found that comment: https://github.com/pytransitions/transitions/issues/259#issuecomment-482139389
But I tried to import transitions.extensions.asyncio
and it seems like it isn't there anymore. So did you remove it?
Hi @TanjaBayer,
haven't had a look at your specific issue yet but just want to tell you that dev-async had been merged into the 0.8 dev branch. If you checkout that one you will find the asyncio extension module. I am waiting for some feedack about a community contributed feature and hope to release 0.8 in the next couple of days on PyPI.
Hey,
thanks for the feedback, I will try to check out the dev branch. And will give some feedback if it works or not, once I had time to test it.
Considering your specific issue: Event triggers have to be awaited. You could (a) wrap your machine code into a function which is passed to the asyncio event loop like this:
from transitions.extensions.asyncio import AsyncMachine
import asyncio
class Evaluator:
async def my_prepare_function(self):
await asyncio.sleep(1)
states = ['Start', 'End']
transitions = [{ 'trigger': 'run', 'source': '*', 'dest': 'End', 'prepare': 'my_prepare_function'}]
_eval = Evaluator()
machine = AsyncMachine(_eval, states, transitions=transitions, initial='Start')
async def start():
await _eval.run()
asyncio.get_event_loop().run_until_complete(start())
assert _eval.state =='End'
You could also (b) pass the trigger to the loop directly:
asyncio.get_event_loop().run_until_complete(_eval.run())
Whether (a) or (b) suits you better depends on your particular problem I guess.
Yes you are right, I forgot that one in my example above.
So I just checked it with dev-0.8 branch.
In my tests it is working fine:
from transitions.extensions.asyncio import AsyncMachine
import asyncio
async def test_finish_state_is_reached_after_executing_run(_eval):
await _eval.run()
assert _eval.state == EvaluationStates.FINISHED
And in my main programm an aiohttp client I use it like that:
In the rest-endpoint callback function:
asyncio.ensure_future(s_h.loop(asyncio.get_event_loop()))
The Instance function which is called in the endpoint:
async def loop(self, loop):
while self._eval.state != EvaluationStates.FINISHED:
await self._eval.run()
So no problems so far with that, hence closing that issue, thanks for the help
Hi,
I looked through old issues but did not find a real solution to that, and even not if async prepare functions are supported at all or not.
Minimal example of what I try to achieve:
The my_prepare_function in reality contains some http requests to services, I need to have the result from before going to the next state.
Before using an async function _eval.run() was waiting for the my_prepare_function to finish before going continuing, but now, as the function is ansync it does no longer wait and _eval.state did not yet change when trying to assert the state.
Is this in general possible with pytransition?
Or is this not at all supported. I can also switch back to using plain threads and waiting for all of them to finish in the my_prepare_function(), but I think using async would be the more elegant way.
Thanks in advance