Example #1
0
    def transfer_patch(self):
        """
        Attempt to cancel a transfer job.
        """
        # Perform token validation. Read data from the process_info file.
        try:
            destination_token = get_destination_token(self.request)
            source_token = get_source_token(self.request)
            self.ticket_number = '{}_{}'.format(hash_tokens(source_token),
                                                hash_tokens(destination_token))
            process_data = get_process_info_data(self.ticket_number)
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        # Wait until the spawned off process has started to cancel the transfer
        while process_data['resource_transfer_in'][
                'function_process_id'] is None:
            try:
                process_data = get_process_info_data(self.ticket_number)
            except json.decoder.JSONDecodeError:
                # Pass while the process_info file is being written to
                pass

        transfer_process_data = process_data['resource_transfer_in']

        # If transfer is still in progress then cancel the subprocess
        if transfer_process_data['status'] == 'in_progress':
            for process in multiprocessing.active_children():
                if process.pid == transfer_process_data['function_process_id']:
                    process.kill()
                    process.join()
                    transfer_process_data['status'] = 'failed'
                    transfer_process_data[
                        'message'] = 'Transfer was cancelled by the user'
                    transfer_process_data['status_code'] = '499'
                    transfer_process_data['expiration'] = str(timezone.now() +
                                                              relativedelta(
                                                                  hours=1))
                    update_or_create_process_info(transfer_process_data,
                                                  'resource_transfer_in',
                                                  self.ticket_number)
                    return Response(data={
                        'status_code':
                        transfer_process_data['status_code'],
                        'message':
                        transfer_process_data['message']
                    },
                                    status=status.HTTP_200_OK)
        # If transfer is finished then don't attempt to cancel subprocess
        else:
            return Response(data={
                'status_code': transfer_process_data['status_code'],
                'message': transfer_process_data['message']
            },
                            status=status.HTTP_406_NOT_ACCEPTABLE)
Example #2
0
    def get(self, request, ticket_number):
        """
        Get the resource's download contents.

        Parameters
        ----------
        ticket_number: str
            The ticket number of the download being prepared.
        
        Returns
        -------
        200: OK
        Returns the zip of resources to be downloaded.
        
        400: Bad Request
        {
            "error": "'eaasi_token' not found as query parameter."
        }

        401: Unauthorized
        {
            "PresQT Error: Header 'eaasi_token' does not match the 'eaasi_token' for this server process."
        }
        
        404: Not Found
        {
            "message": "File unavailable."
        }
        """
        try:
            token = request.query_params['eaasi_token']
        except MultiValueDictKeyError:
            return Response(
                data={'error': "'eaasi_token' not found as query parameter."},
                status=status.HTTP_400_BAD_REQUEST)

        # Perform token validation. Read data from the process_info file.
        try:
            data = get_process_info_data('downloads', ticket_number)
            process_token_validation(token, data, 'eaasi_token')
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        # Return the file to download if it has finished.
        if data['status'] == 'finished':
            # Path to the file to be downloaded
            zip_name = data['zip_name']
            zip_file_path = os.path.join('mediafiles', 'downloads',
                                         ticket_number, zip_name)

            response = HttpResponse(open(zip_file_path, 'rb'),
                                    content_type='application/zip')
            response['Content-Disposition'] = 'attachment; filename={}'.format(
                zip_name)
        else:
            response = Response(data={'message': 'File unavailable.'},
                                status=status.HTTP_404_NOT_FOUND)

        return response
