Skip to content

Commit

Permalink
Merge pull request #12 from leonlnj/echo_server_ci
Browse files Browse the repository at this point in the history
Add upi echo server example and ci
  • Loading branch information
leonlnj authored Oct 6, 2022
2 parents 8170722 + 37ca278 commit 82f86cf
Show file tree
Hide file tree
Showing 10 changed files with 351 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
branches: [ main ]
pull_request:
branches: []
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -74,3 +75,5 @@ jobs:
output-file-path: ./gen/python/grpc/output.json
external-data-json-path: ./cache/benchmark-data.json
fail-on-alert: true
upi-echo-server:
uses: ./.github/workflows/publish-upi-echo-server.yaml
96 changes: 96 additions & 0 deletions .github/workflows/publish-upi-echo-server.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: upi-echo-server
on:
workflow_call:
workflow_dispatch:

env:
DOCKER_REGISTRY: ghcr.io
ARTIFACT_RETENTION_DAYS: 1
GO_VERSION: 1.18

jobs:
create-version:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.create_version.outputs.version }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- id: create_version
name: Create version string
run: |
# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
[ "$VERSION" == "main" ] && VERSION=$(git describe --tags --always --first-parent)
# Strip "v" prefix
[[ "${VERSION}" == "v"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# If it's pull request the version string is prefixed by 0.0.0-
[ ${{ github.event_name}} == "pull_request" ] && VERSION="0.0.0-${{ github.event.pull_request.head.sha }}"
echo ${VERSION}
echo "::set-output name=version::${VERSION}"
build:
runs-on: ubuntu-latest
needs:
- create-version
steps:
- uses: actions/checkout@v2
- name: Build Docker image
run: docker build -t upi-echo-server:${{ needs.create-version.outputs.version }} -f example/go/simple/Dockerfile .
- name: Save Docker image
run: docker image save --output upi-echo-server.${{ needs.create-version.outputs.version }}.tar upi-echo-server:${{ needs.create-version.outputs.version }}
- name: Publish Docker Artifact
uses: actions/upload-artifact@v2
with:
name: upi-echo-server.${{ needs.create-version.outputs.version }}.tar
path: upi-echo-server.${{ needs.create-version.outputs.version }}.tar
retention-days: ${{ env.ARTIFACT_RETENTION_DAYS }}

test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: example/go/simple
env:
GOPATH: ${{ github.workspace }}/example/go/simple/.go
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
- name: Test
run: |
go mod tidy
go test ./... -v
release:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
needs:
- create-version
- build
- test
steps:
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Download API Docker Artifact
uses: actions/download-artifact@v2
with:
name: upi-echo-server.${{ needs.create-version.outputs.version }}.tar

- name: Publish Docker Image
env:
CONTAINER_REGISTRY: ${{ env.DOCKER_REGISTRY }}/${{ github.repository_owner }}
run: |
IMAGE_TAG="${{ env.CONTAINER_REGISTRY }}/upi-echo-server:${{ needs.create-version.outputs.version }}"
docker image load --input upi-echo-server.${{ needs.create-version.outputs.version }}.tar
docker tag upi-echo-server:${{ needs.create-version.outputs.version }} ${IMAGE_TAG}
docker push ${IMAGE_TAG}
14 changes: 14 additions & 0 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Universal Prediction Interface Example

## Go Example
### UPI Echo Server
Server will return a dummy metadata and response table with request table if any.

.
├── go/simple
│ ├── client
│ │ └── main.go
│ └── server
│ ├── server.go
│ └── main.go
└── README.md
18 changes: 18 additions & 0 deletions example/go/simple/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM golang:1.18-alpine as build

WORKDIR /app

COPY example/go/simple ./
RUN go mod download
RUN go build -o /upi-echo-server ./server

# Build the application image
FROM alpine:latest

RUN addgroup -S app && adduser -S app -G app
WORKDIR /app
RUN chown -R app:app /app

COPY --chown=app:app --from=build /upi-echo-server /upi-echo-server
USER app
ENTRYPOINT ["/upi-echo-server"]
54 changes: 54 additions & 0 deletions example/go/simple/client/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package main

import (
"context"
"flag"
"log"
"time"

upiv1 "github.com/caraml-dev/universal-prediction-interface/gen/go/grpc/caraml/upi/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

var (
addr = flag.String("addr", "localhost:50051", "the address to connect to")
)

func main() {
flag.Parse()
// Set up a connection to the server.
conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := upiv1.NewUniversalPredictionServiceClient(conn)

// Contact the server and print out its response.
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.PredictValues(ctx, &upiv1.PredictValuesRequest{
PredictionTable: &upiv1.Table{
Name: "Test",
Columns: []*upiv1.Column{
{
Name: "col1",
Type: upiv1.Type_TYPE_DOUBLE,
},
},
Rows: []*upiv1.Row{
{
RowId: "1",
Values: []*upiv1.Value{
{},
},
},
},
},
})
if err != nil {
log.Fatalf("could not call upi server: %v", err)
}
log.Printf("Response: %s", r.String())
}
18 changes: 18 additions & 0 deletions example/go/simple/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module github.com/caraml-dev/universal-prediction-interface/example/simple

go 1.18

require (
github.com/caraml-dev/universal-prediction-interface v0.0.0-20220913065109-8170722e7551
google.golang.org/grpc v1.49.0
)

require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.2 // indirect
golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220810155839-1856144b1d9c // indirect
google.golang.org/protobuf v1.28.1 // indirect
)
25 changes: 25 additions & 0 deletions example/go/simple/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
github.com/caraml-dev/universal-prediction-interface v0.0.0-20220913065109-8170722e7551 h1:nK41mSx5EZWigXbqDropyQLUegcYlV7CUGXjwBYRj0w=
github.com/caraml-dev/universal-prediction-interface v0.0.0-20220913065109-8170722e7551/go.mod h1:dVNvxu+vducr8/hF2g4HUJ51dwV+fJhUd/TizJYWiO4=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.2 h1:BqHID5W5qnMkug0Z8UmL8tN0gAy4jQ+B4WFt8cCgluU=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.2/go.mod h1:ZbS3MZTZq/apAfAEHGoB5HbsQQstoqP92SjAqtQ9zeg=
golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced h1:3dYNDff0VT5xj+mbj2XucFst9WKk6PdGOrb9n+SbIvw=
golang.org/x/net v0.0.0-20220809184613-07c6da5e1ced/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20220810155839-1856144b1d9c h1:IooGDWedfLC6KLczH/uduUsKQP42ZZYhKx+zd50L1Sk=
google.golang.org/genproto v0.0.0-20220810155839-1856144b1d9c/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw=
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
16 changes: 16 additions & 0 deletions example/go/simple/server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import (
"flag"
"fmt"
)

var (
port = flag.Int("port", 50051, "The server port")
)

func main() {
flag.Parse()
upiServer := UpiServer{}
upiServer.Run(fmt.Sprintf(":%d", *port))
}
46 changes: 46 additions & 0 deletions example/go/simple/server/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

import (
"context"
"log"
"net"

upiv1 "github.com/caraml-dev/universal-prediction-interface/gen/go/grpc/caraml/upi/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
)

type UpiServer struct {
upiv1.UnimplementedUniversalPredictionServiceServer
}

func (_ *UpiServer) PredictValues(
_ context.Context,
req *upiv1.PredictValuesRequest,
) (*upiv1.PredictValuesResponse, error) {
return &upiv1.PredictValuesResponse{
Metadata: &upiv1.ResponseMetadata{
Models: []*upiv1.ModelMetadata{
{
Name: "Echo Request Table",
Version: "1",
},
},
},
PredictionResultTable: req.GetPredictionTable(),
}, nil
}

func (us *UpiServer) Run(address string) {
lis, err := net.Listen("tcp", address)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
upiv1.RegisterUniversalPredictionServiceServer(s, us)
reflection.Register(s)
log.Printf("listening on port %s", address)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
61 changes: 61 additions & 0 deletions example/go/simple/server/server_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

import (
"context"
"fmt"
"log"
"os"
"testing"
"time"

upiv1 "github.com/caraml-dev/universal-prediction-interface/gen/go/grpc/caraml/upi/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

const testPort = 50555

var address = fmt.Sprintf(":%d", testPort)

func TestMain(m *testing.M) {

upiServer := UpiServer{}
go upiServer.Run(address)
os.Exit(m.Run())
}

func TestUpiServer_Run(t *testing.T) {

conn, err := grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock())
if err != nil {
log.Fatalf("did not connect: %v", err)
}

defer conn.Close()
c := upiv1.NewUniversalPredictionServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.PredictValues(ctx, &upiv1.PredictValuesRequest{
PredictionTable: &upiv1.Table{
Name: "Test",
Columns: []*upiv1.Column{
{
Name: "col1",
Type: upiv1.Type_TYPE_DOUBLE,
},
},
Rows: []*upiv1.Row{
{
RowId: "1",
Values: []*upiv1.Value{
{},
},
},
},
},
})
if err != nil {
log.Fatalf("could not call upi server: %v", err)
}
log.Printf("Response: %s", r.String())
}

0 comments on commit 82f86cf

Please sign in to comment.