docs: def response(credentials, password, request):
      """Compile digest auth response
  
      If the qop directive's value is "auth" or "auth-int" , then compute the response as follows:
         RESPONSE = MD5(HA1:nonce:nonceCount:clienNonce:qop:HA2)
      Else if the qop directive is unspecified, then compute the response as follows:
         RESPONSE = MD5(HA1:nonce:HA2)
  
      Arguments:
      - `credentials`: credentials dict
      - `password`: request user password
      - `request`: request dict
      """
      response = None
      algorithm = credentials.get('algorithm')
      HA1_value = HA1(
          credentials.get('realm'),
          credentials.get('username'),
          password,
          algorithm
      )
      HA2_value = HA2(credentials, request, algorithm)
      if credentials.get('qop') is None:
          response = H(b":".join([
              HA1_value.encode('utf-8'),
              credentials.get('nonce', '').encode('utf-8'),
              HA2_value.encode('utf-8')
          ]), algorithm)
      elif credentials.get('qop') == 'auth' or credentials.get('qop') == 'auth-int':
          for k in 'nonce', 'nc', 'cnonce', 'qop':
              if k not in credentials:
                  raise ValueError("%s required for response H" % k)
          response = H(b":".join([HA1_value.encode('utf-8'),
                                 credentials.get('nonce').encode('utf-8'),
                                 credentials.get('nc').encode('utf-8'),
                                 credentials.get('cnonce').encode('utf-8'),
                                 credentials.get('qop').encode('utf-8'),
                                 HA2_value.encode('utf-8')]), algorithm)
      else:
          raise ValueError("qop value are wrong")
  
      return response