Skip to content

Commit

Permalink
Adds remaining endpoints for UI PoC (#397)
Browse files Browse the repository at this point in the history
* Simplifies and improves accuracy of API tests

Signed-off-by: Alex Creasy <[email protected]>

* Adds an API endpoint to get a ModelVersion by ID

Signed-off-by: Alex Creasy <[email protected]>

* Adds an API endpoint to create ModelVersions

Signed-off-by: Alex Creasy <[email protected]>

* Adds an API endpoint to update ModelVersions

Signed-off-by: Alex Creasy <[email protected]>

* Adds an API endpoint to get all ModelVersions for a given RegisteredModel

Signed-off-by: Alex Creasy <[email protected]>

* Adds an API endpoint to create a ModelVersion for a given RegisteredModel

Signed-off-by: Alex Creasy <[email protected]>

* Adds an API endpoint to get all ModelArtifacts for a given ModelVersion

Signed-off-by: Alex Creasy <[email protected]>

* Adds an API endpoint to create a ModelArtifact for a given ModelVersion

Signed-off-by: Alex Creasy <[email protected]>

---------

Signed-off-by: Alex Creasy <[email protected]>
  • Loading branch information
alexcreasy authored Sep 18, 2024
1 parent e5422f7 commit 8dbc2e7
Show file tree
Hide file tree
Showing 21 changed files with 1,360 additions and 206 deletions.
109 changes: 101 additions & 8 deletions clients/ui/bff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,21 @@ make docker-build

### Endpoints

| URL Pattern | Handler | Action |
|--------------------------------------------------------------------------------------|-------------------------------|----------------------------------------------|
| GET /v1/healthcheck | HealthcheckHandler | Show application information. |
| GET /v1/model_registry | ModelRegistryHandler | Get all model registries, |
| GET /v1/model_registry/{model_registry_id}/registered_models | GetAllRegisteredModelsHandler | Gets a list of all RegisteredModel entities. |
| POST /v1/model_registry/{model_registry_id}/registered_models | CreateRegisteredModelHandler | Create a RegisteredModel entity. |
| GET /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id} | GetRegisteredModelHandler | Get a RegisteredModel entity by ID |
| PATCH /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id} | UpdateRegisteredModelHandler | Update a RegisteredModel entity by ID |
| URL Pattern | Handler | Action |
|----------------------------------------------------------------------------------------------|----------------------------------------------|-------------------------------------------------------------|
| GET /v1/healthcheck | HealthcheckHandler | Show application information. |
| GET /v1/model_registry | ModelRegistryHandler | Get all model registries, |
| GET /v1/model_registry/{model_registry_id}/registered_models | GetAllRegisteredModelsHandler | Gets a list of all RegisteredModel entities. |
| POST /v1/model_registry/{model_registry_id}/registered_models | CreateRegisteredModelHandler | Create a RegisteredModel entity. |
| GET /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id} | GetRegisteredModelHandler | Get a RegisteredModel entity by ID |
| PATCH /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id} | UpdateRegisteredModelHandler | Update a RegisteredModel entity by ID |
| GET /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id} | GetModelVersionHandler | Get a ModelVersion by ID |
| POST /api/v1/model_registry/{model_registry_id}/model_versions | CreateModelVersionHandler | Create a ModelVersion entity |
| PATCH /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id} | UpdateModelVersionHandler | Update a ModelVersion entity by ID |
| GET /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id}/versions | GetAllModelVersionsForRegisteredModelHandler | Get all ModelVersion entities by RegisteredModel ID |
| POST /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id}/versions | CreateModelVersionForRegisteredModelHandler | Create a ModelVersion entity for a specific RegisteredModel |
| GET /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id}/artifacts | GetAllModelArtifactsByModelVersionHandler | Get all ModelArtifact entities by ModelVersion ID |
| POST /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id}/artifacts | CreateModelArtifactByModelVersion | Create a ModelArtifact entity for a specific ModelVersion |

