Example #1
0
    def post(self):
        plate_comment_keywords = self.get_argument("plate_comment_keywords")
        well_comment_keywords = self.get_argument("well_comment_keywords")
        operation = self.get_argument("operation")
        sample_names = json_decode(self.get_argument('sample_names'))

        res = {
            "data": [[p.id, p.external_id]
                     for p in Plate.search(samples=sample_names,
                                           plate_notes=plate_comment_keywords,
                                           well_notes=well_comment_keywords,
                                           query_type=operation)]
        }

        self.write(res)
Example #2
0
    def test_search(self):
        with self.assertRaises(ValueError):
            Plate.search()

        with self.assertRaises(ValueError):
            Plate.search(samples=['1.SKB1.640202'], query_type='WRONG')

        plate21 = Plate(21)
        plate22 = Plate(22)
        plate23 = Plate(23)
        plate27 = Plate(27)
        plate30 = Plate(30)
        plate33 = Plate(33)

        self.assertEqual(
            Plate.search(samples=['1.SKB1.640202', '1.SKB2.640194']),
            [plate21, plate27, plate30, plate33])
        self.assertEqual(Plate.search(samples=['1.SKB1.640202']),
                         [plate21, plate27, plate30, plate33])

        self.assertEqual(Plate.search(plate_notes='interesting'), [])
        # Add comments to a plate so we can actually test the
        # search functionality
        plate22.notes = 'Some interesting notes'
        plate23.notes = 'More boring notes'

        self.assertEqual(Plate.search(plate_notes='interesting'), [plate22])
        self.assertCountEqual(Plate.search(plate_notes='interesting boring'),
                              [])
        self.assertEqual(
            Plate.search(samples=['1.SKB1.640202'], plate_notes='interesting'),
            [])
        # sample '1.SKB1.640202' is on 4 sample plates, plus there is a
        # gdna plate with a note containing the word 'interesting'
        self.assertCountEqual(
            Plate.search(samples=['1.SKB1.640202'],
                         plate_notes='interesting',
                         query_type='UNION'),
            [plate21, plate22, plate27, plate30, plate33])

        # The search engine ignores common english words
        self.assertEqual(Plate.search(plate_notes='more'), [])

        # Add comments to some wells
        plate23.get_well(1, 1).composition.notes = 'What else should I write?'
        self.assertEqual(Plate.search(well_notes='write'), [plate23])
        self.assertEqual(
            Plate.search(plate_notes='interesting', well_notes='write'), [])
        self.assertCountEqual(
            Plate.search(plate_notes='interesting',
                         well_notes='write',
                         query_type='UNION'), [plate22, plate23])
def sample_plating_process_handler_patch_request(user, process_id, req_op,
                                                 req_path, req_value,
                                                 req_from):
    """Performs the patch operation on the sample plating process

    Parameters
    ----------
    user: labcontrol.db.user.User
        User performing the request
    process_id: int
        The SamplePlatingProcess to apply the patch operation
    req_op: string
        JSON PATCH op parameter
    req_path: string
        JSON PATCH path parameter
    req_value: string
        JSON PATCH value parameter
    req_from: string
        JSON PATCH from parameter

    Returns
    -------
    dict
        The results of the patch operation

    Raises
    ------
    HTTPError
        400: If req_op is not a supported operation
        400: If req_path is incorrect
    """
    if req_op == 'replace':
        req_path = [v for v in req_path.split('/') if v]
        if len(req_path) != 5:
            raise HTTPError(400, 'Incorrect path parameter')
        attribute = req_path[0]

        if attribute == 'well':
            row = req_path[1]
            col = req_path[2]
            study_id = int(req_path[3])
            well_attribute = req_path[4]

            # The default values of the variables sample_id and
            # blank_or_unknown are set before the try, and these are the values
            # that are used if either (a) study_id is not 0 OR (b) the try
            # fails with a ValueError (see comment in try below). If the try
            # fails with anything other than a ValueError then the entire
            # function bails, so it doesn't matter what these variables are set
            # to. If and only if the try succeeds are these variables set to
            # the values within the try.
            sample_id = req_value
            blank_or_unknown = True

            # It actually IS possible to plate a plate without specifying
            # separate study id(s); can plate just all blanks, or can provide
            # the fully qualified sample id(s)--i.e., <studyid>.<sampleid>.
            if study_id != 0:
                try:
                    # Note that the try fails iff the
                    # Study(study_id).specimen_id_to_sample_id() call fails,
                    # as the blank_or_unknown = False can't really fail ...
                    # this assures that we can't realistically end up in an
                    # inconsistent situation where sample_id has been set
                    # during the try but blank_or_unknown has not.
                    #
                    # Thus, the ordering of these two statements within the try
                    # is really important: do not change it unless you
                    # understand all of the above!
                    the_study = Study(study_id)
                    sample_id = the_study.specimen_id_to_sample_id(req_value)
                    blank_or_unknown = False
                except ValueError:
                    pass
                # end try/except
            # end if

            if well_attribute == 'sample':
                if req_value is None or not req_value.strip():
                    raise HTTPError(
                        400, 'A new value for the well should be provided')

                plates = Plate.search(samples=[sample_id])
                process = SamplePlatingProcess(process_id)
                plates = set(plates) - {process.plate}
                prev_plates = [{
                    'plate_id': p.id,
                    'plate_name': p.external_id
                } for p in plates]
                content, sample_ok = process.update_well(row, col, sample_id)

                if blank_or_unknown:
                    req_value = content

                return {
                    'sample_id': req_value,
                    'previous_plates': prev_plates,
                    'sample_ok': sample_ok
                }
            elif well_attribute == 'notes':
                if req_value is not None:
                    # If the user provides an empty string, just store None
                    # in the database
                    req_value = (req_value.strip()
                                 if req_value.strip() else None)
                SamplePlatingProcess(process_id).comment_well(
                    row, col, req_value)
                return {'comment': req_value}
            else:
                raise HTTPError(404,
                                'Well attribute %s not found' % well_attribute)
        else:
            raise HTTPError(404, 'Attribute %s not found' % attribute)

    else:
        raise HTTPError(
            400, 'Operation %s not supported. Current supported '
            'operations: replace' % req_op)