Skip to content

Commit 31ad5aa

Browse files
authored
[HWORKS-1421] Add option to specify kubernetes namespace at project creation (#336)
1 parent 74828fb commit 31ad5aa

File tree

5 files changed

+44
-14
lines changed

5 files changed

+44
-14
lines changed

python/hopsworks_common/project.py

+7
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def __init__(
5151
services=None,
5252
datasets=None,
5353
creation_status=None,
54+
project_namespace=None,
5455
**kwargs,
5556
):
5657
self._id = project_id
@@ -67,6 +68,7 @@ def __init__(
6768
self._git_api = git_api.GitApi()
6869
self._dataset_api = dataset_api.DatasetApi()
6970
self._environment_api = environment_api.EnvironmentApi()
71+
self._project_namespace = project_namespace
7072

7173
@classmethod
7274
def from_response_json(cls, json_dict):
@@ -101,6 +103,11 @@ def created(self):
101103
"""Timestamp when the project was created"""
102104
return self._created
103105

106+
@property
107+
def project_namespace(self):
108+
"""Kubernetes namespace used by project"""
109+
return self._project_namespace
110+
104111
def get_feature_store(
105112
self, name: Optional[str] = None, engine: Optional[str] = None
106113
): # -> hsfs.feature_store.FeatureStore

python/hsml/core/serving_api.py

+7-11
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def _send_inference_request_via_rest_protocol(
260260
path_params = self._get_istio_inference_path(deployment_instance)
261261
# - add host header
262262
headers["host"] = self._get_inference_request_host_header(
263-
_client._project_name,
263+
deployment_instance.project_namespace,
264264
deployment_instance.name,
265265
client.get_knative_domain(),
266266
)
@@ -291,9 +291,7 @@ def _send_inference_request_via_grpc_protocol(
291291
# the channel, which will be reused in all following calls on the same deployment object.
292292
# The gRPC channel is freed when calling deployment.stop()
293293
print("Initializing gRPC channel...")
294-
deployment_instance._grpc_channel = self._create_grpc_channel(
295-
deployment_instance.name
296-
)
294+
deployment_instance._grpc_channel = self._create_grpc_channel(deployment_instance)
297295
# build an infer request
298296
request = InferRequest(
299297
infer_inputs=data,
@@ -308,11 +306,11 @@ def _send_inference_request_via_grpc_protocol(
308306
# extract infer outputs
309307
return infer_response.outputs
310308

311-
def _create_grpc_channel(self, deployment_name: str):
309+
def _create_grpc_channel(self, deployment_instance):
312310
_client = client.istio.get_instance()
313311
service_hostname = self._get_inference_request_host_header(
314-
_client._project_name,
315-
deployment_name,
312+
deployment_instance.project_namespace,
313+
deployment_instance.name,
316314
client.get_knative_domain(),
317315
)
318316
return _client._create_grpc_channel(service_hostname)
@@ -405,11 +403,9 @@ def get_logs(self, deployment_instance, component, tail):
405403
)
406404

407405
def _get_inference_request_host_header(
408-
self, project_name: str, deployment_name: str, domain: str
406+
self, project_namespace: str, deployment_name: str, domain: str
409407
):
410-
return "{}.{}.{}".format(
411-
deployment_name, project_name.replace("_", "-"), domain
412-
).lower()
408+
return "{}.{}.{}".format(deployment_name, project_namespace, domain).lower()
413409

414410
def _get_hopsworks_inference_path(self, project_id: int, deployment_instance):
415411
return [

python/hsml/deployment.py

+11
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@ def __init__(
3838
predictor,
3939
name: Optional[str] = None,
4040
description: Optional[str] = None,
41+
project_namespace: str = None,
4142
**kwargs,
4243
):
4344
self._predictor = predictor
4445
self._description = description
46+
self._project_namespace = project_namespace
4547

4648
if self._predictor is None:
4749
raise ModelServingException("A predictor is required")
@@ -476,6 +478,15 @@ def environment(self):
476478
def environment(self, environment: str):
477479
self._predictor.environment = environment
478480

481+
@property
482+
def project_namespace(self):
483+
"""Name of inference environment"""
484+
return self._predictor.project_namespace
485+
486+
@project_namespace.setter
487+
def project_namespace(self, project_namespace: str):
488+
self._predictor.project_namespace = project_namespace
489+
479490
def __repr__(self):
480491
desc = (
481492
f", description: {self._description!r}"

python/hsml/predictor.py

+13
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def __init__(
6262
creator: Optional[str] = None,
6363
api_protocol: Optional[str] = INFERENCE_ENDPOINTS.API_PROTOCOL_REST,
6464
environment: Optional[str] = None,
65+
project_namespace: str = None,
6566
**kwargs,
6667
):
6768
serving_tool = (
@@ -98,6 +99,7 @@ def __init__(
9899
self._validate_script_file(self._model_framework, self._script_file)
99100
self._api_protocol = api_protocol
100101
self._environment = environment
102+
self._project_namespace = project_namespace
101103

102104
def deploy(self):
103105
"""Create a deployment for this predictor and persists it in the Model Serving.
@@ -278,6 +280,7 @@ def extract_fields_from_json(cls, json_decamelized):
278280
if "environment_dto" in json_decamelized:
279281
environment = json_decamelized.pop("environment_dto")
280282
kwargs["environment"] = environment["name"]
283+
kwargs["project_namespace"] = json_decamelized.pop("project_namespace")
281284
return kwargs
282285

283286
def update_from_response_json(self, json_dict):
@@ -305,6 +308,7 @@ def to_dict(self):
305308
"servingTool": self._serving_tool,
306309
"predictor": self._script_file,
307310
"apiProtocol": self._api_protocol,
311+
"project_namespace": self._project_namespace,
308312
}
309313
if self.environment is not None:
310314
json = {**json, **{"environmentDTO": {"name": self._environment}}}
@@ -478,6 +482,15 @@ def environment(self):
478482
def environment(self, environment):
479483
self._environment = environment
480484

485+
@property
486+
def project_namespace(self):
487+
"""Kubernetes project namespace"""
488+
return self._project_namespace
489+
490+
@project_namespace.setter
491+
def project_namespace(self, project_namespace):
492+
self._project_namespace = project_namespace
493+
481494
def __repr__(self):
482495
desc = (
483496
f", description: {self._description!r}"

python/tests/fixtures/predictor_fixtures.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
},
4444
"environment_dto": {
4545
"name": "misc-inference-pipeline"
46-
}
46+
},
47+
"project_namespace": "test"
4748
}
4849
]
4950
}
@@ -98,7 +99,8 @@
9899
},
99100
"environment_dto": {
100101
"name": "misc-inference-pipeline"
101-
}
102+
},
103+
"project_namespace": "test"
102104
},
103105
{
104106
"id": 2,
@@ -140,7 +142,8 @@
140142
},
141143
"environment_dto": {
142144
"name": "misc-inference-pipeline"
143-
}
145+
},
146+
"project_namespace": "test"
144147
}
145148
]
146149
}

0 commit comments

Comments
 (0)