Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] main from kubeflow:main #124

Merged
merged 4 commits into from
Sep 20, 2024
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
17 changes: 13 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Build the model-registry binary
FROM registry.access.redhat.com/ubi8/go-toolset:1.21 AS builder
FROM --platform=$BUILDPLATFORM registry.access.redhat.com/ubi8/go-toolset:1.21 AS builder
ARG TARGETOS
ARG TARGETARCH

WORKDIR /workspace
# Copy the Go Modules manifests
Expand All @@ -14,13 +16,12 @@ RUN yum remove -y nodejs npm
RUN yum module -y reset nodejs
RUN yum module -y enable nodejs:18
# install npm and java for openapi-generator-cli
RUN yum install -y nodejs npm java-11
RUN yum install -y nodejs npm java-11 python3

# Copy the go source
COPY ["Makefile", "main.go", ".openapi-generator-ignore", "openapitools.json", "./"]

# Copy rest of the source
COPY .git/ .git/
COPY cmd/ cmd/
COPY api/ api/
COPY internal/ internal/
Expand All @@ -34,7 +35,15 @@ RUN make deps

# Build
USER root
RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 make clean model-registry

# NOTE: The two instructions below are effectively equivalent to 'make clean build'
# DO NOT REMOVE THE 'build/prepare' TARGET!!!
# It ensures consitent repeatable Dockerfile builds

# prepare the build in a separate layer
RUN make clean build/prepare
# compile separately to optimize multi-platform builds
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} make build/compile

# Use distroless as minimal base image to package the model-registry binary
# Refer to https://github.com/GoogleContainerTools/distroless for more details
Expand Down
58 changes: 46 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,10 @@ openapi/validate: bin/openapi-generator-cli

# generate the openapi server implementation
.PHONY: gen/openapi-server
gen/openapi-server: bin/openapi-generator-cli openapi/validate
@if git diff --cached --exit-code --name-only | grep -q "api/openapi/model-registry.yaml" || \
git diff --exit-code --name-only | grep -q "api/openapi/model-registry.yaml" || \
[ -n "${FORCE_SERVER_GENERATION}" ]; then \
./scripts/gen_openapi_server.sh; \
else \
echo "INFO api/openapi/model-registry.yaml is not staged or modified, will not re-generate server"; \
fi
gen/openapi-server: bin/openapi-generator-cli openapi/validate internal/server/openapi/api_model_registry_service.go

internal/server/openapi/api_model_registry_service.go: bin/openapi-generator-cli api/openapi/model-registry.yaml
ROOT_FOLDER=${PROJECT_PATH} ./scripts/gen_openapi_server.sh

# generate the openapi schema model and client
.PHONY: gen/openapi
Expand All @@ -102,7 +98,7 @@ vet:

.PHONY: clean
clean:
rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/converter/generated/*.go pkg/openapi
rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/converter/generated/*.go pkg/openapi internal/server/openapi/api_model_registry_service.go

.PHONY: clean/odh
clean/odh:
Expand All @@ -122,7 +118,7 @@ bin/protoc-gen-go-grpc:

GOLANGCI_LINT ?= ${PROJECT_BIN}/golangci-lint
bin/golangci-lint:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.59.1
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.61.0

GOVERTER ?= ${PROJECT_BIN}/goverter
bin/goverter:
Expand Down Expand Up @@ -157,10 +153,22 @@ deps: bin/protoc bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/golang
vendor:
${GO} mod vendor

.PHONY: build
build: gen vet lint
# WARNING: DO NOT DELETE THIS TARGET, USED BY Dockerfile!!!
.PHONY: build/prepare
build/prepare: gen vet lint

# WARNING: DO NOT DELETE THIS TARGET, USED BY Dockerfile!!!
.PHONY: build/compile
build/compile:
${GO} build -buildvcs=false

# WARNING: DO NOT EDIT THIS TARGET DIRECTLY!!!
# Use build/prepare to add build prerequisites
# Use build/compile to add/edit go source compilation
# WARNING: Editing this target directly WILL affect the Dockerfile image build!!!
.PHONY: build
build: build/prepare build/compile

.PHONY: build/odh
build/odh: vet
${GO} build -buildvcs=false
Expand Down Expand Up @@ -210,6 +218,32 @@ endif
image/build:
${DOCKER} build . -f ${DOCKERFILE} -t ${IMG}:$(IMG_VERSION)

# build docker image using buildx
# PLATFORMS defines the target platforms for the model registry image be built to provide support to multiple
# architectures. (i.e. make docker-buildx). To use this option you need to:
# - be able to use docker buildx. More info: https://docs.docker.com/build/buildx/
# - have enabled BuildKit. More info: https://docs.docker.com/develop/develop-images/build_enhancements/
# - be able to push the image to your registry (i.e. if you do not set a valid value via IMG=<myregistry/image:<tag>> then the export will fail)
# To adequately provide solutions that are compatible with multiple platforms, you should consider using this option.
PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le
.PHONY: image/buildx
image/buildx:
ifeq ($(DOCKER),docker)
# docker uses builder containers
- $(DOCKER) buildx rm model-registry-builder
$(DOCKER) buildx create --use --name model-registry-builder --platform=$(PLATFORMS)
$(DOCKER) buildx build --push --platform=$(PLATFORMS) --tag ${IMG} -f ${DOCKERFILE} .
$(DOCKER) buildx rm model-registry-builder
else ifeq ($(DOCKER),podman)
# podman uses image manifests
$(DOCKER) manifest create -a ${IMG}
$(DOCKER) buildx build --platform=$(PLATFORMS) --manifest ${IMG} -f ${DOCKERFILE} .
$(DOCKER) manifest push ${IMG}
$(DOCKER) manifest rm ${IMG}
else
$(error Unsupported container tool $(DOCKER))
endif

# push docker image
.PHONY: image/push
image/push:
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Model registry provides a central repository for model developers to store and m

![build checks status](https://github.com/kubeflow/model-registry/actions/workflows/build.yml/badge.svg?branch=main)
[![codecov](https://codecov.io/github/kubeflow/model-registry/graph/badge.svg?token=61URLQA3VS)](https://codecov.io/github/kubeflow/model-registry)
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B162%2Fgithub.com%2Fkubeflow%2Fmodel-registry.svg?type=shield&issueType=license)](https://app.fossa.com/projects/custom%2B162%2Fgithub.com%2Fkubeflow%2Fmodel-registry?ref=badge_shield&issueType=license)

## Pre-requisites:
- go >= 1.21
Expand Down Expand Up @@ -128,10 +129,7 @@ This allows to verify the expected "Core layer" of logical data mapping develope

Python client is also tested with Unit Tests and Integration Tests written in Python.

End-to-end testing is developed with Robot Framework; this higher-lever layer of testing is used to:
- demonstrate *User Stories* from high level perspective
- demonstrate coherent logical data mapping by performing the same high level capabilities, using REST API flow Vs Python client flow,
directly checking the end results in the backend gRPC MLMD server.
End-to-end testing is developed with Pytest and Robot Framework; this higher-lever layer of testing is used to demonstrate *User Stories* from high level perspective.

## FAQ

Expand Down
49 changes: 31 additions & 18 deletions clients/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,27 @@ pip install huggingface-hub

## Basic usage

### Connecting to MR

You can connect to a secure Model Registry using the default constructor (recommended):

```py
from model_registry import ModelRegistry

registry = ModelRegistry("https://server-address", author="Ada Lovelace") # Defaults to a secure connection via port 443
```

# registry = ModelRegistry("http://server-address", 1234, author="Ada Lovelace", is_secure=False) # To use MR without TLS
Or you can set the `is_secure` flag to `False` to connect **without** TLS (not recommended):

```py
registry = ModelRegistry("http://server-address", 8080, author="Ada Lovelace", is_secure=False) # insecure port set to 8080
```

### Registering models

To register your first model, you can use the `register_model` method:

```py

model = registry.register_model(
"my-model", # model name
Expand All @@ -61,11 +76,18 @@ model = registry.register_model(
)

model = registry.get_registered_model("my-model")
print(model)

version = registry.get_model_version("my-model", "2.0.0")
print(version)

experiment = registry.get_model_artifact("my-model", "2.0.0")
print(experiment)
```

You can also update your models:

```py
# change is not reflected on pushed model version
version.description = "Updated model version"

Expand All @@ -79,6 +101,8 @@ When registering models stored on S3-compatible object storage, you should use `
unambiguous URI for your artifact.

```py
from model_registry import utils

model = registry.register_model(
"my-model", # model name
uri=utils.s3_uri_from("path/to/model", "my-bucket"),
Expand Down Expand Up @@ -120,32 +144,21 @@ hf_model = registry.register_hf_model(
There are caveats to be noted when using this method:

- It's only possible to import a single model file per Hugging Face Hub repo right now.
- If the model you want to import is in a global namespace, you should provide an author, e.g.

```py
hf_model = registry.register_hf_model(
"gpt2", # this model implicitly has no author
"onnx/decoder_model.onnx",
author="OpenAI", # Defaults to unknown in the absence of an author
version="1.0.0",
description="gpt-2 model",
model_format_name="onnx",
model_format_version="1",
)
```

### Listing models

To list models you can use
```py
for model in registry.get_registered_models():
...
... # your logic using `model` loop variable here

# and versions associated with a model
for version in registry.get_model_versions("my-model"):
...
... # your logic using `version` loop variable here
```

<!-- see https://github.com/kubeflow/model-registry/issues/358 until fixed, the below is just easier not to mention in the doc.

You can also use `order_by_creation_time`, `order_by_update_time`, or `order_by_id` to change the sorting order

```py
Expand All @@ -154,9 +167,9 @@ for version in latest_updates:
...
```

By default, all queries will be `ascending`, but this method is also available for explicitness.
By default, all queries will be `ascending`, but this method is also available for explicitness. -->

> Note: You can also set the `page_size()` that you want the Pager to use when invoking the Model Registry backend.
> Advanced usage note: You can also set the `page_size()` that you want the Pager to use when invoking the Model Registry backend.
> When using it as an iterator, it will automatically manage pages for you.

#### Implementation notes
Expand Down
1 change: 1 addition & 0 deletions clients/ui/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
**/node_modules
src/__tests__/cypress/cypress/downloads/
dist
yarn-error.log
yarn.lock
Expand Down
Loading