def model_simulate(model_id, method, objective_id, objective_direction, operations): try: model_wrapper = storage.get(model_id) except Unauthorized as error: abort(401, error.message) except Forbidden as error: abort(403, error.message) except ModelNotFound as error: abort(404, error.message) model = model_wrapper.model # Use the context manager to undo all modifications to the shared model instance on # completion. with model: apply_operations(model, operations) try: flux_distribution, growth_rate = simulate( model, model_wrapper.biomass_reaction, method, objective_id, objective_direction, ) except OptimizationError: return jsonify({"status": model.solver.status}) else: return jsonify( { "status": model.solver.status, "flux_distribution": flux_distribution, "growth_rate": growth_rate, } )
def model_community_simulate(model_ids, medium, method): try: model_wrappers = [storage.get(model_id) for model_id in model_ids] except Unauthorized as error: abort(401, error.message) # noqa: B306 except Forbidden as error: abort(403, error.message) # noqa: B306 except ModelNotFound as error: abort(404, error.message) # noqa: B306 return community.simulate(model_wrappers, medium, method)
def update_local_models(model_id, model_store=None): """Update locally stored models. Annotate model metabolites with CHEBI identifiers and store them locally for easy access. :param model_id: string, model identifier :param model_store: path to directory where to store the processed models. """ model_store = model_store or 'data/models' if model_id in LOCAL_MODELS: sbml_file = os.path.join(model_store, 'original', model_id + '.sbml.gz') model = read_sbml_model(sbml_file) else: model = load_model(model_id) # annotate metabolites namespace = storage.get(model_id).namespace metabolite_namespace = MODEL_METABOLITE_NAMESPACE[model_id] db_name = 'CHEBI' metabolites_missing_annotation = [ m.id for m in model.metabolites if len(m.annotation.get(db_name, [])) < 1 ] model_xref = sync_query_identifiers([ strip_compartment[namespace](mid) for mid in metabolites_missing_annotation ], namespace, db_name) for metabolite_id in metabolites_missing_annotation: compound_id = strip_compartment[namespace](metabolite_id) if compound_id in model_xref: metabolite = model.metabolites.get_by_id(metabolite_id) if db_name not in metabolite.annotation: metabolite.annotation[db_name] = [] metabolite.annotation[db_name].extend([ f'{db_name}:{i}' if not i.startswith(f"{db_name}:") else i for i in model_xref[compound_id] ]) # TODO: For some reason, id-mapper doesn't make this link, add manually for now if compound_id in GLUCOSE and db_name == 'CHEBI': metabolite.annotation[db_name].append('CHEBI:42758') if metabolite_namespace not in metabolite.annotation: metabolite.annotation[metabolite_namespace] = [] metabolite.annotation[metabolite_namespace].append(compound_id) # gecko protein exchanges db_name = 'uniprot' protein_exchanges = model.reactions.query( lambda rxn: re.match(r'^prot_.*_exchange$', rxn.id)) for rxn in protein_exchanges: rxn.annotation[db_name] = [ re.findall('^prot_(.*)_exchange$', rxn.id)[0] ] write_sbml_model(model, os.path.join(model_store, model_id + '.sbml.gz'))
def model_modify( model_id, medium, genotype, fluxomics, metabolomics, uptake_secretion_rates, molar_yields, growth_rate, ): if not request.is_json: abort(415, "Non-JSON request content is not supported") try: model_wrapper = storage.get(model_id) except Unauthorized as error: abort(401, error.message) except Forbidden as error: abort(403, error.message) except ModelNotFound as error: abort(404, error.message) # Use the context manager to undo all modifications to the shared model instance on # completion. with model_wrapper.model as model: # Build list of operations to perform on the model operations = [] warnings = [] errors = [] if medium: results = apply_medium(model, medium) operations.extend(results[0]) warnings.extend(results[1]) errors.extend(results[2]) if genotype: results = apply_genotype(model, genotype) operations.extend(results[0]) warnings.extend(results[1]) errors.extend(results[2]) if ( fluxomics or metabolomics or uptake_secretion_rates or molar_yields or growth_rate ): results = apply_measurements( model, model_wrapper.biomass_reaction, fluxomics, metabolomics, uptake_secretion_rates, molar_yields, growth_rate, ) operations.extend(results[0]) warnings.extend(results[1]) errors.extend(results[2]) if errors: # If any errors occured during modifications, discard generated operations # and return the error messages to the client for follow-up return {"errors": errors}, 400 else: return {"operations": operations, "warnings": warnings}
def test_get_model_unauthorized(monkeypatch, app): monkeypatch.setattr(requests, "get", lambda url, headers: MockResponseUnauthorized()) g.jwt_valid = False with pytest.raises(Unauthorized): storage.get(11)
def test_get_model_forbidden(monkeypatch, app): monkeypatch.setattr(requests, "get", lambda url, headers: MockResponseForbidden()) g.jwt_valid = False with pytest.raises(Forbidden): storage.get(11)
def test_get_model(monkeypatch, app): monkeypatch.setattr(requests, "get", lambda url, headers: MockResponseSuccess()) g.jwt_valid = False assert type(storage.get(10).model) == Model