def validate_species(jsondata, method): missing = expect(jsondata, ["name", "aliases"]) if len(missing): return {"missing values": [f"Missing values: {missing}"]} errors = {} aliases = [s.strip() for s in jsondata["aliases"].split(",")] if method == "PUT": for name in [jsondata["name"]] + aliases: try: Species.objects.get({"$or": [{"name": name}, {"alias": name}]}) except DoesNotExist: pass else: errors["name"] = [ f"Name/alias {name} already exists in the database as name or alias" ] elif method == "POST": s_name = jsondata["name"] try: found_species = Species.objects.get({"name": s_name}) except DoesNotExist: errors["not_found"] = [f"Species {s_name} not found"] for name in [s_name] + aliases: try: Species.objects.get({ "$and": [{ "$or": [{ "name": name }, { "alias": name }] }, { "name": { "$ne": s_name } }] }) except DoesNotExist: pass else: errors["name"] = [ f"Name/alias {name} already exists in the database as name or alias" ] for key, value in jsondata.items(): if key not in ["name", "aliases", "editRow"]: if len(key.split(".")) != 4: errors[f"invalid_field_{key}"] = [ f"Field {key} was unexpected. Contact Admin." ] if len(value) == 0: errors[f"empty_value_{key}"] = [ f"Field {key} contains an empty value {value}" ] return errors
def validate_step_start(step_name, json_data): # It should also validate if all the samples are ready to start it. errors = {} missing = expect(json_data, ["sample_barcodes", "workflow_batch"]) if len(missing): errors["missing_parameters"] = "Missing parameters {}".format(",".join(missing)) return errors # Check missing step step = None try: step = m_step.Step.objects.get({"name":step_name}) except pymodm.errors.DoesNotExist: errors["step_name"] = "Step doesn't exist" # Check missing samples samples = [] if len(json_data.get("sample_barcodes",[])) == 0: errors["sample_barcodes"] = "No samples provided" else: missing_samples = [] for s_b in json_data["sample_barcodes"]: sample = None try: sample_o = m_sample.Sample.objects.get({"barcode": s_b}) samples.append(sample_o) except pymodm.errors.DoesNotExist: missing_samples.append(s_b) if len(missing_samples) > 0: e_b = "Missing samples: {}".format(",".join(missing_samples)) errors["sample_barcodes"] = e_b # Check if there are samples that have started this step already # (and haven't finished) started_is = step.get_started() potential_samples = set(json_data["sample_barcodes"]) for started_i in started_is: started_samples = set([s.barcode for s in started_i.samples]) intersection = potential_samples.intersection(started_samples) if len(intersection) > 0: errors["already_running"] = "Samples {} are already running this step. Go to that currently running step or cancel it.".format(", ".join(intersection)) # Check if step is correct. workflow_name, batch_name = json_data["workflow_batch"].split(": ") if step is not None: next_step = step.category invalid_step = [] for sample in samples: if not sample.valid_next_step(next_step, batch_name): invalid_step.append(sample.barcode) if len(invalid_step) > 0: e_b = "Invalid next step for samples: {}".format(",".join(invalid_step)) errors["invalid_step"] = e_b return errors
def validate_species_delete(jsondata): missing = expect(jsondata, ["name"]) if len(missing): return {"missing values": [f"Missing values: {missing}"]} s_name = jsondata["name"] try: found_species = Species.objects.get({"name": s_name}) except DoesNotExist: return {"not_found": [f"Species {s_name} not found"]} return {}
def validate_and_add(jsonbody): errors = {} missing = expect(jsonbody, ["value"]) if missing: errors["missing_property"] = f"Missing properties: {missing}" if len(errors): return errors #Cleaning other fields tag_data = {k: v for k, v in jsonbody.items() if k in ["value", "style", "description"]} Tag(**tag_data).save() return errors
def validate_results_report(jsondata): errors = {} missing = expect(jsondata, ["sample_barcodes", "workflow_batch"]) if len(missing): errors["missing_parameters"] = "Missing parameters {}".format(",".join(missing)) return errors missing_barcodes = [] for s_b in jsondata["sample_barcodes"]: try: sample = m_sample.Sample.objects.get({"barcode": s_b}) except pymodm.errors.DoesNotExist: missing_barcodes.append(s_b) if len(missing_barcodes): errors["sample_barcodes"] = "Missing samples: ({})".format(", ".join(missing_barcodes)) if not ": " in jsondata["workflow_batch"]: errors["workflow_batch"] = "Invalid workflow_batch" return errors
def validate_and_remove_from_sample(tagvalue, jsonbody): errors = {} missing = expect(jsonbody, ["sample_barcodes"]) if missing: errors["missing_property"] = f"Missing properties: {missing}" try: tag = Tag.objects.get({"_id": tagvalue}) except pymodm.errors.DoesNotExist: errors["tag_not_found"] = [f"Tag {tagvalue} not found."] samples = list(Sample.objects.raw({"barcode": {"$in": jsonbody["sample_barcodes"]}})) if len(samples) == 0: errors["no_valid_samples"] = ["No valid samples found with the provided barcodes."] if len(errors): return errors for sample in samples: sample.unassign_tag(tag) return errors
def validate_assign(jsonbody): """ Expects dictionary with fields workflow, sample_barcodes, batch_name """ errors = expect(jsonbody, ["plate_type", "workflow", "sample_barcodes", "batch_name"]) if len(errors): return {"missing argument": errors} errors = {} try: workflow_name = jsonbody["workflow"] workflow = m_workflow.Workflow.objects.get({"name": workflow_name}) except pymodm.errors.DoesNotExist: errors["workflow"] = "Workflow doesn't exist" return errors allowed_as_first_step = False if "step_name" in jsonbody: workflow_step_names = [s["name"] for s in workflow.steps_denormalized] try: i = workflow_step_names.index(jsonbody["step_name"]) if i == 0: prev_step = "root" else: prev_step = workflow.steps[i - 1].category if workflow.steps[i].requirements.get("allow_as_first_step", False): allowed_as_first_step = True except ValueError: errors["step_name"] = "Invalid step {} for workflow {}".format(jsonbody["step_name"], jsonbody["workflow"]) if len(jsonbody["sample_barcodes"]) == 0: errors["sample_barcodes"] = "No samples provided" else: wrong_samples = [] already_assigned = [] errors_step = [] for s_b in jsonbody["sample_barcodes"]: if s_b != "None": try: sample = m_sample.Sample.objects.get({"barcode": s_b}) except pymodm.errors.DoesNotExist: wrong_samples.append(s_b) continue for batch in sample.get_batches(workflow_name): if not(jsonbody.get("reorganizing", False) or batch.archived): already_assigned.append(s_b) if "step_name" in jsonbody: if (prev_step != "root" and prev_step not in sample.workflows.get(jsonbody["workflow"], []) and not allowed_as_first_step): errors_step.append(s_b) if len(wrong_samples) > 0: e_b = "Missing samples: {}".format(",".join(wrong_samples)) errors["sample_barcodes"] = e_b if len(already_assigned) > 0: errors["already_assigned"] = "Some samples were already assigned to workflow. ({})".format(",".join(already_assigned)) if len(errors_step) > 0: errors["step"] = "Invalid step for some samples. ({})".format(",".join(errors_step)) if not m_sample.Sample.validate_field("batch_name", jsonbody["batch_name"]): errors["batch_name"] = "Invalid batch name. Name should only have letters, dash (-) or underscore(_)" if len(jsonbody["sample_barcodes"]) > m_sample.Sample.plate_size(jsonbody["plate_type"]): errors["sample_barcodes_amount"] = "Too many samples for plate size." return errors