Skip to content

Commit

Permalink
Create KFServing Python SDK (kubeflow#218)
Browse files Browse the repository at this point in the history
  • Loading branch information
jinchihe authored and k8s-ci-robot committed Jul 12, 2019
1 parent 8c1088a commit de69399
Show file tree
Hide file tree
Showing 151 changed files with 22,358 additions and 70 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ bin

# development overlay for image patch not to be checked in
config/overlays/development/manager_image_patch.yaml

# swagger-codegen tools
hack/sdk-gen/swagger-codegen-cli.jar
81 changes: 76 additions & 5 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ required = [
"k8s.io/client-go/plugin/pkg/client/auth/gcp", # for development against gcp
"k8s.io/code-generator/cmd/client-gen", # for go generate
"k8s.io/code-generator/cmd/deepcopy-gen", # for go generate
"k8s.io/code-generator/cmd/openapi-gen", # for go generate
"sigs.k8s.io/controller-tools/cmd/controller-gen", # for crd/rbac generation
"sigs.k8s.io/controller-runtime/pkg/client/config",
"sigs.k8s.io/controller-runtime/pkg/controller",
Expand Down Expand Up @@ -73,6 +74,10 @@ version="v1.4.7"
name = "k8s.io/client-go"
version = "kubernetes-1.12.6"

[[constraint]]
name = "k8s.io/kube-openapi"
branch = "release-1.10"

[[override]]
name = "github.com/tensorflow/tensorflow"
version = "=v1.13.1"
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ ifndef GOPATH
endif
go generate ./pkg/... ./cmd/...
hack/update-codegen.sh
hack/update-openapigen.sh

# Build the docker image
docker-build: test
Expand Down
76 changes: 76 additions & 0 deletions cmd/spec-gen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Copyright 2019 kubeflow.org.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
"encoding/json"
"fmt"
"os"
"strings"

"github.com/go-openapi/spec"
kfsvcv1alpha1 "github.com/kubeflow/kfserving/pkg/apis/serving/v1alpha1"
"k8s.io/klog"
"k8s.io/kube-openapi/pkg/common"
)

// Generate OpenAPI spec definitions for KFService Resource
func main() {
if len(os.Args) <= 1 {
klog.Fatal("Supply a version")
}
version := os.Args[1]
if !strings.HasPrefix(version, "v") {
version = "v" + version
}
oAPIDefs := kfsvcv1alpha1.GetOpenAPIDefinitions(func(name string) spec.Ref {
return spec.MustCreateRef("#/definitions/" + common.EscapeJsonPointer(swaggify(name)))
})
defs := spec.Definitions{}
for defName, val := range oAPIDefs {
defs[swaggify(defName)] = val.Schema
}
swagger := spec.Swagger{
SwaggerProps: spec.SwaggerProps{
Swagger: "2.0",
Definitions: defs,
Paths: &spec.Paths{Paths: map[string]spec.PathItem{}},
Info: &spec.Info{
InfoProps: spec.InfoProps{
Title: "KFServing",
Description: "Python SDK for KFServing",
Version: version,
},
},
},
}
jsonBytes, err := json.MarshalIndent(swagger, "", " ")
if err != nil {
klog.Fatal(err.Error())
}
fmt.Println(string(jsonBytes))
}


func swaggify(name string) string {
name = strings.Replace(name, "github.com/kubeflow/kfserving/pkg/apis/serving/", "", -1)
name = strings.Replace(name, "github.com/knative/pkg/apis.", "knative/", -1)
name = strings.Replace(name, "k8s.io/api/core/", "", -1)
name = strings.Replace(name, "k8s.io/apimachinery/pkg/apis/meta/", "", -1)
name = strings.Replace(name, "/", ".", -1)
return name
}
22 changes: 22 additions & 0 deletions hack/sdk-gen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

# Readme for Generating KFServing SDK

The guide shows how to generate the openapi model and swagger.json file from kersering types using `openapi-gen` and generate KFServing python sdk for the python object models using `swagger-codegen`.

## Generate openapi spec and swagger file.

From KFServing root folder, you can `make generate` or execute the below script directly to generate openapi spec and swagger file.

```
./hack/update-openapigen.sh
```
After executing, the `openapi_generated.go` and `swagger.json` are generated and stored under `pkg/apis/serving/v1alpha1/`.

## Generate KFServing Python SDK

From KFSering root folder, execute the script `hack/sdk-gen/sdk-gen.sh` to install swagger-codegen and generate KFServing Python SDK, or you can install customized swagger-codegen and generate SDK manually following the [guide](https://github.com/swagger-api/swagger-codegen#getting-started) of swagger-codegen.

```
./hack/sdk-gen/sdk-gen.sh
```
After the script execution, the kfserving Python SDK is generated in the `sdk` directory.
32 changes: 32 additions & 0 deletions hack/sdk-gen/sdk-gen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash

# Copyright 2019 The Kubeflow Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -o errexit
set -o nounset

SWAGGER_JAR_URL="http://central.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.6/swagger-codegen-cli-2.4.6.jar"
SWAGGER_CODEGEN_JAR="hack/sdk-gen/swagger-codegen-cli.jar"
SWAGGER_CODEGEN_CONF="hack/sdk-gen/swagger_config.json"
SWAGGER_CODEGEN_FILE="pkg/apis/serving/v1alpha1/swagger.json"
SDK_OUTPUT_PATH="sdk"

echo "Downloading the swagger-codegen JAR package ..."
wget -O ${SWAGGER_CODEGEN_JAR} ${SWAGGER_JAR_URL}

echo "Generating Python SDK for KFServing ..."
java -jar ${SWAGGER_CODEGEN_JAR} generate -i ${SWAGGER_CODEGEN_FILE} -l python -o ${SDK_OUTPUT_PATH} -c ${SWAGGER_CODEGEN_CONF}

echo "KFServing Python SDK is generated successfully to folder ${SDK_OUTPUT_PATH}/."
11 changes: 11 additions & 0 deletions hack/sdk-gen/swagger_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"packageName" : "kfserving",
"projectName" : "kfserving",
"packageVersion": "0.1",
"importMappings": {
"V1Container": "from kubernetes.client import V1Container",
"V1ObjectMeta": "from kubernetes.client import V1ObjectMeta",
"V1ListMeta": "from kubernetes.client import V1ListMeta",
"V1ResourceRequirements": "from kubernetes.client import V1ResourceRequirements"
}
}
2 changes: 1 addition & 1 deletion hack/update-codegen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ if [ -z "${GOPATH:-}" ]; then
export GOPATH=$(go env GOPATH)
fi
# Generating KFservice client files
${CODEGEN_PKG}/generate-groups.sh all "github.com/kubeflow/kfserving/pkg/client" "github.com/kubeflow/kfserving/pkg/apis" serving:v1alpha1
${CODEGEN_PKG}/generate-groups.sh all "github.com/kubeflow/kfserving/pkg/client" "github.com/kubeflow/kfserving/pkg/apis" serving:v1alpha1
38 changes: 38 additions & 0 deletions hack/update-openapigen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#!/bin/bash

# Copyright 2019 The Kubeflow Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -o errexit
set -o nounset
set -o pipefail

if [ -z "${GOPATH:-}" ]; then
export GOPATH=$(go env GOPATH)
fi

# Update kative files to add `+k8s:openapi-gen=true` to workaround the knative types cannot be load.
# TBD @jinchihe: This should be updated from knative (PR: https://github.com/knative/pkg/pull/510).
sed -i '/^type Condition struct {/i // +k8s:openapi-gen=true' vendor/github.com/knative/pkg/apis/condition_types.go
sed -i '/^type VolatileTime struct {/i // +k8s:openapi-gen=true' vendor/github.com/knative/pkg/apis/volatile_time.go

# Generating OpenAPI specification
go run vendor/k8s.io/code-generator/cmd/openapi-gen/main.go --input-dirs github.com/kubeflow/kfserving/pkg/apis/serving/v1alpha1,github.com/knative/pkg/apis --output-package github.com/kubeflow/kfserving/pkg/apis/serving/v1alpha1/ --go-header-file hack/boilerplate.go.txt

# Workaroud error "spec redeclared in this block" in unit test.
sed -i 's%spec "github.com/go-openapi/spec"%openapispec "github.com/go-openapi/spec"%g' pkg/apis/serving/v1alpha1/openapi_generated.go
sed -i 's/spec\./openapispec\./g' pkg/apis/serving/v1alpha1/openapi_generated.go

# Generating swagger file
go run cmd/spec-gen/main.go 0.1 > pkg/apis/serving/v1alpha1/swagger.json
Loading

0 comments on commit de69399

Please sign in to comment.