Skip to content

Commit

Permalink
Merge pull request #271 from cliveseldon/openapi
Browse files Browse the repository at this point in the history
Add Open API Definitions
  • Loading branch information
ukclivecox authored Oct 28, 2018
2 parents 9a7a0da + 281b005 commit 96d33a1
Show file tree
Hide file tree
Showing 33 changed files with 2,216 additions and 26 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,7 @@ wrappers/python/fbs/
#ONNX example
examples/models/onnx_resnet50/cpu_codegen/Function_0_codegen.cpp
examples/models/onnx_resnet50/resnet.onnx

#openapi
engine/src/main/resources/static/seldon.json
api-frontend/src/main/resources/static/seldon.json
4 changes: 3 additions & 1 deletion api-frontend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ VERSION_FILE=target/version.txt
write_version:
ls target/seldon-apife-*.jar | sed -n 's/target\/seldon-apife-\(.*\).jar$$/\1/p' > $(VERSION_FILE) && cat $(VERSION_FILE)

build_jar: update_proto
build_jar: update_proto update_swagger
mvn clean verify -Dlicense.useMissingFile -B

build_image: build_jar write_version
Expand Down Expand Up @@ -52,3 +52,5 @@ port_forward_api_server:
POD_NAME=$$(kubectl --namespace default get pod -l app=seldon-apiserver-container-app -o template --template="{{(index .items 0).metadata.name}}") && \
kubectl port-forward $${POD_NAME} 8080:8080

update_swagger:
cp -v ../openapi/apife.oas3.json src/main/resources/static/seldon.json
4 changes: 3 additions & 1 deletion api-frontend/Makefile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LOCAL_PRIVATE_REPO=127.0.0.1:5000
build: clean build_image


build_jar: update_proto
build_jar: update_proto update_swagger
@set -x && mvn clean verify -Dlicense.useMissingFile -B

write_version: build_jar
Expand Down Expand Up @@ -47,3 +47,5 @@ update_proto: download_protos
cp -vr ../proto/k8s/k8s.io src/main/proto
cp -v ../proto/k8s/v1.proto src/main/proto

update_swagger:
cp -v ../openapi/apife.oas3.json src/main/resources/static/seldon.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
Expand Down Expand Up @@ -122,7 +123,7 @@ String ping() {
return "pong";
}