### Sample local calls
```
Expand Down Expand Up @@ -115,4 +122,90 @@ curl -i -X PATCH "http://localhost:4000/api/v1/model_registry/model-registry/reg
"owner": "eder",
"state": "LIVE"
}}'
```
```
# GET /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id}
curl -i http://localhost:4000/api/v1/model_registry/model-registry/model_versions/1
```
```
# POST /api/v1/model_registry/{model_registry_id}/model_versions
curl -i -X POST "http://localhost:4000/api/v1/model_registry/model-registry/model_versions" \
-H "Content-Type: application/json" \
-d '{ "data": {
"customProperties": {
"my-label9": {
"metadataType": "MetadataStringValue",
"string_value": "val"
}
},
"description": "Version description",
"externalId": "9927",
"name": "ModelVersion One",
"state": "LIVE",
"author": "alex",
"registeredModelId": "1"
}}'
```
```
# PATCH /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id}
curl -i -X PATCH "http://localhost:4000/api/v1/model_registry/model-registry/model_versions/1" \
-H "Content-Type: application/json" \
-d '{ "data": {
"customProperties": {
"my-label9": {
"metadataType": "MetadataStringValue",
"string_value": "val"
}
},
"description": "New description",
"externalId": "9927",
"name": "ModelVersion One",
"state": "LIVE",
"author": "alex",
"registeredModelId": "1"
}}'
```
```
# GET /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id}/versions
curl -i localhost:4000/api/v1/model_registry/model-registry/registered_models/1/versions
```
```
# POST /v1/model_registry/{model_registry_id}/registered_models/{registered_model_id}/versions
curl -i -X POST "http://localhost:4000/api/v1/model_registry/model-registry/registered_models/1/versions" \
-H "Content-Type: application/json" \
-d '{ "data": {
"customProperties": {
"my-label9": {
"metadataType": "MetadataStringValue",
"string_value": "val"
}
},
"description": "New description",
"externalId": "9927",
"name": "ModelVersion One",
"state": "LIVE",
"author": "alex"
}}'
```
```
# GET /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id}/artifacts
curl -i http://localhost:4000/api/v1/model_registry/model-registry/model_versions/1/artifacts
```
```
# POST /api/v1/model_registry/{model_registry_id}/model_versions/{model_version_id}/artifacts
curl -i -X POST "http://localhost:4000/api/v1/model_registry/model-registry/model_versions/1/artifacts" \
-H "Content-Type: application/json" \
-d '{ "data": {
"customProperties": {
"my-label9": {
"metadataType": "MetadataStringValue",
"string_value": "val"
}
},
"description": "New description",
"externalId": "9927",
"name": "ModelArtifact One",
"state": "LIVE",
"artifactType": "TYPE_ONE"
}}'
```
38 changes: 28 additions & 10 deletions clients/ui/bff/api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,23 @@ import (
)

const (
Version = "1.0.0"
PathPrefix = "/api/v1"
ModelRegistryId = "model_registry_id"
RegisteredModelId = "registered_model_id"
HealthCheckPath = PathPrefix + "/healthcheck"
ModelRegistry = PathPrefix + "/model_registry"
RegisteredModelListPath = ModelRegistry + "/:" + ModelRegistryId + "/registered_models"
RegisteredModelPath = RegisteredModelListPath + "/:" + RegisteredModelId
Version = "1.0.0"
PathPrefix = "/api/v1"
ModelRegistryId = "model_registry_id"
RegisteredModelId = "registered_model_id"
ModelVersionId = "model_version_id"
ModelArtifactId = "model_artifact_id"
HealthCheckPath = PathPrefix + "/healthcheck"
ModelRegistryListPath = PathPrefix + "/model_registry"
ModelRegistryPath = ModelRegistryListPath + "/:" + ModelRegistryId
RegisteredModelListPath = ModelRegistryPath + "/registered_models"
RegisteredModelPath = RegisteredModelListPath + "/:" + RegisteredModelId
RegisteredModelVersionsPath = RegisteredModelPath + "/versions"
ModelVersionListPath = ModelRegistryPath + "/model_versions"
ModelVersionPath = ModelVersionListPath + "/:" + ModelVersionId
ModelVersionArtifactListPath = ModelVersionPath + "/artifacts"
ModelArtifactListPath = ModelRegistryPath + "/model_artifacts"
ModelArtifactPath = ModelArtifactListPath + "/:" + ModelArtifactId
)

