docs: def generate_response(chaldict,uri,username,passwd,method='GET',cnonce=None):
    """
    Generate an authorization response dictionary. chaldict should contain the digest
    challenge in dict form. Use fetch_challenge to create a chaldict from a HTTPResponse
    object like this: fetch_challenge(res.getheaders()).
  
    returns dict (the authdict)
  
    Note. Use build_authorization_arg() to turn an authdict into the final Authorization
    header value.
    """
    authdict = {} 
    qop = dict_fetch(chaldict,'qop')
    domain = dict_fetch(chaldict,'domain')
    nonce = dict_fetch(chaldict,'nonce')
    stale = dict_fetch(chaldict,'stale')
    algorithm = dict_fetch(chaldict,'algorithm','MD5')
    realm = dict_fetch(chaldict,'realm','MD5')
    opaque = dict_fetch(chaldict,'opaque')
    nc = "00000001"
    if not cnonce:
      cnonce = H(str(random.randint(0,10000000)))[:16]
  
    if algorithm.lower()=='md5-sess':
      a1 = A1(username,realm,passwd,nonce,cnonce)
    else:
      a1 = A1(username,realm,passwd)
  
    a2 = A2(method,uri)
  
    secret = H(a1)
    data = '%s:%s:%s:%s:%s' % (nonce,nc,cnonce,qop,H(a2))
    authdict['username'] = '"%s"' % username
    authdict['realm'] = '"%s"' % realm
    authdict['nonce'] = '"%s"' % nonce
    authdict['uri'] = '"%s"' % uri
    authdict['response'] = '"%s"' % KD(secret,data)
    authdict['qop'] = '"%s"' % qop
    authdict['nc'] = nc
    authdict['cnonce'] = '"%s"' % cnonce
    
    return authdict