Skip to content

Commit f84f0f6

Browse files
tariq-hasanshashank-iitbhu
authored andcommitted
Add unit test for create_experiment in the katib_client module (kubeflow#2325)
* added logger for katib_client module Signed-off-by: tariq-hasan <[email protected]> * added API_VERSION as a constant Signed-off-by: tariq-hasan <[email protected]> * updated the KatibClient constructor to match the TrainingClient constructor Signed-off-by: tariq-hasan <[email protected]> * added test for create_experiment in katib_client Signed-off-by: tariq-hasan <[email protected]> --------- Signed-off-by: tariq-hasan <[email protected]>
1 parent 424c0d6 commit f84f0f6

File tree

4 files changed

+301
-19
lines changed

4 files changed

+301
-19
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ pytest: prepare-pytest prepare-pytest-testdata
170170
pytest ./test/unit/v1beta1/suggestion --ignore=./test/unit/v1beta1/suggestion/test_skopt_service.py
171171
pytest ./test/unit/v1beta1/earlystopping
172172
pytest ./test/unit/v1beta1/metricscollector
173+
cp ./pkg/apis/manager/v1beta1/python/api_pb2.py ./sdk/python/v1beta1/kubeflow/katib/katib_api_pb2.py
174+
pytest ./sdk/python/v1beta1/kubeflow/katib
175+
rm ./sdk/python/v1beta1/kubeflow/katib/katib_api_pb2.py
173176

174177
# The skopt service doesn't work appropriately with Python 3.11.
175178
# So, we need to run the test with Python 3.9.

sdk/python/v1beta1/kubeflow/katib/api/katib_client.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import inspect
16+
import logging
1617
import multiprocessing
1718
import textwrap
1819
import time
@@ -27,24 +28,35 @@
2728
from kubernetes import client, config
2829

2930

31+
logger = logging.getLogger(__name__)
32+
33+
3034
class KatibClient(object):
3135
def __init__(
3236
self,
33-
config_file: str = None,
34-
context: str = None,
35-
client_configuration: client.Configuration = None,
37+
config_file: Optional[str] = None,
38+
context: Optional[str] = None,
39+
client_configuration: Optional[client.Configuration] = None,
3640
namespace: str = utils.get_default_target_namespace(),
3741
):
38-
"""KatibClient constructor.
42+
"""KatibClient constructor. Configure logging in your application
43+
as follows to see detailed information from the KatibClient APIs:
44+
.. code-block:: python
45+
import logging
46+
logging.basicConfig()
47+
log = logging.getLogger("kubeflow.katib.api.katib_client")
48+
log.setLevel(logging.DEBUG)
3949
4050
Args:
4151
config_file: Path to the kube-config file. Defaults to ~/.kube/config.
4252
context: Set the active context. Defaults to current_context from the kube-config.
4353
client_configuration: Client configuration for cluster authentication.
4454
You have to provide valid configuration with Bearer token or
45-
with username and password.
46-
You can find an example here: https://github.com/kubernetes-client/python/blob/67f9c7a97081b4526470cad53576bc3b71fa6fcc/examples/remote_cluster.py#L31
47-
namespace: Target Kubernetes namespace. Can be overridden during method invocations.
55+
with username and password. You can find an example here:
56+
https://github.com/kubernetes-client/python/blob/67f9c7a97081b4526470cad53576bc3b71fa6fcc/examples/remote_cluster.py#L31
57+
namespace: Target Kubernetes namespace. By default it takes namespace
58+
from `/var/run/secrets/kubernetes.io/serviceaccount/namespace` location
59+
or set as `default`. Namespace can be overridden during method invocations.
4860
"""
4961

5062
self.in_cluster = False
@@ -131,8 +143,7 @@ def create_experiment(
131143
f"Failed to create Katib Experiment: {namespace}/{experiment_name}"
132144
)
133145

134-
# TODO (andreyvelich): Use proper logger.
135-
print(f"Experiment {namespace}/{experiment_name} has been created")
146+
logger.debug(f"Experiment {namespace}/{experiment_name} has been created")
136147

137148
if self._is_ipython():
138149
if self.in_cluster:
@@ -248,7 +259,7 @@ def tune(
248259

249260
# Create Katib Experiment template.
250261
experiment = models.V1beta1Experiment(
251-
api_version=f"{constants.KUBEFLOW_GROUP}/{constants.KATIB_VERSION}",
262+
api_version=constants.API_VERSION,
252263
kind=constants.EXPERIMENT_KIND,
253264
metadata=models.V1ObjectMeta(name=name, namespace=namespace),
254265
spec=models.V1beta1ExperimentSpec(),
@@ -743,7 +754,7 @@ def wait_for_experiment_condition(
743754
)
744755
):
745756
utils.print_experiment_status(experiment)
746-
print(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
757+
logger.debug(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
747758
return experiment
748759

749760
# Raise exception if Experiment is Failed.
@@ -763,7 +774,7 @@ def wait_for_experiment_condition(
763774
)
764775
):
765776
utils.print_experiment_status(experiment)
766-
print(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
777+
logger.debug(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
767778
return experiment
768779

769780
# Check if Experiment reaches Running condition.
@@ -774,7 +785,7 @@ def wait_for_experiment_condition(
774785
)
775786
):
776787
utils.print_experiment_status(experiment)
777-
print(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
788+
logger.debug(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
778789
return experiment
779790

780791
# Check if Experiment reaches Restarting condition.
@@ -785,7 +796,7 @@ def wait_for_experiment_condition(
785796
)
786797
):
787798
utils.print_experiment_status(experiment)
788-
print(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
799+
logger.debug(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
789800
return experiment
790801

791802
# Check if Experiment reaches Succeeded condition.
@@ -796,12 +807,12 @@ def wait_for_experiment_condition(
796807
)
797808
):
798809
utils.print_experiment_status(experiment)
799-
print(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
810+
logger.debug(f"Experiment: {namespace}/{name} is {expected_condition}\n\n\n")
800811
return experiment
801812

802813
# Otherwise, print the current Experiment results and sleep for the pooling interval.
803814
utils.print_experiment_status(experiment)
804-
print(
815+
logger.debug(
805816
f"Waiting for Experiment: {namespace}/{name} to reach {expected_condition} condition\n\n\n"
806817
)
807818
time.sleep(polling_interval)
@@ -880,7 +891,7 @@ def edit_experiment_budget(
880891
except Exception:
881892
raise RuntimeError(f"Failed to edit Katib Experiment: {namespace}/{name}")
882893

883-
print(f"Experiment {namespace}/{name} has been updated")
894+
logger.debug(f"Experiment {namespace}/{name} has been updated")
884895

885896
def delete_experiment(
886897
self,
@@ -919,8 +930,7 @@ def delete_experiment(
919930
except Exception:
920931
raise RuntimeError(f"Failed to delete Katib Experiment: {namespace}/{name}")
921932

922-
# TODO (andreyvelich): Use proper logger.
923-
print(f"Experiment {namespace}/{name} has been deleted")
933+
logger.debug(f"Experiment {namespace}/{name} has been deleted")
924934

925935
def get_suggestion(
926936
self,

0 commit comments

Comments
 (0)