Example #3
0
    def post(self, request):
        """
        Upload a proposal task to EaaSI

        Returns
        -------
        200: OK
        {
            "id": "19",
            "message": "Proposal task was submitted."
            "proposal_link": "https://localhost/api_v1/services/eaasi/1/"
        }

        400: Bad Request
        {
        "error": "ticket_number is missing from the request body."
        }
        """
        try:
            ticket_number = request.data['ticket_number']
        except KeyError:
            return Response(data={"error": "ticket_number is missing from the request body."},
                            status=status.HTTP_400_BAD_REQUEST)

        # Create a one time use token for EaaSI to use.
        eaasi_token = str(uuid4())
        data = get_process_info_data('downloads', ticket_number)
        data['eaasi_token'] = eaasi_token
        write_file('mediafiles/downloads/{}/process_info.json'.format(ticket_number), data, True)

        # Build EaaSI download endpoint url
        eaasi_download_reverse = reverse('eaasi_download', kwargs={"ticket_number": ticket_number})
        eaasi_download_url = request.build_absolute_uri(eaasi_download_reverse)
        final_eaasi_download_url = '{}?eaasi_token={}'.format(eaasi_download_url, eaasi_token)

        data = {
            "data_url": final_eaasi_download_url,
            "data_type": "bagit+zip"
        }

        response = requests.post(
            'https://eaasi-portal.emulation.cloud/environment-proposer/api/v1/proposals',
            data=json.dumps(data),
            headers={"Content-Type": "application/json"})

        if response.status_code != 202:
            return Response(
                data={'message': 'Proposal submission returned a status code of {}.'.format(
                    response.status_code)},
                status=response.status_code)

        response_json = response.json()

        # Add Proposal link to payload
        reverse_proposal_url = reverse('proposal', kwargs={"proposal_id": response_json['id']})
        response_json['proposal_link'] = request.build_absolute_uri(reverse_proposal_url)

        return Response(data=response_json, status=status.HTTP_200_OK)
Example #4
0
    def upload_get(self):
        """
        Get the status of an upload job.
        """
        # Perform token validation. Read data from the process_info file.
        try:
            destination_token = get_destination_token(self.request)
            self.ticket_number = hash_tokens(destination_token)
            self.process_data = get_process_info_data(self.ticket_number)
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        try:
            upload_process_data = self.process_data['resource_upload']
        except KeyError:
            return Response(data={
                'error':
                'PresQT Error: "resource_upload" not found in process_info file.'
            },
                            status=status.HTTP_400_BAD_REQUEST)

        upload_status = upload_process_data['status']
        total_files = upload_process_data['upload_total_files']
        files_finished = upload_process_data['upload_files_finished']

        job_percentage = calculate_job_percentage(total_files, files_finished)
        data = {
            'status_code': upload_process_data['status_code'],
            'status': upload_status,
            'message': upload_process_data['message'],
            'job_percentage': job_percentage
        }

        if upload_status == 'finished':
            http_status = status.HTTP_200_OK
            data['status'] = upload_status
            data['failed_fixity'] = upload_process_data['failed_fixity']
            data['resources_ignored'] = upload_process_data[
                'resources_ignored']
            data['resources_updated'] = upload_process_data[
                'resources_updated']
            data['link_to_resource'] = upload_process_data['link_to_resource']
            data['job_percentage'] = 99
        else:
            if upload_status == 'in_progress':
                http_status = status.HTTP_202_ACCEPTED
                data['job_percentage'] = job_percentage
            else:
                http_status = status.HTTP_500_INTERNAL_SERVER_ERROR

        return Response(status=http_status, data=data)
Example #5
0
    def get(self, request, ticket_number):
        """
        Check in on the resource's transfer process state.

        Parameters
        ----------
        ticket_number : str
            The ticket number of the transfer being prepared.

        Returns
        -------
        200: OK
        """
        # Perform token validation. Read data from the process_info file.
        try:
            destination_token = get_destination_token(request)
            source_token = get_source_token(request)
            process_data = get_process_info_data('transfers', ticket_number)
            process_token_validation(hash_tokens(destination_token),
                                     process_data, 'presqt-destination-token')
            process_token_validation(hash_tokens(source_token), process_data, 'presqt-source-token')
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        transfer_status = process_data['status']
        data = {'status_code': process_data['status_code'], 'message': process_data['message']}

        if transfer_status == 'finished':
            http_status = status.HTTP_200_OK
            data['failed_fixity'] = process_data['failed_fixity']
            data['resources_ignored'] = process_data['resources_ignored']
            data['resources_updated'] = process_data['resources_updated']
        else:
            if transfer_status == 'in_progress':
                http_status = status.HTTP_202_ACCEPTED
            else:
                http_status = status.HTTP_500_INTERNAL_SERVER_ERROR

        return Response(status=http_status, data=data)
