import time from threading import Thread import requests from rest_framework.exceptions import APIException, ParseError from django.conf import settings from apps.utils.errors import SP_REQUEST_ERROR from apps.utils.tools import print_roundtrip requests.packages.urllib3.disable_warnings() class SpClient: """ 音响接口 """ def __init__(self, username=settings.SP_USERNAME, password=settings.SP_PASSWORD) -> None: if not settings.SP_ENABLED: return None self.username = username self.password = password self.headers = {} self.isGetingToken = False self.isRuning = True self.t = None # 线程 self.setup() def _get_token_loop(self): while self.isRuning: params = { "user": { "email": self.username, "password": self.password } } r = requests.post(json=params, url=settings.SP_BASE_URL + '/api/users/login', verify=False) if r.status_code == 200: ret = r.json() self.headers['Authorization'] = 'Bearer ' + ret['user']['token'] time.sleep(3600) def get_token(self): self.isGetingToken = True params = { 'grant_type': 'client_credentials', 'client_id': self.client_id, 'client_secret': self.client_secret } r = requests.post(params=params, url=settings.SP_BASE_URL + '/evo-apigw/evo-oauth/oauth/token', verify=False) if r.status_code == 200: ret = r.json() self.headers['Authorization'] = 'Bearer ' + ret['user']['token'] self.isGetingToken = False def setup(self): t = Thread(target=self._get_token_loop, args=(), daemon=True) t.start() def __del__(self): """ 自定义销毁 """ self.isRuning = False # self.t.join() def request(self, url: str, method: str, params=dict(), json=dict(), timeout=10, file_path_rela=None, raise_exception=True): if self is None: raise ParseError('音响对接未启用') if self.isGetingToken: req_num = 0 while True: time.sleep(0.5) if not self.isGetingToken: self.request(url, method, params, json, timeout, file_path_rela, raise_exception) req_num = req_num + 1 if req_num > 4: break else: files = None if file_path_rela: # 相对路径 files = {'file': open(settings.BASE_DIR + file_path_rela, 'rb')} try: if params: url = url.format(**params) r = getattr(requests, method)('{}{}'.format(settings.SP_BASE_URL, url), headers=self.headers, params=params, json=json, timeout=timeout, files=files, verify=False) except Exception: if raise_exception: raise APIException(**SP_REQUEST_ERROR) return 'error', SP_REQUEST_ERROR # if settings.DEBUG: # print_roundtrip(r) if r.status_code == 200: ret = r.json() if 'code' in ret and ret['code'] not in ['0', '100', '00000', '1000', 0, 100, 1000]: detail = '音响错误:{}'.format(str(ret.get('msg', ''))) err_detail = dict(detail=detail, code='sp_'+str(ret['code'])) if raise_exception: raise ParseError(**err_detail) return 'fail', dict(detail=detail, code='sp_'+str(ret['code'])) return 'success', ret else: ret = r.json() detail = '音响错误:{}-{}'.format(str(ret.get('type', '')), str(ret.get('message', ''))) err_detail = dict(detail=detail, code='sp_'+str(ret['code'])) if raise_exception: raise ParseError(**err_detail) return 'fail', dict(detail=detail, code='sp_'+str(ret['code'])) if raise_exception: raise APIException(**SP_REQUEST_ERROR) return 'error', SP_REQUEST_ERROR