def _list_experiments(): request_message = _get_request_message(ListExperiments()) experiment_entities = _get_tracking_store().list_experiments(request_message.view_type) response_message = ListExperiments.Response() response_message.experiments.extend([e.to_proto() for e in experiment_entities]) response = Response(mimetype='application/json') response.set_data(message_to_json(response_message)) return response
def _list_experiments(): request_message = _get_request_message(ListExperiments()) # `ListFields` returns a list of (FieldDescriptor, value) tuples for *present* fields: # https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html # #google.protobuf.message.Message.ListFields params = {field.name: val for field, val in request_message.ListFields()} experiment_entities = _get_tracking_store().list_experiments(**params) response_message = ListExperiments.Response() response_message.experiments.extend([e.to_proto() for e in experiment_entities]) if experiment_entities.token: response_message.next_page_token = experiment_entities.token response = Response(mimetype="application/json") response.set_data(message_to_json(response_message)) return response
def list_experiments( self, view_type=ViewType.ACTIVE_ONLY, max_results=None, page_token=None, ): """ :param view_type: Qualify requested type of experiments. :param max_results: If passed, specifies the maximum number of experiments desired. If not passed, the server will pick a maximum number of results to return. :param page_token: Token specifying the next page of results. It should be obtained from a ``list_experiments`` call. :return: A :py:class:`PagedList <mlflow.store.entities.PagedList>` of :py:class:`Experiment <mlflow.entities.Experiment>` objects. The pagination token for the next page can be obtained via the ``token`` attribute of the object. """ req_body = message_to_json( ListExperiments(view_type=view_type, max_results=max_results, page_token=page_token)) response_proto = self._call_endpoint(ListExperiments, req_body) experiments = [ Experiment.from_proto(x) for x in response_proto.experiments ] # If the response doesn't contain `next_page_token`, `response_proto.next_page_token` # returns an empty string (default value for a string proto field). token = (response_proto.next_page_token if response_proto.HasField("next_page_token") else None) return PagedList(experiments, token)
def list_experiments(self, view_type=ViewType.ACTIVE_ONLY): """ :return: a list of all known Experiment objects """ req_body = message_to_json(ListExperiments(view_type=view_type)) response_proto = self._call_endpoint(ListExperiments, req_body) return [Experiment.from_proto(experiment_proto) for experiment_proto in response_proto.experiments]
def _list_experiments(): response_message = ListExperiments.Response() experiment_entities = _get_store().list_experiments() response_message.experiments.extend( [e.to_proto() for e in experiment_entities]) response = Response(mimetype='application/json') response.set_data( MessageToJson(response_message, preserving_proto_field_name=True)) return response
def test_get_experiment_by_name(self, store_class): creds = MlflowHostCreds('https://hello') store = store_class(lambda: creds) with mock.patch('mlflow.store.rest_store.http_request') as mock_http: response = mock.MagicMock response.status_code = 200 experiment = Experiment( experiment_id="123", name="abc", artifact_location="/abc", lifecycle_stage=LifecycleStage.ACTIVE) response.text = json.dumps({ "experiment": json.loads(message_to_json(experiment.to_proto()))}) mock_http.return_value = response result = store.get_experiment_by_name("abc") expected_message0 = GetExperimentByName(experiment_name="abc") self._verify_requests(mock_http, creds, "experiments/get-by-name", "GET", message_to_json(expected_message0)) assert result.experiment_id == experiment.experiment_id assert result.name == experiment.name assert result.artifact_location == experiment.artifact_location assert result.lifecycle_stage == experiment.lifecycle_stage # Test GetExperimentByName against nonexistent experiment mock_http.reset_mock() nonexistent_exp_response = mock.MagicMock nonexistent_exp_response.status_code = 404 nonexistent_exp_response.text =\ MlflowException("Exp doesn't exist!", RESOURCE_DOES_NOT_EXIST).serialize_as_json() mock_http.return_value = nonexistent_exp_response assert store.get_experiment_by_name("nonexistent-experiment") is None expected_message1 = GetExperimentByName(experiment_name="nonexistent-experiment") self._verify_requests(mock_http, creds, "experiments/get-by-name", "GET", message_to_json(expected_message1)) assert mock_http.call_count == 1 # Test REST client behavior against a mocked old server, which has handler for # ListExperiments but not GetExperimentByName mock_http.reset_mock() list_exp_response = mock.MagicMock list_exp_response.text = json.dumps({ "experiments": [json.loads(message_to_json(experiment.to_proto()))]}) list_exp_response.status_code = 200 def response_fn(*args, **kwargs): # pylint: disable=unused-argument if kwargs.get('endpoint') == "/api/2.0/mlflow/experiments/get-by-name": raise MlflowException("GetExperimentByName is not implemented", ENDPOINT_NOT_FOUND) else: return list_exp_response mock_http.side_effect = response_fn result = store.get_experiment_by_name("abc") expected_message2 = ListExperiments(view_type=ViewType.ALL) self._verify_requests(mock_http, creds, "experiments/get-by-name", "GET", message_to_json(expected_message0)) self._verify_requests(mock_http, creds, "experiments/list", "GET", message_to_json(expected_message2)) assert result.experiment_id == experiment.experiment_id assert result.name == experiment.name assert result.artifact_location == experiment.artifact_location assert result.lifecycle_stage == experiment.lifecycle_stage # Verify that REST client won't fall back to ListExperiments for 429 errors (hitting # rate limits) mock_http.reset_mock() def rate_limit_response_fn(*args, **kwargs): # pylint: disable=unused-argument raise MlflowException("Hit rate limit on GetExperimentByName", REQUEST_LIMIT_EXCEEDED) mock_http.side_effect = rate_limit_response_fn with pytest.raises(MlflowException) as exc_info: store.get_experiment_by_name("imspamming") assert exc_info.value.error_code == ErrorCode.Name(REQUEST_LIMIT_EXCEEDED) assert mock_http.call_count == 1