# Copyright 2014 Novo Nordisk Foundation Center for Biosustainability, DTU.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
WebModels API
-------------
A high level API for retrieving models from the
http://darwin.di.uminho.pt/models and http://bigg.ucsd.edu databases
"""
from __future__ import absolute_import, print_function
import io
import logging
import tempfile
import optlang
import requests
from cobra.io import load_json_model, read_sbml_model
from pandas import DataFrame
from cameo.io import sanitize_ids
__all__ = ['index_models_minho', 'index_models_bigg', 'bigg', 'minho']
logger = logging.getLogger(__name__)
class NotFoundException(Exception):
def __init__(self, type, index, *args, **kwargs):
message = "Could not retrieve %s for entry with index %i" % (type, index)
Exception.__init__(self, message, *args, **kwargs)
def load_webmodel(query, solver_interface, sanitize=True):
logger.debug('Querying webmodels ... trying http://bigg.ucsd.edu first')
try:
model = get_model_from_bigg(query, solver_interface=solver_interface, sanitize=sanitize)
except Exception:
logger.debug('Querying webmodels ... trying minho next')
try:
df = index_models_minho()
except requests.ConnectionError as e:
logger.error("You need to be connected to the internet to load an online model.")
raise e
except Exception as e:
logger.error("Something went wrong while looking up available webmodels.")
raise e
try:
model = get_model_from_uminho(query, df, solver_interface=solver_interface, sanitize=sanitize)
except IndexError:
raise ValueError("%s is neither a file nor a model ID." % query)
return model
[docs]def index_models_minho(host="http://darwin.di.uminho.pt/models"):
"""
Retrieves a summary of all models in the database.
Parameters
----------
host: the service host (optional, default: http://darwin.di.uminho.pt/models)
Returns
-------
pandas.DataFrame
summary of the models in the database
"""
uri = host + "/models.json"
try:
response = requests.get(uri, timeout=3)
except requests.ConnectionError as e:
logger.error("Cannot reach %s. Are you sure that you are connected to the internet?" % host)
raise e
if response.ok:
try:
json = response.json()
except Exception as e:
logger.error('No json could be decoded from server response coming from {}.'.format(host))
raise e
else:
index = DataFrame(json, columns=["id", "name", "doi", "author",
"year", "formats", "organism",
"taxonomy", "optflux_validated"])
index.columns = ["id", "name", "doi", "author", "year", "formats", "organism", "taxonomy", "validated"]
return index
else:
raise Exception("Could not index available models. %s returned status code %d" % (host, response.status_code))
def get_model_from_uminho(query, index, host="http://darwin.di.uminho.pt/models", solver_interface=optlang,
sanitize=True):
model_index = index[index["name"] == query]['id'].values[0]
sbml_file = get_sbml_file(model_index, host)
sbml_file.close()
model = read_sbml_model(sbml_file.name)
model.solver = solver_interface
if sanitize:
sanitize_ids(model)
return model
def get_sbml_file(index, host="http://darwin.di.uminho.pt/models"):
temp = tempfile.NamedTemporaryFile(delete=False)
uri = host + "/models/%i.sbml" % index
try:
response = requests.get(uri)
except requests.ConnectionError as e:
logger.error("Cannot reach {}. Are you sure that you are connected to the internet?".format(host))
raise e
if response.ok:
temp.write(response.text.encode('utf-8'))
temp.flush()
return temp
else:
raise NotFoundException("sbml", index)
[docs]def index_models_bigg():
try:
response = requests.get('http://bigg.ucsd.edu/api/v2/models', timeout=3)
except requests.ConnectionError as e:
logger.error("Cannot reach http://bigg.ucsd.edu. Are you sure that you are connected to the internet?")
raise e
if response.ok:
try:
json = response.json()
except Exception as e:
logger.error('No json could be decoded from server response coming from http://bigg.ucsd.edu.')
raise e
else:
return DataFrame.from_dict(json['results'])
else:
raise Exception(
"Could not index available models. bigg.ucsd.edu returned status code {}".format(response.status_code))
def get_model_from_bigg(id, solver_interface=optlang, sanitize=True):
try:
response = requests.get('http://bigg.ucsd.edu/api/v2/models/{}/download'.format(id))
except requests.ConnectionError as e:
logger.error("Cannot reach http://bigg.ucsd.edu. Are you sure that you are connected to the internet?")
raise e
if response.ok:
with io.StringIO(response.text) as f:
model = load_json_model(f)
model.solver = solver_interface
if sanitize:
sanitize_ids(model)
return model
else:
raise Exception(
"Could not download model {}. bigg.ucsd.edu returned status code {}".format(id, response.status_code))
class ModelDB(object):
def __init__(self, index_method, index_key, get_model_method):
self._index_method = index_method
self._index_key = index_key
self._get_model_method = get_model_method
self._index = None
self.status = ''
def _index_models(self):
try:
self._index = self._index_method()
self.status = 'indexed'
except requests.ConnectionError:
self.status = "The server could not be reached. Make sure you are connected to the internet"
def __dir__(self):
if self._index is None:
self._index_models()
return list(self._index[self._index_key])
def __getattr__(self, item):
if self._index is None:
self._index_models()
if item in self._index[self._index_key].values:
return self._get_model_method(item, self._index)
else:
super(ModelDB, self).__getattribute__(item)
bigg = ModelDB(index_models_bigg, 'bigg_id', lambda q, idx: get_model_from_bigg(q))
minho = ModelDB(index_models_minho, 'name', get_model_from_uminho)
def validated_minho_names():
minho = index_models_minho()
minho_validated = minho[minho.validated]
return minho_validated
minho.validated = ModelDB(validated_minho_names, 'name', get_model_from_uminho)
# bigg = ModelDB()
# try:
# model_ids = index_models_bigg().bigg_id
# except requests.ConnectionError:
# bigg.no_models_available = "Cameo couldn't reach http://bigg.ucsd.edu at initialization time." \
# "Are you connected to the internet?"
# except Exception as e:
# bigg.no_models_available = "Cameo could reach http://bigg.ucsd.edu at initialization time" \
# "but something went wrong while decoding the server response."
# logger.debug(e)
# else:
# for id in model_ids:
# setattr(bigg, str_to_valid_variable_name(id), lazy_object_proxy.Proxy(partial(get_model_from_bigg, id)))
#
# minho = ModelDB()
# try:
# minho_models = index_models_minho()
# except requests.ConnectionError as e:
# minho.no_models_available = "Cameo couldn't reach http://darwin.di.uminho.pt/models at initialization time." \
# "Are you connected to the internet?"
# logger.debug(e)
# except Exception as e:
# minho.no_models_available = "Cameo could reach http://darwin.di.uminho.pt/models at initialization time" \
# "but something went wrong while decoding the server response."
# logger.debug(e)
# else:
# model_indices = minho_models.id
# model_ids = minho_models.name
# for index, id in zip(model_indices, model_ids):
# setattr(minho, str_to_valid_variable_name(id), lazy_object_proxy.Proxy(partial(get_model_from_uminho, index)))
#
# validated_models = minho_models[minho_models.validated]
# minho.validated = ModelDB()
# model_indices = validated_models.id
# model_ids = validated_models.name
# for index, id in zip(model_indices, model_ids):
# setattr(minho.validated, str_to_valid_variable_name(id),
# lazy_object_proxy.Proxy(partial(get_model_from_uminho, index)))
if __name__ == "__main__":
print(index_models_minho())
from cameo.io import load_model
model = load_model(get_sbml_file(2))
print(model.objective)