docs: def backup_db(callback, bool_func, output_fname, *args, **kwargs):
      """Backup Mambu Database via REST API.
  
      Makes two calls to Mambu API:
  
      - a POST to request a backup to be made
  
      - a GET, once the backup is ready, to download the latest backup
  
      * callback is a string to a callback URL Mambu will internally call
        when the backup is ready to download. You should have a webservice
        there to warn you when the backup is ready.
  
      * bool_func is a function you use against your own code to test if the
        said backup is ready. This function backup_db manages both the logic
        of the request of a backup and the downloading of it too, so
        bool_func allows you to have some way on your side to know when this
        function will download the backup.
  
        The thing is you have to build a webservice (for the callback)
        making some kind of flag turn that your bool_func will read and know
        when to say True, telling backup_db to begin the download of the
        backup.
  
      * output_fname the name of the file that will hold the downloaded
        backup. PLEASE MIND that Mambu sends a ZIP file here.
  
      * user, pwd and url allow you to change the Mambu permissions for
        the getmambuurl internally called here.
  
      * verbose is a boolean flag for verbosity.
  
      * retries number of retries for bool_func or -1 for keep waiting.
  
      * force_download_latest boolean, True to force download even if no
        callback is called. False to throw error if callback isn't received
        after retries.
  
      * returns a dictionary with info about the download
          -latest     boolean flag, if the db downloaded was the latest or not
      """
      from datetime import datetime
  
      try:
          verbose = kwargs['verbose']
      except KeyError:
          verbose = False
      try:
          retries = kwargs['retries']
      except KeyError:
          retries = -1
      try:
          force_download_latest = bool(kwargs['force_download_latest'])
      except KeyError:
          force_download_latest = False
  
      if verbose:
          log = open('/tmp/log_mambu_backup','a')
          log.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S') + " - Mambu DB Backup\n")
          log.flush()
  
      user = kwargs.pop('user', apiuser)
      pwd = kwargs.pop('pwd', apipwd)
      data = {'callback' : callback}
      try:
          posturl = iriToUri(getmambuurl(*args, **kwargs) + "database/backup")
          if verbose:
              log.write("open url: "+posturl+"\n")
              log.flush()
          resp = requests.post(posturl, data=data, headers={'content-type': 'application/json'}, auth=(apiuser, apipwd))
      except Exception as ex:
          mess = "Error requesting backup: %s" % repr(ex)
          if verbose:
              log.write(mess + "\n")
              log.close()
          raise MambuError(mess)
  
      if resp.status_code != 200:
          mess = "Error posting request for backup: %s" % resp.content
          if verbose:
              log.write(mess + "\n")
              log.close()
          raise MambuCommError(mess)
  
      data['latest'] = True
      while retries and not bool_func():
          if verbose:
              log.write("waiting...\n")
              log.flush()
          sleep(10)
          retries -= 1
          if retries < 0: retries = -1
      if not retries:
          mess = "Tired of waiting, giving up..."
          if verbose:
              log.write(mess + "\n")
              log.flush()
          if not force_download_latest:
              if verbose:
                  log.close()
              raise MambuError(mess)
          else:
              data['latest'] = False
      sleep(30)
  
      geturl = iriToUri(getmambuurl(*args, **kwargs) + "database/backup/LATEST")
      if verbose:
          log.write("open url: "+geturl+"\n")
          log.flush()
      resp = requests.get(geturl, auth=(apiuser, apipwd))
  
      if resp.status_code != 200:
          mess = "Error getting database backup: %s" % resp.content
          if verbose:
              log.write(mess + "\n")
              log.close()
          raise MambuCommError(mess)
  
      if verbose:
          log.write("saving...\n")
          log.flush()
      with open(output_fname, "w") as fw:
          fw.write(resp.content)
  
      if verbose:
          log.write("DONE!\n")
          log.close()
  
      return data