@CrossOrigin(origins = "*")
@RequestMapping(value = "/api/v0.1/predictions", method = RequestMethod.POST, consumes = "application/json; charset=utf-8", produces = "application/json; charset=utf-8")
public ResponseEntity<String> prediction(RequestEntity<String> requestEntity,Principal principal) {

Expand Down Expand Up @@ -172,6 +173,7 @@ public ResponseEntity<String> prediction(RequestEntity<String> requestEntity,Pri

}

@CrossOrigin(origins = "*")
@RequestMapping(value = "/api/v0.1/feedback", method = RequestMethod.POST, consumes = "application/json; charset=utf-8", produces = "application/json; charset=utf-8")
@ResponseStatus(value = HttpStatus.OK)
public void feedback(RequestEntity<String> requestEntity, Principal principal)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.seldon.apife.config;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCorsFilter implements Filter {

public SimpleCorsFilter() {
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
HttpServletRequest request = (HttpServletRequest) req;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
//response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization");
response.setHeader("Access-Control-Allow-Headers", "API-Key, accept, Content-Type, x-requested-with, authorization");
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}

@Override
public void init(FilterConfig filterConfig) {
}

@Override
public void destroy() {
}
}
Empty file.
5 changes: 4 additions & 1 deletion engine/Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
IMAGE_NAME=engine
VERSION_FILE=target/version.txt

build_jar: update_proto
build_jar: update_proto update_swagger
mvn clean verify -Dlicense.useMissingFile -B

write_version:
Expand Down Expand Up @@ -37,3 +37,6 @@ update_proto:
@cp -v ../proto/prediction.proto src/main/proto/
cp -vr ../proto/k8s/k8s.io src/main/proto
cp -v ../proto/k8s/v1.proto src/main/proto

update_swagger:
cp -v ../openapi/engine.oas3.json src/main/resources/static/seldon.json
4 changes: 3 additions & 1 deletion engine/Makefile.ci
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LOCAL_PRIVATE_REPO=127.0.0.1:5000
build: clean build_image


build_jar: update_proto
build_jar: update_proto update_swagger
@set -x && mvn clean verify -Dlicense.useMissingFile -B

write_version: build_jar
Expand Down Expand Up @@ -47,3 +47,5 @@ update_proto: download_protos
cp -vr ../proto/k8s/k8s.io src/main/proto
cp -v ../proto/k8s/v1.proto src/main/proto

update_swagger:
cp -v ../openapi/engine.oas3.json src/main/resources/static/seldon.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
Expand Down Expand Up @@ -98,7 +99,7 @@ String unpause() {
return "unpaused";
}


@CrossOrigin(origins = "*")
@RequestMapping(value = "/api/v0.1/predictions", method = RequestMethod.POST, consumes = "application/json; charset=utf-8", produces = "application/json; charset=utf-8")
public ResponseEntity<String> predictions(RequestEntity<String> requestEntity)
{
Expand Down Expand Up @@ -137,6 +138,7 @@ public ResponseEntity<String> predictions(RequestEntity<String> requestEntity)

}

@CrossOrigin(origins = "*")
@RequestMapping(value= "/api/v0.1/feedback", method = RequestMethod.POST, consumes = "application/json; charset=utf-8", produces = "application/json; charset=utf-8")
public ResponseEntity<String> feedback(RequestEntity<String> requestEntity) {
Feedback feedback;
Expand Down Expand Up @@ -173,9 +175,5 @@ public ResponseEntity<String> feedback(RequestEntity<String> requestEntity) {
throw new APIException(ApiExceptionType.ENGINE_INVALID_JSON,"");
}
}

@RequestMapping("/api/v0.1/events")
String events() {
return "Not Implemented";
}

}
Empty file.
14 changes: 14 additions & 0 deletions openapi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@


# Creates a base swagger definition
seldon.grpcapi.swagger.json:
protoc -I/usr/local/include -I. -I${GOPATH}/src -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway --swagger_out=logtostderr=true:. prediction.grpcapi.proto

engine.oa3.json apife.oa3.josn component.oa3.json:
python create_openapis.py

clean:
rm -f engine.oa3.json
rm -f apife.oa3.josn
rm -f component.oa3.json

42 changes: 42 additions & 0 deletions openapi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Open API V3 for Seldon Core API

We provide initial [OpenAPI](https://www.openapis.org/) 3.0 specifications for our APIs

* [Seldon Core External via Ambassador](engine.oas3.json)
* [Seldon Core External via API Gateway](apife.oas3.json)
* [Seldon Core Internal microservice API](wrapper.oas3.json)

You will find the API Specs at runtime at the ```/seldon.json``` path of your API endpoint.

You will need to be running 0.2.4-SNAPSHOT or later for this endpoint to be active.

## Viewing/Testing via Swagger-UI

You can view the APIs using the [Swagger UI tool](https://swagger.io/tools/swagger-ui/).

You can run this via Docker with:

```
docker run --network host --rm swaggerapi/swagger-editor
```

It will be reachable at http://localhost:8080/

![swagger-ui-ambassador](./swagger-ui-ambassador.png)

For using the Swagger "try it out" feature there are some caveats due to Swagger UI bugs:

* For the [Seldon Core External via API Gateway](apife.oas3.json)
* You will need to use a hardwired host, localhost:8002 is provided for Authorization as currently the Swagger UI can't handle variables in Authorization calls.
* You will need to use the browser network console to get the bearer token from the returned json as this is not displayed by the Swagger UI.
* For the [Seldon Internal API](wrapper.oas3.json)
* in GET calls you can't edit the JSON string passed.


## Contributions and Roadmap

We welcome contributions to improving these initial API specifications.

We plan to investigate how these APIs can be customized to show the acceptable payloads for a particular machine learning inference graph running under Seldon Core. Suggestions welcome.


Loading

0 comments on commit 96d33a1

Please sign in to comment.