Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
from swagger_server.gateways.kfserving_client import post_service
from swagger_server.gateways.kfserving_client import from_client_upload_service

import logging


def get_inferenceservices(id, namespace=None): # noqa: E501
"""get_inferenceservices
Expand All @@ -32,8 +34,20 @@ def get_inferenceservices(id, namespace=None): # noqa: E501

:rtype: ApiInferenceservice
"""
single_service = get_all_services(id, namespace=namespace)
return single_service, 200
log = logging.getLogger("inf_serv")
# Attempt to find the id in a model mesh predictor
try:
single_service = get_all_services(id, namespace=namespace, group="serving.kserve.io", version="v1alpha1", plural="predictors")
return single_service, 200
except:
pass
# Attempt to find the id in a kserve inferenceservice
try:
single_service = get_all_services(id, namespace=namespace, group="serving.kserve.io", version="v1beta1", plural="inferenceservices")
return single_service, 200
except Exception as err:
log.exception("Error when trying to find an inferenceservice: ")
return str(err), 500


def list_inferenceservices(page_token=None, page_size=None, sort_by=None, filter=None, namespace=None): # noqa: E501
Expand All @@ -54,8 +68,16 @@ def list_inferenceservices(page_token=None, page_size=None, sort_by=None, filter

:rtype: ApiListInferenceservicesResponse
"""
all_services = get_all_services(namespace=namespace)
return all_services, 200
log = logging.getLogger("inf_serv")
try:
# Combine the list of items from the modelmesh predictors and kserve inferenceservices
all_mm_services = get_all_services(namespace=namespace, group="serving.kserve.io", version="v1alpha1", plural="predictors")
all_k_services = get_all_services(namespace=namespace, group="serving.kserve.io", version="v1beta1", plural="inferenceservices")
all_mm_services['items'] = all_mm_services['items'] + all_k_services['items']
return all_mm_services, 200
except Exception as err:
log.exception("Error when trying to list inferenceservices: ")
return str(err), 500


def create_service(body, namespace=None): # noqa: E501
Expand All @@ -70,8 +92,13 @@ def create_service(body, namespace=None): # noqa: E501

:rtype: ApiInferenceservice
"""
created_service = post_service(body, namespace=namespace)
return created_service, 200
log = logging.getLogger("inf_serv")
try:
created_service = post_service(body, namespace=namespace)
return created_service, 200
except Exception as err:
log.exception("Error when deploying an inferenceservice: ")
return str(err), 500


def upload_service(uploadfile, name=None, namespace=None): # noqa: E501
Expand All @@ -88,5 +115,11 @@ def upload_service(uploadfile, name=None, namespace=None): # noqa: E501

:rtype: ApiComponent
"""
uploaded_service = from_client_upload_service(uploadfile, namespace=namespace)
return uploaded_service, 200
log = logging.getLogger("inf_serv")
try:
uploaded_service = from_client_upload_service(upload_file=uploadfile, namespace=namespace)
return uploaded_service, 200
except Exception as err:
log.exception("Error when deploying an inferenceservice: ")
return str(err), 500

81 changes: 61 additions & 20 deletions api/server/swagger_server/gateways/kfserving_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,82 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from kfserving import KFServingClient
import yaml
from kubernetes import client, config


def get_kfserving_client():
client = KFServingClient()
return client
def get_all_services(name=None, namespace=None, group=None, version=None, plural=None):

config.load_incluster_config()
api = client.CustomObjectsApi()

def get_all_services(name=None, namespace=None):
client = get_kfserving_client()
if not namespace:
namespace = 'default'
return client.get(name, namespace=namespace)

if name is None:
resource = api.list_namespaced_custom_object(
group=group,
version=version,
namespace=namespace,
plural=plural,
)
else:
resource = api.get_namespaced_custom_object(
group=group,
version=version,
namespace=namespace,
name=name,
plural=plural,
)
return resource


def post_service(inferenceservice=None, namespace=None, group=None, version=None, plural=None):

config.load_incluster_config()
api = client.CustomObjectsApi()

def post_service(inferenceservice=None, namespace=None):
client = get_kfserving_client()
service_dict = inferenceservice.to_dict()
name = service_dict['metadata']['name']
# Get resource information from the dict
version_split = service_dict['apiVersion'].split("/")
group = version_split[0]
version = version_split[1]
plural = service_dict['kind'].lower() + "s"
if not namespace:
namespace = service_dict['metadata'].get('namespace', 'default')
try:
return client.create(service_dict, namespace=namespace)
except:
return client.patch(name, service_dict, namespace=namespace)

# create the resource
ns_obj = api.create_namespaced_custom_object(
group=group,
version=version,
namespace=namespace,
plural=plural,
body=service_dict,
)
return ns_obj


def from_client_upload_service(upload_file=None, namespace=None):
client = get_kfserving_client()
def from_client_upload_service(upload_file=None, namespace=None, group=None, version=None, plural=None):

config.load_incluster_config()
api = client.CustomObjectsApi()

yaml_object = yaml.safe_load(upload_file)
# Get resource information from the yaml
name = yaml_object['metadata']['name']
version_split = yaml_object['apiVersion'].split("/")
group = version_split[0]
version = version_split[1]
plural = yaml_object['kind'].lower() + "s"
if not namespace:
namespace = yaml_object['metadata'].get('namespace', 'default')
try:
return client.create(yaml_object, namespace=namespace)
except:
return client.patch(name, yaml_object, namespace=namespace)

# create the resource
ns_obj = api.create_namespaced_custom_object(
group=group,
version=version,
namespace=namespace,
plural=plural,
body=yaml_object,
)
return ns_obj
11 changes: 10 additions & 1 deletion dashboard/origin-mlx/src/components/Detail/KFServingDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ export default class KFServingDetail extends React.Component<KFServingDetailProp
const API = this.props.API || ""
const namespace = this.props.namespace || ""
const service = this.state.service
console.log("Asset:")
console.log(this.props.asset)

const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({...this.state, file: e.currentTarget.files[0]})
Expand Down Expand Up @@ -150,7 +152,8 @@ export default class KFServingDetail extends React.Component<KFServingDetailProp
let transformerMessage = ""
//let transformerSeverity = ""

if (service.status) {

if (service.status?.condition) {
for (let conditionIter=0; conditionIter<service.status.conditions.length; conditionIter++) {
let condition = service.status.conditions[conditionIter]
// If this is the DefaultPredictorReady status then scrape some info
Expand Down Expand Up @@ -196,6 +199,12 @@ export default class KFServingDetail extends React.Component<KFServingDetailProp
}
}
}
else {
predictorTimestamp = service.metadata.creationTimestamp
predictorStatusIcon = service.status.activeModelState == "Ready"
? <CheckCircleIcon className="check-icon"/>
: <ErrorIcon className="error-icon"/>
}

return (
<>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ const styles = {
function MetaFeatured(props: MetaFeaturedProps) {
const { assets, classes } = props

console.log("Asset:")
console.log(props.assets)

//return (<h1> Placeholder </h1>)

return (
<div className={classes.wrapper}>
<Grid container
Expand All @@ -52,32 +57,49 @@ function MetaFeatured(props: MetaFeaturedProps) {
>
{assets.map(asset => {
const name = asset.metadata.name;
var runningStatus = asset.status?.conditions[0]?.status || ""
var statusIcon = ""

let runningStatus = ""
let statusIcon = ""
if (asset.status.conditions) {
runningStatus = asset.status?.conditions[0]?.status || ""

if (asset.status) {
for (var i=0; i< asset.status.conditions.length; i++) {
if (asset.status.conditions[i].type === "Ready") {
const index = asset.status.conditions.indexOf(asset.status.conditions[i])
runningStatus = asset.status.conditions[index].status
if (runningStatus === 'True') {
statusIcon = checkmark
}
else {
statusIcon = cancel
if (asset.status) {
for (var i=0; i< asset.status.conditions.length; i++) {
if (asset.status.conditions[i].type === "Ready") {
const index = asset.status.conditions.indexOf(asset.status.conditions[i])
runningStatus = asset.status.conditions[index].status
if (runningStatus === 'True') {
statusIcon = checkmark
}
else {
statusIcon = cancel
}
}
}
}
}
else {
runningStatus = asset.status.available
if (runningStatus === 'true')
statusIcon = checkmark
else
statusIcon = cancel
}
const description = asset.kind;
const tag = Object.keys(asset.spec).join(",")
const link = "inferenceservices"
const predictor = asset.spec.predictor
const framework = predictor.tensorflow ? "tensorflow"
: predictor.keras ? "keras"
: predictor.sklearn ? "sklearn"
: predictor["scikit-learn"] ? "sklearn"
: predictor.pytorch ? "pytorch" : "custom"
let predictor = asset.spec.predictor
let framework = ""
if (asset.spec.predictor) {
framework = predictor.tensorflow ? "tensorflow"
: predictor.keras ? "keras"
: predictor.sklearn ? "sklearn"
: predictor["scikit-learn"] ? "sklearn"
: predictor.pytorch ? "pytorch" : "custom"
}
else {
framework = asset.spec.modelType.name
}
return (
<Grid item key={name} xs md={4}
lg={3} xl={2} className={classes.card} >
Expand Down
3 changes: 3 additions & 0 deletions manifests/base/mlx-deployments/mlx-api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ rules:
- apiGroups: ["serving.knative.dev"]
resources: ["services", "revisions", "configurations"]
verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
- apiGroups: ["serving.kserve.io"]
resources: ["predictors", "inferenceservices"]
verbs: ["get", "list", "create", "update", "delete", "patch", "watch"]
---
apiVersion: v1
kind: ServiceAccount
Expand Down