type App struct {
Expand Down Expand Up @@ -54,7 +63,7 @@ func NewApp(cfg config.EnvConfig, logger *slog.Logger) (*App, error) {
}

if err != nil {
return nil, fmt.Errorf("failed to create ModelRegistry client: %w", err)
return nil, fmt.Errorf("failed to create ModelRegistryListPath client: %w", err)
}

app := &App{
Expand All @@ -78,9 +87,18 @@ func (app *App) Routes() http.Handler {
router.GET(RegisteredModelPath, app.AttachRESTClient(app.GetRegisteredModelHandler))
router.POST(RegisteredModelListPath, app.AttachRESTClient(app.CreateRegisteredModelHandler))
router.PATCH(RegisteredModelPath, app.AttachRESTClient(app.UpdateRegisteredModelHandler))
router.GET(RegisteredModelVersionsPath, app.AttachRESTClient(app.GetAllModelVersionsForRegisteredModelHandler))
router.POST(RegisteredModelVersionsPath, app.AttachRESTClient(app.CreateModelVersionForRegisteredModelHandler))

router.GET(ModelVersionPath, app.AttachRESTClient(app.GetModelVersionHandler))
router.POST(ModelVersionListPath, app.AttachRESTClient(app.CreateModelVersionHandler))
router.PATCH(ModelVersionPath, app.AttachRESTClient(app.UpdateModelVersionHandler))
router.GET(ModelVersionArtifactListPath, app.AttachRESTClient(app.GetAllModelArtifactsByModelVersionHandler))
router.POST(ModelVersionArtifactListPath, app.AttachRESTClient(app.CreateModelArtifactByModelVersionHandler))

// Kubernetes client routes
router.GET(ModelRegistry, app.ModelRegistryHandler)
router.GET(ModelRegistryListPath, app.ModelRegistryHandler)
router.PATCH(ModelRegistryPath, app.AttachRESTClient(app.UpdateModelVersionHandler))

return app.RecoverPanic(app.enableCORS(router))
}
12 changes: 12 additions & 0 deletions clients/ui/bff/api/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,15 @@ func (app *App) ReadJSON(w http.ResponseWriter, r *http.Request, dst any) error

return nil
}

func ParseURLTemplate(tmpl string, params map[string]string) string {
args := make([]string, len(params)*2)

for k, v := range params {
args = append(args, ":"+k, v)
}

r := strings.NewReplacer(args...)

return r.Replace(tmpl)
}
21 changes: 21 additions & 0 deletions clients/ui/bff/api/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package api

import (
"github.com/stretchr/testify/assert"
"testing"
)

func TestParseURLTemplate(t *testing.T) {
expected := "/v1/model_registry/demo-registry/registered_models/111-222-333/versions"
tmpl := "/v1/model_registry/:model_registry_id/registered_models/:registered_model_id/versions"
params := map[string]string{"model_registry_id": "demo-registry", "registered_model_id": "111-222-333"}

actual := ParseURLTemplate(tmpl, params)

assert.Equal(t, expected, actual)
}

func TestParseURLTemplateWhenEmpty(t *testing.T) {
actual := ParseURLTemplate("", nil)
assert.Empty(t, actual)
}
2 changes: 1 addition & 1 deletion clients/ui/bff/api/model_registry_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestModelRegistryHandler(t *testing.T) {
kubernetesClient: mockK8sClient,
}

req, err := http.NewRequest(http.MethodGet, ModelRegistry, nil)
req, err := http.NewRequest(http.MethodGet, ModelRegistryListPath, nil)
assert.NoError(t, err)

rr := httptest.NewRecorder()
Expand Down
Loading

0 comments on commit 8dbc2e7

Please sign in to comment.