Example #6
0
    def patch(self, request, ticket_number):
        """
        Cancel the resource upload process on the server. Update the process_info.json
        file appropriately.

        Parameters
        ----------
        ticket_number : str
            The ticket number of the upload being prepared.

        Returns
        -------
        200: OK
        {
            "status_code": "499",
            "message": "Upload was cancelled by the user"
        }

        400: Bad Request
        {
            "error": "'presqt-destination-token' missing in the request headers."
        }

        401: Unauthorized
        {
            "error": "Header 'presqt-destination-token' does not match the
            'presqt-destination-token' for this server process."
        }

        404: Not Found
        {
            "error": "Invalid ticket number, '1234'."
        }

        406: Not Acceptable
        {
            "status_code": "200",
            "message": "Upload Successful"
        }
        """
        # Perform token validation. Read data from the process_info file.
        try:
            token = get_destination_token(request)
            data = get_process_info_data('uploads', ticket_number)
            process_token_validation(hash_tokens(token), data,
                                     'presqt-destination-token')
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        # Wait until the spawned off process has started to cancel the upload
        while data['function_process_id'] is None:
            try:
                data = get_process_info_data('uploads', ticket_number)
            except json.decoder.JSONDecodeError:
                # Pass while the process_info file is being written to
                pass

        # If upload is still in progress then cancel the subprocess
        if data['status'] == 'in_progress':
            for process in multiprocessing.active_children():
                if process.pid == data['function_process_id']:
                    process.kill()
                    process.join()
                    data['status'] = 'failed'
                    data['message'] = 'Upload was cancelled by the user'
                    data['status_code'] = '499'
                    data['expiration'] = str(timezone.now() +
                                             relativedelta(hours=1))
                    process_info_path = 'mediafiles/uploads/{}/process_info.json'.format(
                        ticket_number)
                    write_file(process_info_path, data, True)
                    return Response(data={
                        'status_code': data['status_code'],
                        'message': data['message']
                    },
                                    status=status.HTTP_200_OK)
        # If upload is finished then don't attempt to cancel subprocess
        else:
            return Response(data={
                'status_code': data['status_code'],
                'message': data['message']
            },
                            status=status.HTTP_406_NOT_ACCEPTABLE)
Example #7
0
    def get(self, request, ticket_number):
        """
        Check in on the resource's upload process state.

        Parameters
        ----------
        ticket_number : str
            The ticket number of the upload being prepared.

        Returns
        -------
        200: OK
        {
            "status_code": "200",
            "message": "Upload successful",
            "failed_fixity": [],
            "resources_ignored": [],
            "resources_updated": []
        }

        202: Accepted
        {
            "status_code": null,
            "message": "Upload is being processed on the server"
        }

        400: Bad Request
        {
            "error": "PresQT Error: 'presqt-destination-token' missing in the request headers."
        }

        401: Unauthorized
        {
            "error": "PresQT Error: Header 'presqt-destination-token' does not match the
            'presqt-destination-token' for this server process."
        }

        404: Not Found
        {
            "error": "PresQT Error: Invalid ticket number, '1234'."
        }

        500: Internal Server Error
        {
            "status_code": "404",
            "message": "Resource with id 'bad_id' not found for this user."
        }
        """
        # Perform token validation. Read data from the process_info file.
        try:
            token = get_destination_token(request)
            process_data = get_process_info_data('uploads', ticket_number)
            process_token_validation(hash_tokens(token), process_data,
                                     'presqt-destination-token')
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        upload_status = process_data['status']
        data = {
            'status_code': process_data['status_code'],
            'message': process_data['message']
        }

        if upload_status == 'finished':
            http_status = status.HTTP_200_OK
            data['failed_fixity'] = process_data['failed_fixity']
            data['resources_ignored'] = process_data['resources_ignored']
            data['resources_updated'] = process_data['resources_updated']
        else:
            if upload_status == 'in_progress':
                http_status = status.HTTP_202_ACCEPTED
            else:
                http_status = status.HTTP_500_INTERNAL_SERVER_ERROR

        return Response(status=http_status, data=data)
