title: Await for function until it receives a callback in python async IO
body: <p>I have created a GATT Client in python using the Bleak Library. I subscribe to a notification characteristic and after when I get the callback in the notification handler function, I do a write to a characteristic.Until now, after I start the notification I used put a asyncio.sleep for 5 seconds and then I would do a write on the characteristic. But this is very flaky and there is no control over the code, so I want to wait until I receive a callback in notification handler function and when I get the response, I want to do the write. I am new to python async IO and I am not sure how to achieve this. Thanks for your time and effort.</p>
  <p>Here is the Code:</p>
  <pre><code>
  import logging
  import asyncio
  import platform
  
  from bleak import BleakClient
  from bleak import _logger as logger
  import time
  
  from concurrent.futures import ThreadPoolExecutor
  
  CHARACTERISTIC_UUID = &quot;0000c305-0000-1000-8000-00805f9b34fb&quot;
  CHARACTERISTIC_UUID_WR = &quot;0000c303-0000-1000-8000-00805f9b34fb&quot;
  CHARACTERISTIC_UUID_RD = &quot;0000c301-0000-1000-8000-00805f9b34fb&quot;
  
  _executor = ThreadPoolExecutor(1)
  
  async def notification_handler(sender, data):
      &quot;&quot;&quot;Simple notification handler which prints the data received.&quot;&quot;&quot;
      print(&quot;{0}: {1}&quot;.format(sender, data))
      print(hexdump(data, 16))
  
  
  def hexdump(src, length=16):
          result = []
          digits = 4 if isinstance(src, str) else 2
          for i in range(0, len(src), length):
              s = src[i:i + length]
              hexa = &quot; &quot;.join(map(&quot;{0:0&gt;2X}&quot;.format, src))
              text = &quot;&quot;.join([chr(x) if 0x20 &lt;= x &lt; 0x7F else &quot;.&quot; for x in s])
              result.append(&quot;%04X   %-*s   %s&quot; % (i, length * (digits + 1), hexa, text))
          return &quot;\n&quot;.join(result)
  
  async def run(address, debug=False):
      if debug:
          import sys
  
          l = logging.getLogger(&quot;asyncio&quot;)
          l.setLevel(logging.DEBUG)
          h = logging.StreamHandler(sys.stdout)
          h.setLevel(logging.DEBUG)
          l.addHandler(h)
          logger.addHandler(h)
  
  
  
      async with BleakClient(address) as client:
          x = await client.is_connected()
          logger.info(&quot;Connected: {0}&quot;.format(x))
  
          bleDevice = client
          await client.start_notify(CHARACTERISTIC_UUID, notification_handler)
  
  
          # before: asyncio.sleep(5)
  
  
          # now: wait here until I the notification_hanlder get a callback, then do the write
  
          await client.write_gatt_char(CHARACTERISTIC_UUID_WR, [0xA6, 0x00, 0x02, 0xD0, 0x01, 0x77])
          
          await client.write_gatt_char(CHARACTERISTIC_UUID_WR, [0xA6])
  
          await client.write_gatt_char(CHARACTERISTIC_UUID_WR, [0xA7])
  
  if __name__ == &quot;__main__&quot;:
      import os
  
      os.environ[&quot;PYTHONASYNCIODEBUG&quot;] = str(1)
      address = (
          &quot;48:23:35:00:14:be&quot;  # &lt;--- Change to your device's address here if you are using Windows or Linux
          if platform.system() != &quot;Darwin&quot;
          else &quot;B9EA5233-37EF-4DD6-87A8-2A875E821C46&quot;  # &lt;--- Change to your device's address here if you are using macOS
      )
  
      # for i in range(5):
      loop = asyncio.get_event_loop()
      loop.set_debug(True)
      loop.run_until_complete(run(address, True))
  </code></pre>