parameters: (self, code=None, http=None, device_flow_info=None)
docstring: Exchanges a code for OAuth2Credentials.
  
      Args:
  
        code: string, a dict-like object, or None. For a non-device
            flow, this is either the response code as a string, or a
            dictionary of query parameters to the redirect_uri. For a
            device flow, this should be None.
        http: httplib2.Http, optional http instance to use when fetching
            credentials.
        device_flow_info: DeviceFlowInfo, return value from step1 in the
            case of a device flow.
  
      Returns:
        An OAuth2Credentials object that can be used to authorize requests.
  
      Raises:
        FlowExchangeError: if a problem occurred exchanging the code for a
            refresh_token.
        ValueError: if code and device_flow_info are both provided or both
            missing.
docstring_summary: Exchanges a code for OAuth2Credentials.
docstring_tokens: Exchanges a code for OAuth2Credentials .
function: def step2_exchange(self, code=None, http=None, device_flow_info=None):
      """Exchanges a code for OAuth2Credentials.
  
      Args:
  
        code: string, a dict-like object, or None. For a non-device
            flow, this is either the response code as a string, or a
            dictionary of query parameters to the redirect_uri. For a
            device flow, this should be None.
        http: httplib2.Http, optional http instance to use when fetching
            credentials.
        device_flow_info: DeviceFlowInfo, return value from step1 in the
            case of a device flow.
  
      Returns:
        An OAuth2Credentials object that can be used to authorize requests.
  
      Raises:
        FlowExchangeError: if a problem occurred exchanging the code for a
            refresh_token.
        ValueError: if code and device_flow_info are both provided or both
            missing.
  
      """
      if code is None and device_flow_info is None:
        raise ValueError('No code or device_flow_info provided.')
      if code is not None and device_flow_info is not None:
        raise ValueError('Cannot provide both code and device_flow_info.')
  
      if code is None:
        code = device_flow_info.device_code
      elif not isinstance(code, six.string_types):
        if 'code' not in code:
          raise FlowExchangeError(code.get(
              'error', 'No code was supplied in the query parameters.'))
        code = code['code']
  
      post_data = {
          'client_id': self.client_id,
          'client_secret': self.client_secret,
          'code': code,
          'scope': self.scope,
      }
      if device_flow_info is not None:
        post_data['grant_type'] = 'http://oauth.net/grant_type/device/1.0'
      else:
        post_data['grant_type'] = 'authorization_code'
        post_data['redirect_uri'] = self.redirect_uri
      body = urllib.parse.urlencode(post_data)
      headers = {
          'content-type': 'application/x-www-form-urlencoded',
      }
  
      if self.user_agent is not None:
        headers['user-agent'] = self.user_agent
  
      if http is None:
        http = httplib2.Http()
  
      resp, content = http.request(self.token_uri, method='POST', body=body,
                                   headers=headers)
      d = _parse_exchange_token_response(content)
      if resp.status == 200 and 'access_token' in d:
        access_token = d['access_token']
        refresh_token = d.get('refresh_token', None)
        if not refresh_token:
          logger.info(
              'Received token response with no refresh_token. Consider '
              "reauthenticating with approval_prompt='force'.")
        token_expiry = None
        if 'expires_in' in d:
          token_expiry = datetime.datetime.utcnow() + datetime.timedelta(
              seconds=int(d['expires_in']))
  
        extracted_id_token = None
        if 'id_token' in d:
          extracted_id_token = _extract_id_token(d['id_token'])
  
        logger.info('Successfully retrieved access token')
        return OAuth2Credentials(access_token, self.client_id,
                                 self.client_secret, refresh_token, token_expiry,
                                 self.token_uri, self.user_agent,
                                 revoke_uri=self.revoke_uri,
                                 id_token=extracted_id_token,
                                 token_response=d)
      else:
        logger.info('Failed to retrieve access token: %s', content)
        if 'error' in d:
          # you never know what those providers got to say
          error_msg = str(d['error']) + str(d.get('error_description', ''))
        else:
          error_msg = 'Invalid response: %s.' % str(resp.status)
        raise FlowExchangeError(error_msg)
function_tokens: def step2_exchange ( self , code = None , http = None , device_flow_info = None ) : if code is None and device_flow_info is None : raise ValueError ( 'No code or device_flow_info provided.' ) if code is not None and device_flow_info is not None : raise ValueError ( 'Cannot provide both code and device_flow_info.' ) if code is None : code = device_flow_info . device_code elif not isinstance ( code , six . string_types ) : if 'code' not in code : raise FlowExchangeError ( code . get ( 'error' , 'No code was supplied in the query parameters.' ) ) code = code [ 'code' ] post_data = { 'client_id' : self . client_id , 'client_secret' : self . client_secret , 'code' : code , 'scope' : self . scope , } if device_flow_info is not None : post_data [ 'grant_type' ] = 'http://oauth.net/grant_type/device/1.0' else : post_data [ 'grant_type' ] = 'authorization_code' post_data [ 'redirect_uri' ] = self . redirect_uri body = urllib . parse . urlencode ( post_data ) headers = { 'content-type' : 'application/x-www-form-urlencoded' , } if self . user_agent is not None : headers [ 'user-agent' ] = self . user_agent if http is None : http = httplib2 . Http ( ) resp , content = http . request ( self . token_uri , method = 'POST' , body = body , headers = headers ) d = _parse_exchange_token_response ( content ) if resp . status == 200 and 'access_token' in d : access_token = d [ 'access_token' ] refresh_token = d . get ( 'refresh_token' , None ) if not refresh_token : logger . info ( 'Received token response with no refresh_token. Consider ' "reauthenticating with approval_prompt='force'." ) token_expiry = None if 'expires_in' in d : token_expiry = datetime . datetime . utcnow ( ) + datetime . timedelta ( seconds = int ( d [ 'expires_in' ] ) ) extracted_id_token = None if 'id_token' in d : extracted_id_token = _extract_id_token ( d [ 'id_token' ] ) logger . info ( 'Successfully retrieved access token' ) return OAuth2Credentials ( access_token , self . client_id , self . client_secret , refresh_token , token_expiry , self . token_uri , self . user_agent , revoke_uri = self . revoke_uri , id_token = extracted_id_token , token_response = d ) else : logger . info ( 'Failed to retrieve access token: %s' , content ) if 'error' in d : # you never know what those providers got to say error_msg = str ( d [ 'error' ] ) + str ( d . get ( 'error_description' , '' ) ) else : error_msg = 'Invalid response: %s.' % str ( resp . status ) raise FlowExchangeError ( error_msg )