Example #8
0
    def get(self, request, ticket_number, response_format=None):
        """
        Check in on the resource's download process state.

        Parameters
        ----------
        ticket_number : str
            The ticket number of the download being prepared.
        response_format: str
            The type of response to return. Either json or zip

        Returns
        -------
        200: OK
        Returns the zip of resources to be downloaded.
        or
        {
            "status_code": "200",
            "message": "Download successful but with fixity errors.",
            "failed_fixity": ["/Character Sheet - Alternative - Print Version.pdf"]
        }

        202: Accepted
        {
            "status_code": null,
            "message": "Download is being processed on the server"
        }

        400: Bad Request
        {
            "error": "PresQT Error: 'presqt-source-token' missing in the request headers."
        }
        or
        {
            "error": "PresQT Error: 'csv' is not a valid format for this endpoint."
        }

        401: Unauthorized
        {
            "error": "PresQT Error: Header 'presqt-source-token' does not match the
            'presqt-source-token' for this server process."
        }

        404: Not Found
        {
            "error": "PresQT Error: Invalid ticket number, '1234'."
        }

        500: Internal Server Error
        {
            "status_code": "404",
            "message": "Resource with id 'bad_id' not found for this user."
        }
        """
        # Perform token validation. Read data from the process_info file.
        try:
            token = get_source_token(request)
            data = get_process_info_data('downloads', ticket_number)
            process_token_validation(hash_tokens(token), data,
                                     'presqt-source-token')
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        # Verify that the only acceptable response format was provided
        if response_format and response_format not in ['json', 'zip']:
            return Response(data={
                'error':
                'PresQT Error: {} is not a valid format for this endpoint.'.
                format(response_format)
            },
                            status=status.HTTP_400_BAD_REQUEST)

        download_status = data['status']
        message = data['message']
        status_code = data['status_code']

        # Return the file to download if it has finished.
        if download_status == 'finished':
            if response_format == 'zip':
                # Path to the file to be downloaded
                zip_name = data['zip_name']
                zip_file_path = os.path.join('mediafiles', 'downloads',
                                             ticket_number, zip_name)

                response = HttpResponse(open(zip_file_path, 'rb'),
                                        content_type='application/zip')
                response[
                    'Content-Disposition'] = 'attachment; filename={}'.format(
                        zip_name)
            else:
                response = Response(data={
                    'status_code': status_code,
                    'message': message,
                    'zip_name': data['zip_name'],
                    'failed_fixity': data['failed_fixity']
                },
                                    status=status.HTTP_200_OK)
            return response
        else:
            if download_status == 'in_progress':
                http_status = status.HTTP_202_ACCEPTED
            else:
                http_status = status.HTTP_500_INTERNAL_SERVER_ERROR

            return Response(status=http_status,
                            data={
                                'status_code': status_code,
                                'message': message
                            })
Example #9
0
    def post(self, request):
        """
        Upload a proposal task to EaaSI

        Returns
        -------
        200: OK
        {
            "id": "19",
            "message": "Proposal task was submitted."
            "proposal_link": "https://localhost/api_v1/services/eaasi/1/"
        }

        400: Bad Request
        {
            "error": "PresQT Error: 'presqt-source-token' missing in the request headers."
        }
        or
        {
            "error": "PresQT Error: A download does not exist for this user on the server."
        }

        404: Not Found
        {
            "error": "PresQT Error: Invalid ticket number, '1234'."
        }
        or
        {
            "error": "PresQT Error: A resource_download does not exist for this user on the server."
        }
        """
        # Get the source token from the request, hash it to get the ticket_number, get the
        # process_info.json file connected with the ticket_number.
        try:
            source_token = get_source_token(self.request)
            ticket_number = hash_tokens(source_token)
            process_info_data = get_process_info_data(ticket_number)
            download_data = get_process_info_action(process_info_data,
                                                    'resource_download')
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        # Create a one time use token for EaaSI to use.
        eaasi_token = str(uuid4())
        download_data['eaasi_token'] = eaasi_token
        write_file(
            'mediafiles/jobs/{}/process_info.json'.format(ticket_number),
            process_info_data, True)

        # Build EaaSI download endpoint url
        eaasi_download_reverse = reverse(
            'eaasi_download', kwargs={"ticket_number": ticket_number})
        eaasi_download_url = request.build_absolute_uri(eaasi_download_reverse)
        final_eaasi_download_url = '{}?eaasi_token={}'.format(
            eaasi_download_url, eaasi_token)

        data = {"data_url": final_eaasi_download_url, "data_type": "bagit+zip"}

        response = requests.post(
            'https://eaasi-portal.emulation.cloud/environment-proposer/api/v1/proposals',
            data=json.dumps(data),
            headers={"Content-Type": "application/json"})

        if response.status_code != 202:
            return Response(data={
                'message':
                'Proposal submission returned a status code of {}.'.format(
                    response.status_code)
            },
                            status=response.status_code)

        response_json = response.json()

        # Add Proposal link to payload
        reverse_proposal_url = reverse(
            'proposal', kwargs={"proposal_id": response_json['id']})
        response_json['proposal_link'] = request.build_absolute_uri(
            reverse_proposal_url)

        return Response(data=response_json, status=status.HTTP_200_OK)
