def api_request(methods=None, require_token=True):
    """
    View decorator that handles JSON based API requests and responses consistently.
    :param methods: A list of allowed methods
    :param require_token: Whether API token is checked automatically or not
    """
    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        def _wrapped_view(request, *args, **kwargs):
            ApiToken = apps.get_model('api', 'ApiToken')
            m = methods if methods is not None else DEFAULT_API_METHODS
            if request.method not in m:
                response = ApiResponse(False, 'Method not supported', status=405)
                response['Allow'] = ', '.join(methods)
                return response

            try:
                data = json.loads(request.body.decode('utf-8')) if request.body else {}
                if require_token:
                    token_string = request.GET['token'] if request.method == 'GET' else data['token']
                    try:
                        token = ApiToken.objects.get(token=token_string)
                        token.save()  # Update the last_seen field
                        data['token'] = token

                    except ApiToken.DoesNotExist:
                        logger.exception('Valid token required, "{0}" supplied'.format(token_string))
                        return ApiResponse(False, 'Valid token required', status=403)

                return ApiResponse(data=view_func(request, data=data, *args, **kwargs))

            except Exception as e:
                if e.__class__.__name__ == 'DoesNotExist':
                    logger.exception('Not found while handling ajax request')
                    return ApiResponse(False, 'Exception: {0}'.format(e), status=404)
                else:
                    logger.exception('Error handling ajax request')
                    return ApiResponse(False, 'Exception: {0}'.format(e), status=500)

        return _wrapped_view
    return decorator
def api_request(methods=None, require_token=True):
    """
    View decorator that handles JSON based API requests and responses consistently.
    :param methods: A list of allowed methods
    :param require_token: Whether API token is checked automatically or not
    """
    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        def _wrapped_view(request, *args, **kwargs):
            ApiToken = apps.get_model('api', 'ApiToken')
            m = methods if methods is not None else DEFAULT_API_METHODS
            if request.method not in m:
                response = ApiResponse(False, 'Method not supported', status=405)
                response['Allow'] = ', '.join(methods)
                return response

            try:
                data = json.loads(request.body.decode('utf-8')) if request.body else {}
                if require_token:
                    token_string = request.GET['token'] if request.method == 'GET' else data['token']
                    try:
                        token = ApiToken.objects.get(token=token_string)
                        token.save()  # Update the last_seen field
                        data['token'] = token

                    except ApiToken.DoesNotExist:
                        logger.exception('Valid token required, "{0}" supplied'.format(token_string))
                        return ApiResponse(False, 'Valid token required', status=403)

                return ApiResponse(data=view_func(request, data=data, *args, **kwargs))

            except Exception as e:
                if e.__class__.__name__ == 'DoesNotExist':
                    logger.exception('Not found while handling ajax request')
                    return ApiResponse(False, 'Exception: {0}'.format(e), status=404)
                else:
                    logger.exception('Error handling ajax request')
                    return ApiResponse(False, 'Exception: {0}'.format(e), status=500)

        return _wrapped_view
    return decorator
def api_request ( methods = None , require_token = True ) : def decorator ( view_func ) : @ wraps ( view_func , assigned = available_attrs ( view_func ) ) def _wrapped_view ( request , * args , * * kwargs ) : ApiToken = apps . get_model ( 'api' , 'ApiToken' ) m = methods if methods is not None else DEFAULT_API_METHODS if request . method not in m : response = ApiResponse ( False , 'Method not supported' , status = 405 ) response [ 'Allow' ] = ', ' . join ( methods ) return response try : data = json . loads ( request . body . decode ( 'utf-8' ) ) if request . body else { } if require_token : token_string = request . GET [ 'token' ] if request . method == 'GET' else data [ 'token' ] try : token = ApiToken . objects . get ( token = token_string ) token . save ( ) # Update the last_seen field data [ 'token' ] = token except ApiToken . DoesNotExist : logger . exception ( 'Valid token required, "{0}" supplied' . format ( token_string ) ) return ApiResponse ( False , 'Valid token required' , status = 403 ) return ApiResponse ( data = view_func ( request , data = data , * args , * * kwargs ) ) except Exception as e : if e . __class__ . __name__ == 'DoesNotExist' : logger . exception ( 'Not found while handling ajax request' ) return ApiResponse ( False , 'Exception: {0}' . format ( e ) , status = 404 ) else : logger . exception ( 'Error handling ajax request' ) return ApiResponse ( False , 'Exception: {0}' . format ( e ) , status = 500 ) return _wrapped_view return decorator
View decorator that handles JSON based API requests and responses consistently.
    :param methods: A list of allowed methods
    :param require_token: Whether API token is checked automatically or not
View decorator that handles JSON based API requests and responses consistently . : param methods : A list of allowed methods : param require_token : Whether API token is checked automatically or not