def serve(model_id, model_name, version): """Serve a specific model. This allows you to specify either a model-id or a the name + version of a specific model that you'd like to serve. If the model-id is specified, the name and versions are ignored. Throws an error if the specified model do not exist. """ if (version != 'latest' and model_id) or (model_name and model_id): raise CLIError( 'You must specify either a model_id or a model_name + version, or just the model name (' 'in which case the default latest version will be used)') if not model_name and not model_id: raise CLIError( 'You must specify either a model_id or a model_name + version, or just the model name (' 'in which case the default latest version will be used)') if version == 'latest' and model_name: ModelLoader.load(model_name) else: app = ServerManager.create_app('prod', False) with app.app_context(): if model_id: servable = LearnerManager.query_by_id(model_id) else: servable = LearnerManager.query_by_name_version( model_name, version) if servable.active: p.print_warning('Model specified is already active') return else: LearnerManager.load_version_from_existing_servable(servable) ModelLoader.load(servable.model_name)
def active_model_name_(): app = ServerManager.create_app('prod', False) with app.app_context(): active = __active() active = db.session.query(MLModel.model_name).filter( MLModel.model_id == active.model_id).one() return active[0]
def __active() -> ActiveModel: app = ServerManager.create_app('prod', False) with app.app_context(): active_id = db.session.query(ActiveModel).first() active = db.session.query(MLModel).filter( MLModel.model_id == active_id.model_id).one() # NOQA return active
def load_version_from_existing_servable(cls, servable: MLModel): current = VersionManager.max_v_from_name(servable.model_name)[-1] new = VersionManager.bump_disk(current) cls.bump_tf_version(servable.model_name, current, new) app = ServerManager.create_app('prod', False) with app.app_context(): servable.version_dir = new db.session.commit()
def max_v_from_name(cls, model_name: str): app = ServerManager.create_app('prod', False) with app.app_context(): version = db.session.query(MLModel.major, MLModel.minor, MLModel.patch, MLModel.version_dir) \ .filter(MLModel.model_name == model_name) \ .order_by(MLModel.major.desc(), MLModel.minor.desc(), MLModel.patch.desc()).first() return version
def deactivate() -> None: app = ServerManager.create_app('prod', False) with app.app_context(): try: active = db.session.query(MLModel).filter(MLModel.active == True).one() # NOQA except NoResultFound: return active.active = False db.session.commit()
def get_or_create(table: DefaultMeta, column: str, column_id: str, value: Any) -> tuple: app = ServerManager.create_app('prod', False) with app.app_context(): instance = db.session.query(getattr(table, column_id)).filter(getattr(table, column) == value).first() if instance: return instance else: instance = table(**{column: value}) db.session.add(instance) return get_or_create(table, column, column_id, value)
def run(**kwargs): defaults = { 'bind': '%s:%s' % ('0.0.0.0', '8000'), 'workers': number_of_workers(), 'worker_class': 'gevent', 'use_reloader': False, 'threaded': True } options = {**defaults, **kwargs} StandaloneApplication(ServerManager.create_app('prod', False), options).run()
def query_by_id_(model_id: int, scores: bool = False) -> MLModel: app = ServerManager.create_app('prod', False) with app.app_context(): if scores: return db.session.query(MLModel, ModelScores).filter(MLModel.model_id == model_id) \ .filter(ModelScores.model_id == MLModel.model_id) \ .all() servable = db.session.query(MLModel).filter(MLModel.model_id == model_id).one_or_none() if not servable: raise ModelNotFoundError(f'The model requested with id {model_id} was not found in the database') return servable
def query_by_name_version(cls, name: str, version: str) -> MLModel: app = ServerManager.create_app('prod', False) with app.app_context(): vvv = version.split('.') servable = db.session.query(MLModel).filter(MLModel.model_name == name) \ .filter(MLModel.major == int(vvv[0])) \ .filter(MLModel.minor == int(vvv[1])) \ .filter(MLModel.patch == int(vvv[2])).one_or_none() if not servable: raise ModelNotFoundError(f'The model requested with name, version ({name}, {version})' f' was not found in the database') return servable
def determine_current_schema() -> dict: """ Get the input specification of the currently active model Returns ------- dict: dictionary of the specs """ app = ServerManager.create_app('prod', False) model = active_model_() with app.app_context(): schema = db.session.query(MLModelInputs).filter(MLModelInputs.model_id == model).one() return schema
def assert_query_works(vals): from racket.managers.server import ServerManager app = ServerManager.create_app('prod', False) with app.app_context(): active = active_model_() a = isinstance(active, MLModel) b = active.model_id == int(vals) c = active.version_dir == str(vals) if all([a, b, c]): return True else: return False
def model_filterer_(name, version, m_type): fs = [] if name: fs.append(MLModel.model_name == name) if version: c, v = VersionManager.parse_cli_v(version) fs.append(getattr(MLModel, c) == v) if m_type: fs.append(MLModel.model_type == m_type) app = ServerManager.create_app('prod', False) with app.app_context(): query = db.session.query(MLModel, ModelScores) \ .filter(*fs) return query.all()
def test_create_multiple(learner, sample_data, create_proj): patch_bump = ['.'.join(['0', '0', str(i + 1)]) for i in range(15)] minor_bump = ['.'.join(['0', str(i + 1), '5']) for i in range(10)] major_bump = ['.'.join([str(i + 1), str(i), '0']) for i in range(10)] name_change = ['0.2.4', '0.2.5', '0.3.1', '1.0.0'] os.chdir('sample_project') ProjectManager.RACKET_DIR = '.' for v in patch_bump: fit_store_model(learner, v, sample_data) assert assert_query_works('16') is True for m in minor_bump: fit_store_model(learner, m, sample_data) assert assert_query_works('26') is True for M in major_bump: fit_store_model(learner, M, sample_data) assert assert_query_works('36') is True for n in name_change: fit_store_model(learner, n, sample_data, change_name='keras-other-model') from racket.managers.server import ServerManager app = ServerManager.create_app('prod', False) with app.app_context(): active = active_model_name_() assert isinstance(active, str) assert active == 'keras-other-model' assert isinstance(query_by_id_(model_id=1, scores=False), MLModel) assert isinstance(query_by_id_(model_id=4, scores=True), list) assert len(query_all_(scores=False)) == 40 assert len(query_all_(scores=True)) == 79 filtered = model_filterer_('keras-complex-lstm', None, None) assert len(filtered) == 35 filtered = model_filterer_(None, None, 'regression') assert len(filtered) == 40 os.chdir('../')
def store(self, historic_scores: dict, sql: MLModel) -> None: app = ServerManager.create_app('prod', False) with app.app_context(): db.session.add(sql) db.session.commit() activate(sql.model_id) for scoring_function, score in historic_scores.items(): obj = db.session.query(MLModel).order_by( MLModel.model_id.desc()).first() # noinspection PyArgumentList scoring_entry = ModelScores(model_id=obj.model_id, scoring_fn=scoring_function, score=score) db.session.add(scoring_entry) db.session.commit() p.print_success( f'Successfully stored metadata for model: {self.model_name}')
def serve_model(model_id: int, model_name: str, version: str): """Serve a specific model. This allows you to specify either a model-id or a the name + version of a specific model that you'd like to serve. If the model-id is specified, the name and versions are ignored. Throws an error if the specified model do not exist. Parameters ---------- model_id : int The desired model id to be loaded model_name : str The desired model name to be loaded. Must not be provided if model id is given version : str Semantic version, i.e. `1.1.20` of the model to be loaded """ if (version != 'latest' and model_id) or (model_name and model_id): raise CLIError( 'You must specify either a model_id or a model_name + version, or just the model name (' 'in which case the default latest version will be used)') if not model_name and not model_id: raise CLIError( 'You must specify either a model_id or a model_name + version, or just the model name (' 'in which case the default latest version will be used)') if version == 'latest' and model_name: ModelLoader.load(model_name) else: app = ServerManager.create_app('prod', False) with app.app_context(): active = __active() if model_id: servable = LearnerManager.query_by_id(model_id) else: servable = LearnerManager.query_by_name_version( model_name, version) if servable.model_id == active.model_id: p.print_warning('Model specified is already active') return else: LearnerManager.load_version_from_existing_servable(servable) ModelLoader.load(servable.model_name)
def _store_meta(self) -> None: app = ServerManager.create_app('prod', False) with app.app_context(): deactivate() sqlized = self.sql db.session.add(sqlized) db.session.commit() activate(sqlized.model_id) for scoring_function, score in self.historic_scores.items(): obj = db.session.query(MLModel).order_by( MLModel.model_id.desc()).first() scoring_entry = ModelScores(model_id=obj.model_id, scoring_fn=scoring_function, score=score) db.session.add(scoring_entry) db.session.commit() p.print_success( f'Successfully stored metadata for model: {self.model_name}')
def active_model_(scores: bool = False) -> Union[MLModel, List[MLModel]]: """ Query the model id of the currently active model Returns ------- active model Unique model identifier """ app = ServerManager.create_app('prod', False) with app.app_context(): active = __active() if scores: return db.session.query(MLModel, ModelScores).filter(MLModel.model_id == active.model_id) \ .filter(ModelScores.model_id == MLModel.model_id) \ .all() return active
def active_model_(name: bool = None, scores: bool = False) -> Union[str, dict]: """ Query the model id of the currently active model Returns ------- str Unique model identifier """ app = ServerManager.create_app('prod', False) with app.app_context(): active = db.session.query(MLModel).filter(MLModel.active == True).one() # NOQA if scores: return db.session.query(MLModel, ModelScores).filter(MLModel.model_id == active.model_id) \ .filter(ModelScores.model_id == MLModel.model_id) \ .all() if name: active = db.session.query(MLModel.model_name).filter(MLModel.model_id == active.model_id).one() return active[0] return active.as_dict()
def model_filterer_(name: str = None, version: str = None, m_type: str = None, scores: bool = False) -> list: fs = [] if name: fs.append(MLModel.model_name == name) if version: M, m, p = VersionManager.semantic_to_tuple(version) fs.append(MLModel.major == M) fs.append(MLModel.minor == m) fs.append(MLModel.patch == p) if m_type: fs.append(MLModel.model_type == m_type) app = ServerManager.create_app('prod', False) with app.app_context(): if scores: return db.session.query(MLModel, ModelScores).filter(*fs) \ .filter(ModelScores.model_id == MLModel.model_id) \ .all() return db.session.query(MLModel).filter(*fs).all()
def query_all_(scores: bool = False) -> list: """ Query all the models and their associated scores Parameters ---------- scores: bool If true, return the models alongside with its associated scores Returns ------- models: list List of models """ app = ServerManager.create_app('prod', False) with app.app_context(): if scores: query = db.session.query(MLModel, ModelScores) \ .filter(MLModel.model_id == ModelScores.model_id) else: query = db.session.query(MLModel) return query.all()
def app(): app = ServerManager.create_app('test', False) app.port = '8000' app.hostname = '127.0.0.1' return app
def activate(model_id: int) -> None: app = ServerManager.create_app('prod', False) with app.app_context(): active = db.session.query(ActiveModel).first() active.model_id = model_id db.session.commit()
def initiate_db(cls) -> None: from racket.managers.server import ServerManager ServerManager.create_app('prod', True)
# # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another # directory, add these directories to sys.path here. If the directory is # relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. # import os import sys sys.path.insert(0, os.path.abspath('..')) import racket from racket.managers.server import ServerManager ServerManager.create_app('dev', False) # -- General configuration --------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.napoleon', 'sphinx_click.ext', 'sphinx.ext.todo'] numpydoc_show_class_members = False # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates']
def activate(model_id: int) -> None: app = ServerManager.create_app('prod', False) with app.app_context(): active = db.session.query(MLModel).filter(MLModel.model_id == model_id).one() active.active = True db.session.commit()
def query_all_(): app = ServerManager.create_app('prod', False) with app.app_context(): query = db.session.query(MLModel, ModelScores) \ .filter(MLModel.model_id == ModelScores.model_id) return query.all()