Example #10
0
    def download_get(self):
        """
        Get the status of a download job.

        Will return either a json object or a file bytes depending on the 'resource_format' url
        parameter
        """
        if self.request.query_params:
            try:
                # This check will run for the email links we generate
                self.ticket_number = self.request.query_params['ticket_number']
                self.process_data = get_process_info_data(self.ticket_number)
            except (MultiValueDictKeyError, PresQTValidationError):
                return Response(data={
                    'error':
                    "'ticket_number' not found as query parameter or invalid 'ticket_number' provided."
                },
                                status=status.HTTP_400_BAD_REQUEST)
        else:
            # Perform token validation. Read data from the process_info file.
            try:
                source_token = get_source_token(self.request)
                self.ticket_number = hash_tokens(source_token)
                self.process_data = get_process_info_data(self.ticket_number)
            except PresQTValidationError as e:
                return Response(data={'error': e.data}, status=e.status_code)

        # Verify that the only acceptable response format was provided.
        if self.response_format and self.response_format not in [
                'json', 'zip'
        ]:
            return Response(data={
                'error':
                'PresQT Error: {} is not a valid format for this endpoint.'.
                format(self.response_format)
            },
                            status=status.HTTP_400_BAD_REQUEST)
        try:
            download_process_data = self.process_data['resource_download']
        except KeyError:
            return Response(data={
                'error':
                'PresQT Error: "resource_download" not found in process_info file.'
            },
                            status=status.HTTP_400_BAD_REQUEST)

        download_status = download_process_data['status']
        message = download_process_data['message']
        status_code = download_process_data['status_code']

        total_files = download_process_data['download_total_files']
        files_finished = download_process_data['download_files_finished']
        download_job_percentage = calculate_job_percentage(
            total_files, files_finished)

        # Return the file to download if it has finished.
        if download_status == 'finished':
            if self.response_format == 'zip':
                # Path to the file to be downloaded
                zip_name = download_process_data['zip_name']
                zip_file_path = os.path.join('mediafiles', 'jobs',
                                             self.ticket_number, 'download',
                                             zip_name)

                response = HttpResponse(open(zip_file_path, 'rb'),
                                        content_type='application/zip')
                response[
                    'Content-Disposition'] = 'attachment; filename={}'.format(
                        zip_name)
            else:
                response = Response(data={
                    'status_code':
                    status_code,
                    'message':
                    message,
                    'zip_name':
                    download_process_data['zip_name'],
                    'failed_fixity':
                    download_process_data['failed_fixity'],
                    'job_percentage':
                    download_job_percentage,
                    'status':
                    download_status
                },
                                    status=status.HTTP_200_OK)
            return response
        else:
            if download_status == 'in_progress':
                http_status = status.HTTP_202_ACCEPTED
            else:
                http_status = status.HTTP_500_INTERNAL_SERVER_ERROR

            return Response(status=http_status,
                            data={
                                'job_percentage': download_job_percentage,
                                'status': download_status,
                                'status_code': status_code,
                                'message': message
                            })
