async def _fetch_access_token(self, url, data): """ The real fetch access token """ logger.info('Fetching component access token') req = HTTPRequest(url, body=data) res = await self._http.fetch(req) if res.error is not None: raise WeChatClientException(errcode=None, errmsg=None, client=self, request=req, response=res) result = json.loads(res.body.decode('utf-8', 'ignore'), strict=False) if 'errcode' in result and result['errcode'] != 0: raise WeChatClientException(result['errcode'], result['errmsg'], client=self, request=res.request, response=res) expires_in = 7200 if 'expires_in' in result: expires_in = result['expires_in'] self.session.set('component_access_token', result['component_access_token'], expires_in) self.expires_at = int(time.time()) + expires_in return result
async def _handle_result(self, res, method=None, url=None, **kwargs): result = json.loads(res.body.decode('utf-8', 'ignore'), strict=False) if 'errcode' in result: result['errcode'] = int(result['errcode']) if 'errcode' in result and result['errcode'] != 0: errcode = result['errcode'] errmsg = result.get('errmsg', errcode) if self.auto_retry and errcode in ( WeChatErrorCode.INVALID_CREDENTIAL.value, WeChatErrorCode.INVALID_ACCESS_TOKEN.value, WeChatErrorCode.EXPIRED_ACCESS_TOKEN.value): logger.info( 'Component access token expired, fetch a new one and retry request' ) await self.fetch_access_token() kwargs['params']['component_access_token'] = self.session.get( 'component_access_token') return await self._request(method=method, url_or_endpoint=url, **kwargs) elif errcode == WeChatErrorCode.OUT_OF_API_FREQ_LIMIT.value: # api freq out of limit raise APILimitedException(errcode, errmsg, client=self, request=res.request, response=res) else: raise WeChatClientException(errcode, errmsg, client=self, request=res.request, response=res) return result
def decode_result(self, res): try: result = json.loads(res.body.decode('utf-8', 'ignore'), strict=False) except (TypeError, ValueError): # Return origin response object if we can not decode it as JSON logger.debug('Can not decode response as JSON', exc_info=True) return res return result
async def _request(self, method, url_or_endpoint, **kwargs): if not url_or_endpoint.startswith(('http://', 'https://')): url = '{base}{endpoint}'.format( base=self.API_BASE_URL, endpoint=url_or_endpoint ) else: url = url_or_endpoint params = kwargs.pop('params', {}) params = urlencode(dict((k, to_binary(v)) for k, v in params.items())) url = '{0}?{1}'.format(url, params) data = kwargs.pop('data', {}) if isinstance(data, dict): body = json.dumps(data, ensure_ascii=False) body = body.encode('utf-8') kwargs['body'] = body req = HTTPRequest(url, method=method, **kwargs) res = await self._http.fetch(req) if res.error is not None: raise WeChatOAuthException( errcode=None, errmsg=None, client=self, request=req, response=res ) result = json.loads(res.body.decode('utf-8', 'ignore'), strict=False) if 'errcode' in result and result['errcode'] != 0: errcode = result['errcode'] errmsg = result['errmsg'] raise WeChatOAuthException( errcode, errmsg, client=self, request=res.request, response=res ) return result
def get(self, key, default=None): key = self.key_name(key) value = self.mc.get(key) if value is None: return default return json.loads(to_text(value))