Skip to content

Commit

Permalink
Tf2OpenAPI: Add CLI documentation (kubeflow#220)
Browse files Browse the repository at this point in the history
* Add CLI documentation

* Add cobra as explicit dependency

* update README with correct command
  • Loading branch information
jc2729 authored and k8s-ci-robot committed Jul 9, 2019
1 parent 248a09e commit ce876aa
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 15 deletions.
1 change: 1 addition & 0 deletions Gopkg.lock

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

3 changes: 2 additions & 1 deletion Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ required = [
"sigs.k8s.io/controller-runtime/pkg/source",
"sigs.k8s.io/testing_frameworks/integration", # for integration testing
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1",
"github.com/tensorflow/tensorflow/tensorflow/go", # for tensorflow protos
"github.com/tensorflow/tensorflow/tensorflow/go", # for tensorflow protos,
"github.com/spf13/cobra"
]

[prune]
Expand Down
20 changes: 19 additions & 1 deletion tools/tf2openapi/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
# Tf2OpenAPI
This tool takes TensorFlow SavedModel files as inputs and generates OpenAPI 3.0 specifications for HTTP prediction requests. The SavedModel files must contain signature definitions (SignatureDefs) for models.

## Usage
```
Usage:
tf2openapi [flags]
Required Flags:
-m, --model_base_path string Absolute path of SavedModel file
Flags:
-h, --help help for tf2openapi
-m, --model_base_path string Absolute path of SavedModel file
-n, --name string Name of model (default "model")
-o, --output_file string Absolute path of file to write OpenAPI spec to
-s, --signature_def string Serving Signature Def Key
-v, --version string Model version (default "1")
```

## Overview
### Use Cases for OpenAPI
This project is motivated by the following uses of an OpenAPI specification:
Expand All @@ -14,5 +32,5 @@ The outcome of this project is a TensorFlow-to-OpenAPI transformer which takes S
## Caveats
* There is a dependency on protobufs defined by TensorFlow, e.g. [tensorflow/core/protobuf](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/core/protobuf). Specific protos must be compiled into Go using [protoc](https://github.com/golang/protobuf/tree/master/protoc-gen-go) in the order: tensorflow/core/lib/core/\*.proto, tensorflow/core/framework/\*.proto, tensorflow/core/protobuf/saver.proto, tensorflow/core/protobuf/meta_graph.proto, tensorflow/core/protobuf/saved_model.proto. See Makefile which will automate this.

## TensorFlow Compatibility
## TensorFlow Compatibility
* This tool is compatible with TensorFlow versions 1.xx up to and including 1.13.1. To make it compatible with future TensorFlow versions, you will need to compile the TensorFlow protos and convert them to the internal models. See [DEVELOPER_GUIDE](DEVELOPER_GUIDE.md) for potential issues and solutions.
44 changes: 31 additions & 13 deletions tools/tf2openapi/cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,61 @@
package main

import (
"flag"
"github.com/golang/protobuf/proto"
"github.com/kubeflow/kfserving/tools/tf2openapi/generator"
pb "github.com/kubeflow/kfserving/tools/tf2openapi/generated/protobuf"
"github.com/kubeflow/kfserving/tools/tf2openapi/generator"
"github.com/spf13/cobra"
"io/ioutil"
"log"
"os"
)

var (
model = flag.String("model", "", "Absolute path of SavedModel file")
outFile = flag.String("output-file", "", "Absolute path of file to write OpenAPI spec to")
sigDefKey = flag.String("signature-def", "", "Serving Signature Def Key ")
modelBasePath string
modelName string
modelVersion string
sigDefKey string
outFile string
)

/** Convert SavedModel to OpenAPI. Note that the SavedModel must have at least one signature defined**/
func main() {
flag.Parse()
if *model == "" {
log.Fatalln("Please specify the absolute path of the SavedModel file")
rootCmd := &cobra.Command{
Use: "tf2openapi",
Short: "tf2openapi is an OpenAPI generator for TensorFlow SavedModels",
Long: `This tool takes TensorFlow SavedModel files as inputs and generates OpenAPI 3.0
specifications for HTTP prediction requests. The SavedModel files must
contain signature definitions (SignatureDefs) for models.`,
Run: viewAPI,
}

rootCmd.Flags().StringVarP(&modelBasePath, "model_base_path", "m", "", "Absolute path of SavedModel file")
rootCmd.MarkFlagRequired("model_base_path")
rootCmd.Flags().StringVarP(&modelName, "name", "n", "model", "Name of model")
rootCmd.Flags().StringVarP(&modelVersion, "version", "v", "1", "Model version")
rootCmd.Flags().StringVarP(&outFile, "output_file", "o", "", "Absolute path of file to write OpenAPI spec to")
rootCmd.Flags().StringVarP(&sigDefKey, "signature_def", "s", "", "Serving Signature Def Key")
if err := rootCmd.Execute(); err != nil {
log.Fatalln(err.Error())
}
}

modelPb, err := ioutil.ReadFile(*model)
func viewAPI(cmd *cobra.Command, args []string) {
modelPb, err := ioutil.ReadFile(modelBasePath)
if err != nil {
log.Fatalf("Error reading file %s \n%s", *model, err.Error())
log.Fatalf("Error reading file %s \n%s", modelBasePath, err.Error())
}

/** Convert Go struct to inner model */
model := UnmarshalSavedModelPb(modelPb)

/** Schema generation example **/
spec, err := generator.GenerateOpenAPI(model, *sigDefKey)
spec, err := generator.GenerateOpenAPI(model, sigDefKey)
if err != nil {
log.Fatalln(err.Error())
}
if *outFile != "" {
f, err := os.Create(*outFile)
if outFile != "" {
f, err := os.Create(outFile)
if err != nil {
panic(err)
}
Expand Down

0 comments on commit ce876aa

Please sign in to comment.