Example #11
0
    def download_patch(self):
        """
        Attempt to cancel a download job.
        """
        # Perform token validation. Read data from the process_info file.
        try:
            source_token = get_source_token(self.request)
            self.ticket_number = hash_tokens(source_token)
            self.process_data = get_process_info_data(self.ticket_number)
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        # Verify that the only acceptable response format was provided
        if self.response_format and self.response_format != 'json':
            return Response(data={
                'error':
                'PresQT Error: {} is not a valid format for this endpoint.'.
                format(self.response_format)
            },
                            status=status.HTTP_400_BAD_REQUEST)

        # Wait until the spawned off process has started to cancel the download
        while self.process_data['resource_download'][
                'function_process_id'] is None:
            try:
                self.process_data = get_process_info_data(self.ticket_number)
            except json.decoder.JSONDecodeError:
                # Pass while the process_info file is being written to
                pass

        download_process_data = self.process_data['resource_download']

        # If download is still in progress then cancel the subprocess
        if download_process_data['status'] == 'in_progress':
            for process in multiprocessing.active_children():
                if process.pid == download_process_data['function_process_id']:
                    process.kill()
                    process.join()
                    download_process_data['status'] = 'failed'
                    download_process_data[
                        'message'] = 'Download was cancelled by the user'
                    download_process_data['status_code'] = '499'
                    download_process_data['expiration'] = str(timezone.now() +
                                                              relativedelta(
                                                                  hours=1))
                    update_or_create_process_info(download_process_data,
                                                  'resource_download',
                                                  self.ticket_number)

                return Response(data={
                    'status_code':
                    download_process_data['status_code'],
                    'message':
                    download_process_data['message']
                },
                                status=status.HTTP_200_OK)
        # If download is finished then don't attempt to cancel subprocess
        else:
            return Response(data={
                'status_code': download_process_data['status_code'],
                'message': download_process_data['message']
            },
                            status=status.HTTP_406_NOT_ACCEPTABLE)
Example #12
0
    def transfer_get(self):
        """
        Get the status of a transfer job.
        """
        # Perform token validation. Read data from the process_info file.
        try:
            destination_token = get_destination_token(self.request)
            source_token = get_source_token(self.request)
            self.ticket_number = '{}_{}'.format(hash_tokens(source_token),
                                                hash_tokens(destination_token))
            self.process_data = get_process_info_data(self.ticket_number)
        except PresQTValidationError as e:
            return Response(data={'error': e.data}, status=e.status_code)

        try:
            transfer_process_data = self.process_data['resource_transfer_in']
        except KeyError:
            return Response(data={
                'error':
                'PresQT Error: "resource_download" not found in process_info file.'
            },
                            status=status.HTTP_400_BAD_REQUEST)

        transfer_status = transfer_process_data['status']
        upload_job_percentage = calculate_job_percentage(
            transfer_process_data['upload_total_files'],
            transfer_process_data['upload_files_finished'])
        download_job_percentage = calculate_job_percentage(
            transfer_process_data['download_total_files'],
            transfer_process_data['download_files_finished'])
        data = {
            'status_code':
            transfer_process_data['status_code'],
            'status':
            transfer_status,
            'message':
            transfer_process_data['message'],
            'job_percentage':
            round((upload_job_percentage + download_job_percentage) / 2),
        }

        if transfer_status == 'finished':
            http_status = status.HTTP_200_OK
            data['failed_fixity'] = transfer_process_data['failed_fixity']
            data['resources_ignored'] = transfer_process_data[
                'resources_ignored']
            data['resources_updated'] = transfer_process_data[
                'resources_updated']
            data['enhanced_keywords'] = transfer_process_data[
                'enhanced_keywords']
            data['initial_keywords'] = transfer_process_data[
                'initial_keywords']
            data['source_resource_id'] = transfer_process_data[
                'source_resource_id']
            data['destination_resource_id'] = transfer_process_data[
                'destination_resource_id']
            data['fairshare_evaluation_results'] = transfer_process_data[
                'fairshare_evaluation_results']
            data['link_to_resource'] = transfer_process_data[
                'link_to_resource']
            data['job_percentage'] = 99
        else:
            if transfer_status == 'in_progress':
                http_status = status.HTTP_202_ACCEPTED
            else:
                http_status = status.HTTP_500_INTERNAL_SERVER_ERROR

        return Response(status=http_status, data=data)