1

I'm trying to build a bot using Microsoft's Bot framework in Python following this guide. I can't figure out how to display a message while waiting for a blocking function to return. I've read up on async and await in general, but haven't found any examples specific to the Bot Framework. Here's a simple example. With this code, it waits 2 seconds before displaying both messages. I want to acknowledge the user input immediately, then wait for a long blocking function and return the result.

class MyBot(ActivityHandler):
    async def on_message_activity(self, turn_context: TurnContext):
        start = time.time()

        elapsed = time.time() - start
        await turn_context.send_activity(f"Message received after {elapsed:.1f} seconds")

        await self._blocker()

        elapsed = time.time() - start
        await turn_context.send_activity(f"Finished after {elapsed:.1f} seconds!")
        
    
    async def _blocker(self):
        time.sleep(2)

The full source code is available through the guide above, or directly from here. I only changed the MyBot class.

Elliott B
  • 658
  • 3
  • 22
  • You want send the information to the user .... am waiting for your message something like that – Vinoth Rajendran Apr 20 '21 at 06:23
  • This has perplexed me. I was playing around a bit and the behavior you mention seems to be what I get if I REMOVE the async keywords from the function. But given you have the keywords in your function, you should get a syntax error if it were being called without await. My educated guess is that this has to do with how the turn handler is calling the class since the code itself seems to work properly. Sorry I'm not much help but maybe this can help you think towards a solution. – billoverton Apr 21 '21 at 14:00
  • @ElliottB - There's nothing obviously wrong with your code, so I see two possibilities. The problem may be in some part of your code that you haven't shown us (like the adapter), or the problem may be on the client side. At minimum you should let us know what channel you're using, but you may also want to show us a more complete code sample. (Since there are multiple other people in this thread, you will need to @ mention me if you want me to see your reply.) – Kyle Delaney Apr 21 '21 at 17:42
  • @KyleDelaney sorry I wrote the wrong link before. I updated the question with link to the full source code, which is a template from Microsoft. I'm using Bot Framework Emulator 4.12 – Elliott B Apr 22 '21 at 01:30
  • @ElliottB - Please don't say Emulator when someone asks what channel you're using. What if we help you find a solution that only works in Emulator and doesn't work in the channel you actually want to use? Why wouldn't you want to be forthcoming with information when people are trying to help you? – Kyle Delaney Apr 22 '21 at 22:03
  • @KyleDelaney I guess I misunderstood your question. I intend to make a Teams bot but I'm not there yet, only testing in the emulator for now. Do you think this is a bug in the emulator? – Elliott B Apr 22 '21 at 22:05
  • @ElliottB - Thanks for the information so far. It's probably not a bug in the Emulator but I wanted to have that information just in case. It's more likely to be on the bot side, so could you please let us know what version of Python you're using? The newer Python versions have problems installing the requirements for those samples, so I'm curious to know how you got around that problem. – Kyle Delaney Apr 22 '21 at 23:35
  • @KyleDelaney I just followed the instructions in a fresh venv with Python 3.7.9. I had no problems with the pip installs. I'm on macOS Catalina. – Elliott B Apr 23 '21 at 01:46

1 Answers1

1

It turns out that this is an Emulator problem after all and has nothing to do with the Bot Builder Python SDK. I've reported the bug here: https://github.com/microsoft/BotFramework-Emulator/issues/2262

At first I thought the problem was that you were using time.sleep instead of asyncio.sleep. While this turned out to not be your problem, you should still prefer asyncio.sleep when writing asynchronous code: Python 3.7 - asyncio.sleep() and time.sleep()

You can safely ignore the issue for now. In the future, always remember to test on your target channel because you can't assume Emulator will behave the same way.

Kyle Delaney
  • 9,521
  • 4
  • 27
  • 49