Beispiel #1
0
def construct_model_out(m_v, structure, segment_result):
    '''
    Construct ModelOutput protobuf message object using segmentation results.

    Parameters:
        m_v - django.db.ModelVersion - Database model entry for model version
        structure - django.db.Structure - Databse model entry for the structure
            corresponding to the model version.
        segment_result - [ndarray] - List of output channel data in ndarray form
    Returns:
        model_out - ModelOutput.pb - Protobuf message object for the model output
    '''
    model_out = Model_pb2.ModelOutput()
    model_out.ModelID = m_v.model_version_id
    model_out.ProcesserVersion = "{}.{}".format(m_v.major_version, \
        m_v.minor_version)
    model_out.LanguageCode = m_v.language_code
    structure_pb = structure.model_to_pb()
    for result in segment_result:
        out_channel = Model_pb2.ModelOutputChannel()
        out_channel.Structure.CopyFrom(structure_pb)
        depth, height, width = result.shape
        out_channel.Volume.Width = width
        out_channel.Volume.Height = height
        out_channel.Volume.Depth = depth
        result_bytes = result.tobytes()
        out = BytesIO()
        with gzip.GzipFile(fileobj=out, mode='w') as file_out:
            file_out.write(result_bytes)
        out_channel.Volume.Data = out.getvalue()
        out_channel.Volume.DataType = Primitives3D_pb2.VolumeData3D.DataTypes.Byte
        out_channel.Volume.CompressionMethod = 0
        model_out.Channels.append(out_channel)
    return model_out
Beispiel #2
0
def get_segmentation_result(request, model_id, segmentation_id):
    '''
    Endpoint for API GET Segmentation Job result requests.

    Parameters:
        model_id (str) - model_id with which the segmentation job should use.
        segmentation_id (str) - UUID str for the segmentation job

    Returns:
        1. ModelOutput protobuf message if "accept" header is "application/x-protobuf"
        2. JSON response otherwise
    '''

    # Database query for segmentation job with segmentation_id parameter.
    try:
        seg_job = SegmentationJob.objects.get(model_id=model_id,
                                              segmentation_id=segmentation_id)
    except:
        msg = "Invalid request."
        details = "The segmentation job does not exist."
        return bad_request_helper(request, msg, details, 400)

    job_status = seg_job.get_job_progress()

    # Return unfinished bad request if progress isn't 100.
    if job_status.Progress < 100:
        msg = "Invalid request."
        details = "The segmentation job is still processing."
        return bad_request_helper(request, msg, details, 400)

    try:
        # Attempts to read the file as bytestring
        model_out_path = seg_job.model_output.path
        f_in = open(model_out_path, 'rb')
        model_out = f_in.read()
        f_in.close()

        if request.headers["accept"] == "application/x-protobuf":
            seg_job.delete()
            return HttpResponse(model_out, status=200)
        # Else
        response = Model_pb2.ModelOutput()
        response.ParseFromString(model_out)
        seg_job.delete()
        return JsonResponse(json_format.MessageToDict(response), status=200)
    except:
        msg = "Invalid request."
        details = "The segmentation job has encountered an error."
        return bad_request_helper(request, msg, details, 400)
Beispiel #3
0
    def test_post_job_retrieve_results_protobuf(self):
        '''
        Test for endpoints:
            /api/v2/Model/{modelId}/segmentation
            /api/v2/Model/{modelId}/segmentation/{segmentationId}
            /api/v2/Model/{modelId}/segmentation/{segmentationId}/result

        Since database objects are not maintained between test cases, 3 end-points are tested
        here.
        Retrieve protobuf results
        '''

        #----------------------------------------------------------------------
        # Testing POST /api/v2/Model/{modelId}/segmentation
        #----------------------------------------------------------------------
        # Post job to temporary server
        model_id = PostSegmentationTestCase.model_version.model_version_id.replace(" ", "%20")
        post_response = self.client.post('/api/v2/Model/{}/segmentation'.format(model_id), \
            self.seg_job, \
            content_type='application/x-protobuf', \
            **{'HTTP_ACCEPT':'application/x-protobuf'})
        self.assertEqual(post_response.status_code, 200, \
            msg='/api/v2/Model/{}/segmentation endpoint did not return 200 status code.'.format(\
                model_id))
        # Append orphaned segmentation job file path to path list for teardown.
        db_seg_path = SegmentationJob.objects.all()[0].model_input.path
        self.path_list.append(db_seg_path)
        # Parse protobuf message output
        seg_task = Model_pb2.SegmentationTask()
        seg_task.ParseFromString(post_response.content)
        seg_id = seg_task.SegmentationID

        #----------------------------------------------------------------------
        # Testing /api/v2/Model/{modelId}/segmentation/{segmentationId}
        #----------------------------------------------------------------------
        # Get progress from temporary server.  Since the test client is running with eager Celery
        # scheduling, it should always return 100% progress.
        get_response = self.client.get('/api/v2/Model/{}/segmentation/{}'.format( \
            model_id, seg_id), \
            **{'HTTP_ACCEPT':'application/x-protobuf'})
        self.assertEqual(get_response.status_code, 200, \
            msg='/api/v2/Model/{}/segmentation/{} endpoint did not return 200 status code.'.format(\
                model_id, seg_id))
        # Parse protobuf message output
        progress = Model_pb2.SegmentationProgress()
        progress.ParseFromString(get_response.content)
        self.assertEqual(progress.Progress, 100, \
            msg='/api/v2/Model/{}/segmentation/{} endpoint did not return 100% progress.'.format(\
                model_id, seg_id))
        # Append orphaned segmentation job file path to path list for teardown.
        db_results_path = SegmentationJob.objects.all()[0].model_output.path
        self.path_list.append(db_results_path)

        #----------------------------------------------------------------------
        # Testing /api/v2/Model/{modelId}/segmentation/{segmentationId}/result
        #----------------------------------------------------------------------
        seg_response = self.client.get('/api/v2/Model/{}/segmentation/{}/result'.format( \
            model_id, seg_id), \
            **{'HTTP_ACCEPT':'application/x-protobuf'})
        self.assertEqual(seg_response.status_code, 200, \
            msg='/api/v2/Model/{}/segmentation/{}/result endpoint did not return 200 status code.'\
            .format(model_id, seg_id))
        seg_result = Model_pb2.ModelOutput()
        seg_result.ParseFromString(seg_response.content)
        self.assertEqual(seg_result.ModelID, model_id.replace("%20"," "), \
            msg='/api/v2/Model/{}/segmentation/{}/result endpoint did not fetch correct result.'\
            .format(model_id, seg_id))