def get_run(self, run_id): """ Fetches the run from backend store :param run_id: string containing run UUID (32 hex characters = a uuid4 stripped off of dashes) :return: A single :py:class:`mlflow.entities.Run` object if it exists, otherwise raises an exception """ try: faculty_run = self._client.get_run(self._project_id, UUID(run_id)) except faculty.clients.base.HttpError as e: raise faculty_http_error_to_mlflow_exception(e) else: mlflow_run = faculty_run_to_mlflow_run(faculty_run) return mlflow_run
def test_faculty_run_to_mlflow_run_parent_run_id_backwards_compatability( faculty_attribute, faculty_tag_value, mlflow_tag_value): """Test logic setting parent run ID tag when not available.""" if faculty_tag_value is None: extra_tags = [] else: extra_tags = [FacultyTag(MLFLOW_PARENT_RUN_ID, faculty_tag_value)] faculty_run = FACULTY_RUN._replace(parent_run_id=faculty_attribute, tags=FACULTY_RUN.tags + extra_tags) if mlflow_tag_value is None: parent_run_id_tag = None else: parent_run_id_tag = RunTag(MLFLOW_PARENT_RUN_ID, mlflow_tag_value) expected_run = mlflow_run(parent_run_id_tag=parent_run_id_tag) assert run_equals(faculty_run_to_mlflow_run(faculty_run), expected_run)
def create_run(self, experiment_id, user_id, start_time, tags): """ Creates a run under the specified experiment ID, setting the run's status to "RUNNING" and the start time to the current time. :param experiment_id: ID of the experiment for this run :param user_id: ID of the user launching this run :param start_time: Time the run started at in epoch milliseconds. :param tags: List of Mlflow Tag entities. :return: The created Run object """ tags = [] if tags is None else tags # For backward compatability, fall back to run name or parent run ID # set in tags tag_dict = {tag.key: tag.value for tag in tags} run_name = tag_dict.get(MLFLOW_RUN_NAME) or "" parent_run_id = tag_dict.get(MLFLOW_PARENT_RUN_ID) or None try: faculty_run = self._client.create_run( self._project_id, int(experiment_id), run_name, mlflow_timestamp_to_datetime(start_time), None if parent_run_id is None else UUID(parent_run_id), tags=[mlflow_tag_to_faculty_tag(tag) for tag in tags], ) except ExperimentDeleted as conflict: raise MlflowException( "Experiment {0} is deleted." " To create runs for this experiment," " first restore it with the shell command " "'mlflow experiments restore {0}'".format( conflict.experiment_id ) ) except faculty.clients.base.HttpError as e: raise faculty_http_error_to_mlflow_exception(e) else: mlflow_run = faculty_run_to_mlflow_run(faculty_run) return mlflow_run
def test_faculty_run_to_mlflow_run_name_backwards_compatability( faculty_attribute, faculty_tag_value, mlflow_attribute, mlflow_tag_value): """Test logic setting run name tag when not available.""" if faculty_tag_value is None: extra_tags = [] else: extra_tags = [FacultyTag(MLFLOW_RUN_NAME, faculty_tag_value)] faculty_run = FACULTY_RUN._replace(name=faculty_attribute, tags=FACULTY_RUN.tags + extra_tags) if mlflow_tag_value is None: name_tag = None else: name_tag = RunTag(MLFLOW_RUN_NAME, mlflow_tag_value) expected_run = mlflow_run(name=mlflow_attribute, name_tag=name_tag) assert run_equals(faculty_run_to_mlflow_run(faculty_run), expected_run)
def test_faculty_run_to_mlflow_run( faculty_run_status, mlflow_run_status, deleted_at, lifecycle_stage, faculty_ended_at, mlflow_end_time, ): faculty_run = FACULTY_RUN._replace( status=faculty_run_status, deleted_at=deleted_at, ended_at=faculty_ended_at, ) expected_mlflow_run = mlflow_run( status=mlflow_run_status, end_time=mlflow_end_time, lifecycle_stage=lifecycle_stage, ) assert run_equals(faculty_run_to_mlflow_run(faculty_run), expected_mlflow_run)
def update_run_info(self, run_id, run_status, end_time): """ Updates the metadata of the specified run. :param run_id: string containing run UUID :param run_status: RunStatus to update the run to, optional :param end_time: timestamp to update the run ended_at to, optional :return: :py:class:`mlflow.entities.RunInfo` describing the updated run. """ try: faculty_run = self._client.update_run_info( self._project_id, UUID(run_id), mlflow_to_faculty_run_status(run_status), mlflow_timestamp_to_datetime(end_time), ) except faculty.clients.base.HttpError as e: raise faculty_http_error_to_mlflow_exception(e) else: mlflow_run = faculty_run_to_mlflow_run(faculty_run) return mlflow_run.info
def _search_runs( self, experiment_ids, filter_string, run_view_type, max_results, order_by, page_token, ): """ Return runs that match the given list of search expressions within the experiments, as well as a pagination token (indicating where the next page should start). Subclasses of ``AbstractStore`` should implement this method to support pagination instead of ``search_runs``. See ``search_runs`` for parameter descriptions. :return: A tuple of ``runs`` and ``token`` where ``runs`` is a list of ``mlflow.entities.Run`` objects that satisfy the search expressions, and ``token`` is the pagination token for the next page of results. """ if order_by is not None and order_by != []: raise ValueError("order_by not currently supported") if page_token is not None: raise ValueError("page_token not currently supported") try: filter = build_search_runs_filter( experiment_ids, filter_string, run_view_type ) except mlflow_faculty.filter.MatchesNothing: return [], None except ValueError as e: raise MlflowException(str(e)) def _get_runs(): response = self._client.query_runs(self._project_id, filter) for run in response.runs: yield run next_page = response.pagination.next while next_page is not None: response = self._client.query_runs( self._project_id, filter, start=next_page.start, limit=next_page.limit, ) for run in response.runs: yield run next_page = response.pagination.next try: run_generator = _get_runs() faculty_runs = list(islice(run_generator, max_results)) except faculty.clients.base.HttpError as e: raise faculty_http_error_to_mlflow_exception(e) mlflow_runs = [faculty_run_to_mlflow_run(run) for run in faculty_runs] return mlflow_runs, None