class TokeniseRequest(): def __init__(self, cache, _id, secret, service_name, service_url, _type='Bearer'): self.cache = cache self._id, self.secret = _id, secret self.service_name, self.service_url = service_name, service_url self._type = _type self.base = Requests() def get_token(self): response = self.base.post(self.service_url, { 'app_id': self._id, 'app_secret': self.secret }) json, status = self.base.logging(f'GET TOKEN FOR {self.service_name}', response) if status == 200: self.cache.set(self.service_name, json['token'], 3600) def make_header(self): token = self.cache.get(self.service_name) if token is None: return {} else: return {'Authorization': f'{self._type} {token}'} def __call__(self, function): return self.decorate(function) def decorate(self, function): @wraps(function) def wrapper(*args, **kwargs): return self.call(function, *args, **kwargs) return wrapper def call(self, function, *args, **kwargs): token = self.cache.get(self.service_name) if token is not None: kwargs['header'] = self.make_header() response = function(*args, **kwargs) if response.status_code != 402: return response self.get_token() kwargs['header'] = self.make_header() response = function(*args, **kwargs) return response
def __init__(self, cache, _id, secret, service_name, service_url, _type='Bearer'): self.cache = cache self._id, self.secret = _id, secret self.service_name, self.service_url = service_name, service_url self._type = _type self.base = Requests()
class OrderPropView(APIView): base = Requests() permissions = [ IsCustomAuthenticated, ] def post(self, request): try: response_add_order = order_breaker.call(self.base.post, self.base.URLS['order'], request.data['order']) json, status = self.base.logging('ADD ORDER WITH PROPERTY', response_add_order) if status == 201: try: response_add_prop = prop_breaker.call( self.base.post, self.base.URLS['prop'], request.data['prop']) json, status = self.base.logging('ADD ORDER WITH PROPERTY', response_add_prop) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) order_breaker.call( self.base.delete, self.base.URLS['prop'] + f'{json["order_uuid"]}/') json, status = {'error': 'Service unavailable'}, 503 except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) tasks.post.delay(self.base.URLS['order'], request.data['order']) json, status = {'error': 'Service unavailable'}, 503 finally: return Response(json, status)
class PropertyBaseOperView(APIView): base = Requests() pagination = LimitOffsetPagination() pagination.default_limit = 100 def post(self, request): try: response = breaker.call(self.base.post, self.base.URLS['prop'], request.data) json, status = self.base.logging('ADD PROPERTY', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) tasks.post.delay(self.base.URLS['prop'], request.data) json = {'error': 'Service unavailable'} status = 503 finally: cache.set('prop_state', breaker._state_storage, None) return Response(json, status) def get(self, request, limit_offset=None): limit_offset = request.query_params url = self.base.URLS['prop'] if limit_offset: url += f'?limit={limit_offset["limit"]}&offset={limit_offset["offset"]}' try: response = breaker.call(self.base.get, url) json, status = self.base.logging('GET PROPERTIES', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json = {'error': 'Service unavailable'} status = 503 finally: cache.set('prop_state', breaker._state_storage, None) return Response(json, status)
class UserOrdersAdvView(APIView): base = Requests() permissions = [ IsCustomAuthenticated, ] def get(self, request, user_id, ord_id): try: response_get_user = user_breaker.call( self.base.get, self.base.URLS['user'] + f'{user_id}/') if response_get_user.status_code == 200: try: response = order_breaker.call( self.base.get, self.base.URLS['order'] + f'{ord_id}/') json, status = self.base.logging('GET USER ORDER', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json, status = {'error': 'Service unavailable'}, 503 cache.set('order_state', order_breaker._state_storage, None) else: json, status = {'User doesn\'t exist'}, 404 except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json, status = {'error': 'Service unavailable'}, 503 finally: cache.set('user_state', user_breaker._state_storage, None) return Response(json, status) def delete(self, request, user_id, ord_id): try: response_get_user = user_breaker.call( self.base.get, self.base.URLS['user'] + f'{user_id}/') if response_get_user.status_code == 200: try: response = order_breaker.call( self.base.delete, self.base.URLS['order'] + f'{ord_id}/') json, status = self.base.logging('DELETE USER ORDER', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) tasks.delete.delay(self.base.URLS['order'] + f'{ord_id}/') json, status = { 'error': 'Service unavailable. Enqueued' }, 503 cache.set('order_state', order_breaker._state_storage, None) else: json, status = 'User doesn\'t exist', 404 except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json, status = {'error': 'Service unavailable'}, 503 finally: cache.set('user_state', user_breaker._state_storage, None) return Response(json, status)
class PropertyAdvOperView(APIView): base = Requests() permission_classes = [ IsCustomAuthenticated, ] def get(self, request, prop_id): try: response = breaker.call(self.base.get, self.base.URLS['prop'] + f'{prop_id}/') json, status = self.base.logging('GET PROPERTY', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json = {'error': 'Service unavailable'} status = 503 finally: cache.set('prop_state', breaker._state_storage, None) return Response(json, status) def put(self, request, prop_id): try: response = breaker.call(self.base.put, self.base.URLS['prop'] + f'{prop_id}/', request.data) json, status = self.base.logging('UPDATE PROPERTY', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) tasks.put.delay(self.base.URLS['prop'] + f'{prop_id}/', request.data) json = {'error': 'Service unavailable'} status = 503 finally: cache.set('prop_state', breaker._state_storage, None) return Response(json, status) def delete(self, request, prop_id): try: response = breaker.call(self.base.delete, self.base.URLS['prop'] + f'{prop_id}/') json, status = self.base.logging('DELETE PROPERTY', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) tasks.delete.delay(self.base.URLS['prop'] + f'{prop_id}/') json = {'error': 'Service unavailable'} status = 503 finally: cache.set('prop_state', breaker._state_storage, None) return Response(json, status)
class TokenExchangeView(APIView): base = Requests() def post(self, request): code = request.data['code'] data = { 'grant_type': 'authorization_code', 'client_id': 'in7xsewpL5Hisi0ESPGyGz58HQ1eWhc97zObNMVG', 'client_secret': 'SC12l7LpgO3Vu6oIMRSwBjt0ud2y8jCY3Ux1EJ7Vsuul8siu5pIdn9L5P6IeXhv1nRkKQ6WqvG02pLl3EMBIt0EeulDjdOZJnDp5UYzCE9ZGZK7wqTLX9xMQpWdLDTtt', 'code': code } get_token_request = self.base.post(self.base.URLS['oauth'] + 'token/', data) json, status = self.base.logging('GET TOKEN', get_token_request) return Response(data=json, status=status)
class OrderBaseOperView(APIView): base = Requests() pagination = LimitOffsetPagination() pagination.default_limit = 100 def post(self, request): @TokeniseRequest(cache, USER_ID, USER_SECRET, 'ORDER', 'http://*****:*****@TokeniseRequest(cache, USER_ID, USER_SECRET, 'ORDER', 'http://localhost:8002/serviceAuth/') def func(*args, **kwargs): return self.base.get(*args, **kwargs) limit_offset = request.query_params url = self.base.URLS['order'] if limit_offset: url += f'?limit={limit_offset["limit"]}&offset={limit_offset["offset"]}' try: response = breaker.call(func, url) json, status = self.base.logging('GET ORDERS', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json = {'error': 'Service unavailable'} status = 503 finally: cache.set('order_state', breaker._state_storage, None) return Response(json, status)
class UserAuthView(APIView): base = Requests() pagination = LimitOffsetPagination() pagination.default_limit = 100 def post(self, request): @TokeniseRequest(cache, USER_ID, USER_SECRET, 'USER', 'http://localhost:8001/serviceAuth/') def func(*args, **kwargs): return self.base.post(*args, **kwargs) try: response = breaker.call(func, self.base.URLS['auth'], request.data) json, status = self.base.logging('AUTH', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json = {'error': 'Service unavailable'} status = 503 finally: cache.set('user_state', breaker._state_storage, None) return Response(json, status)
class UserAdvOperView(APIView): base = Requests() permissions = [ IsCustomAuthenticated, ] def get(self, request, user_id): @TokeniseRequest(cache, USER_ID, USER_SECRET, 'USER', 'http://localhost:8001/serviceAuth/') def func(*args, **kwargs): return self.base.get(*args, **kwargs) try: response = breaker.call(func, self.base.URLS['user'] + f'{user_id}/', self.base.auth_header(request)) json, status = self.base.logging('GET USER', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json = {'error': 'Service unavailable'} status = 503 finally: cache.set('user_state', breaker._state_storage, None) return Response(json, status)
class UserPropertyView(APIView): base = Requests() permissions = [ IsCustomAuthenticated, ] def get(self, request, user_id): try: limit_offset = request.query_params response_get_user = user_breaker.call( self.base.get, self.base.URLS['user'] + f'{user_id}/') if response_get_user.status_code == 200: url = self.base.URLS['prop'] if limit_offset: url += f'?limit={limit_offset["limit"]}&offset={limit_offset["offset"]}' try: response = prop_breaker.call(self.base.get, url) json, status = self.base.logging('GET USER PROPERIES', response) new_json = [] for prop in json: if prop['owner_uuid'] == str(user_id): new_json.append(prop) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) cache.set('prop_state', prop_breaker._state_storage, None) new_json, status = {'error': 'Service unavailable'}, 503 else: new_json, status = {'User doesn\'t exist'}, 404 except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) new_json, status = {'error': 'Service unavailable'}, 503 finally: cache.set('user_state', user_breaker._state_storage, None) return Response(new_json, status) def post(self, request, user_id): try: response_get_user = user_breaker.call( self.base.get, self.base.URLS['user'] + f'{user_id}/') if response_get_user.status_code == 200: request.data['owner_uuid'] = str(user_id) try: response = prop_breaker.call(self.base.post, self.base.URLS['prop'], request.data) json, status = self.base.logging('ADD USER PROPERTY', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) tasks.post.delay(self.base.URLS['prop'], request.data) json, status = { 'error': 'Service unavailable. Enqueued' }, 503 cache.set('prop_state', prop_breaker._state_storage, None) else: return Response('User doesn\'t exist', 404) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) json, status = {'error': 'Service unavailable'}, 503 finally: cache.set('user_state', user_breaker._state_storage, None) return Response(json, status)
class OrderAdvOperView(APIView): base = Requests() permission_classes = [ IsCustomAuthenticated, ] def get(self, request, ord_id): @TokeniseRequest(cache, USER_ID, USER_SECRET, 'ORDER', 'http://*****:*****@TokeniseRequest(cache, USER_ID, USER_SECRET, 'ORDER', 'http://*****:*****@TokeniseRequest(cache, USER_ID, USER_SECRET, 'ORDER', 'http://localhost:8002/serviceAuth/') def func(*args, **kwargs): return self.base.delete(*args, **kwargs) try: response = breaker.call(func, self.base.URLS['order'] + f'{ord_id}/') json, status = self.base.logging('DELETE ORDER', response) except (RequestException, pybreaker.CircuitBreakerError) as error: self.base.log_exception(error) tasks.delete.delay(self.base.URLS['order'] + f'{ord_id}/') json = {'error': 'Service unavailable'} status = 503 finally: cache.set('order_state', breaker._state_storage, None) return Response(json, status)
from .celery import celery_app from requests.exceptions import RequestException from api.views.Requests import Requests MAIN_REQ = Requests() # celery -A celery_queue worker -l info -P gevent @celery_app.task(autoretry_for=(RequestException, ), retry_kwargs={'max_retries': 5}, retry_backoff=True) def post(url, data, header=None): MAIN_REQ.post(url, data, header) @celery_app.task(autoretry_for=(RequestException, ), retry_kwargs={'max_retries': 5}, retry_backoff=True) def put(url, data, header=None): MAIN_REQ.put(url, data, header) @celery_app.task(autoretry_for=(RequestException, ), retry_kwargs={'max_retries': 5}, retry_backoff=True) def delete(url, data, header=None): MAIN_REQ.delete(url, header)