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

feat(ws): add swagger config #206

Open
wants to merge 7 commits into
base: notebooks-v2
Choose a base branch
from
Open
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
15 changes: 11 additions & 4 deletions workspaces/backend/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,21 @@ lint: golangci-lint ## Run golangci-lint linter
lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
$(GOLANGCI_LINT) run --fix

##@ Swagger

.PHONY: swag
swag:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will have to add instructions to either user install it or make sure that we install as binary. Do you think we can do similar to what we do on bin? with env test?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, other kubeflow projects "version" the file under api folder:
https://github.com/kubeflow/model-registry/tree/main/api/
https://github.com/kubeflow/pipelines/tree/master/api

Can we do the same? If we have the generated file inside our codebase we add easily to kubeflow docs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swag fmt -g cmd/main.go && swag init -g cmd/main.go -o api/v1/swagger


##@ Build

.PHONY: build
build: fmt vet ## Build backend binary.
build: fmt vet swag ## Build backend binary.
go build -o bin/backend cmd/main.go

.PHONY: run
run: fmt vet ## Run a backend from your host.
.PHONY: run
run: fmt vet swag ## Run a backend from your host.
go run ./cmd/main.go --port=$(PORT)

# If you wish to build the manager image targeting other platforms you can use the --platform flag.
Expand Down Expand Up @@ -144,4 +151,4 @@ GOBIN=$(LOCALBIN) go install $${package} ;\
mv $(1) $(1)-$(3) ;\
} ;\
ln -sf $(1)-$(3) $(1)
endef
endef
18 changes: 18 additions & 0 deletions workspaces/backend/api/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@ limitations under the License.
package api

import (
"fmt"
"log/slog"
"net/http"
"strings"

"github.com/julienschmidt/httprouter"
httpSwagger "github.com/swaggo/http-swagger"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authorization/authorizer"
"sigs.k8s.io/controller-runtime/pkg/client"

_ "github.com/kubeflow/notebooks/workspaces/backend/api/v1/swagger"
"github.com/kubeflow/notebooks/workspaces/backend/internal/config"
"github.com/kubeflow/notebooks/workspaces/backend/internal/repositories"
)
Expand All @@ -51,6 +55,10 @@ const (

// namespaces
AllNamespacesPath = PathPrefix + "/namespaces"

// swagger
SwaggerPath = PathPrefix + "/swagger/*any"
SwaggerYAMLPath = PathPrefix + "/swagger/swagger.yaml"
)

type App struct {
Expand Down Expand Up @@ -102,5 +110,15 @@ func (a *App) Routes() http.Handler {
router.GET(AllWorkspaceKindsPath, a.GetWorkspaceKindsHandler)
router.GET(WorkspaceKindsByNamePath, a.GetWorkspaceKindHandler)

// swagger
router.GET(SwaggerPath, func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
if r.URL.Path == SwaggerYAMLPath {
version := strings.TrimPrefix(PathPrefix, "/")
swaggerFile := fmt.Sprintf("%s/swagger/swagger.yaml", version)
http.ServeFile(w, r, swaggerFile)
return
}
httpSwagger.Handler(httpSwagger.URL(PathPrefix+"/swagger/doc.json")).ServeHTTP(w, r)
})
return a.recoverPanic(a.enableCORS(router))
}
9 changes: 9 additions & 0 deletions workspaces/backend/api/healthcheck_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,17 @@ import (
"net/http"

"github.com/julienschmidt/httprouter"

_ "github.com/kubeflow/notebooks/workspaces/backend/internal/models/health_check"
)

// @Summary Returns the health status of the application
// @Description Provides a healthcheck response indicating the status of key services.
// @Tags healthcheck
// @Produce application/json
// @Success 200 {object} health_check.HealthCheck "Successful healthcheck response"
// @Failure 500 {object} ErrorResponse "Internal server error"
// @Router /healthcheck [get]
func (a *App) GetHealthcheckHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

healthCheck, err := a.repositories.HealthCheck.HealthCheck(Version)
Expand Down
110 changes: 110 additions & 0 deletions workspaces/backend/api/v1/swagger/docs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Package swagger Code generated by swaggo/swag. DO NOT EDIT
package swagger
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mention on other, my suggestion is to serialize into another folder (i.e. openapi) on root of backend


import "github.com/swaggo/swag"

const docTemplate = `{
"schemes": {{ marshal .Schemes }},
"swagger": "2.0",
"info": {
"description": "{{escape .Description}}",
"title": "{{.Title}}",
"contact": {},
"license": {
"name": "License: Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "{{.Version}}"
},
"host": "{{.Host}}",
"basePath": "{{.BasePath}}",
"paths": {
"/healthcheck": {
"get": {
"description": "Provides a healthcheck response indicating the status of key services.",
"produces": [
"application/json"
],
"tags": [
"healthcheck"
],
"summary": "Returns the health status of the application",
"responses": {
"200": {
"description": "Successful healthcheck response",
"schema": {
"$ref": "#/definitions/health_check.HealthCheck"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
}
},
"definitions": {
"api.ErrorResponse": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"health_check.HealthCheck": {
"type": "object",
"properties": {
"status": {
"$ref": "#/definitions/health_check.ServiceStatus"
},
"system_info": {
"$ref": "#/definitions/health_check.SystemInfo"
}
}
},
"health_check.ServiceStatus": {
"type": "string",
"enum": [
"Healthy",
"Unhealthy"
],
"x-enum-varnames": [
"ServiceStatusHealthy",
"ServiceStatusUnhealthy"
]
},
"health_check.SystemInfo": {
"type": "object",
"properties": {
"version": {
"type": "string"
}
}
}
}
}`

// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "1.0.0",
Host: "localhost:4000",
BasePath: "/api/v1",
Schemes: []string{"http", "https"},
Title: "Kubeflow Notebooks API",
Description: "This API provides endpoints to manage notebooks in a Kubernetes cluster.\nFor more information, visit https://www.kubeflow.org/docs/components/notebooks/",
InfoInstanceName: "swagger",
SwaggerTemplate: docTemplate,
LeftDelim: "{{",
RightDelim: "}}",
}

func init() {
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
}
90 changes: 90 additions & 0 deletions workspaces/backend/api/v1/swagger/swagger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
{
"schemes": [
"http",
"https"
],
"swagger": "2.0",
"info": {
"description": "This API provides endpoints to manage notebooks in a Kubernetes cluster.\nFor more information, visit https://www.kubeflow.org/docs/components/notebooks/",
"title": "Kubeflow Notebooks API",
"contact": {},
"license": {
"name": "License: Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
},
"version": "1.0.0"
},
"host": "localhost:4000",
"basePath": "/api/v1",
"paths": {
"/healthcheck": {
"get": {
"description": "Provides a healthcheck response indicating the status of key services.",
"produces": [
"application/json"
],
"tags": [
"healthcheck"
],
"summary": "Returns the health status of the application",
"responses": {
"200": {
"description": "Successful healthcheck response",
"schema": {
"$ref": "#/definitions/health_check.HealthCheck"
}
},
"500": {
"description": "Internal server error",
"schema": {
"$ref": "#/definitions/api.ErrorResponse"
}
}
}
}
}
},
"definitions": {
"api.ErrorResponse": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
}
},
"health_check.HealthCheck": {
"type": "object",
"properties": {
"status": {
"$ref": "#/definitions/health_check.ServiceStatus"
},
"system_info": {
"$ref": "#/definitions/health_check.SystemInfo"
}
}
},
"health_check.ServiceStatus": {
"type": "string",
"enum": [
"Healthy",
"Unhealthy"
],
"x-enum-varnames": [
"ServiceStatusHealthy",
"ServiceStatusUnhealthy"
]
},
"health_check.SystemInfo": {
"type": "object",
"properties": {
"version": {
"type": "string"
}
}
}
}
}
62 changes: 62 additions & 0 deletions workspaces/backend/api/v1/swagger/swagger.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
basePath: /api/v1
definitions:
api.ErrorResponse:
properties:
code:
type: string
message:
type: string
type: object
health_check.HealthCheck:
properties:
status:
$ref: '#/definitions/health_check.ServiceStatus'
system_info:
$ref: '#/definitions/health_check.SystemInfo'
type: object
health_check.ServiceStatus:
enum:
- Healthy
- Unhealthy
type: string
x-enum-varnames:
- ServiceStatusHealthy
- ServiceStatusUnhealthy
health_check.SystemInfo:
properties:
version:
type: string
type: object
host: localhost:4000
info:
contact: {}
description: |-
This API provides endpoints to manage notebooks in a Kubernetes cluster.
For more information, visit https://www.kubeflow.org/docs/components/notebooks/
license:
name: 'License: Apache 2.0'
url: http://www.apache.org/licenses/LICENSE-2.0.html
title: Kubeflow Notebooks API
version: 1.0.0
paths:
/healthcheck:
get:
description: Provides a healthcheck response indicating the status of key services.
produces:
- application/json
responses:
"200":
description: Successful healthcheck response
schema:
$ref: '#/definitions/health_check.HealthCheck'
"500":
description: Internal server error
schema:
$ref: '#/definitions/api.ErrorResponse'
summary: Returns the health status of the application
tags:
- healthcheck
schemes:
- http
- https
swagger: "2.0"
11 changes: 11 additions & 0 deletions workspaces/backend/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ import (
"github.com/kubeflow/notebooks/workspaces/backend/internal/server"
)

// @title Kubeflow Notebooks API
// @version 1.0.0
// @description This API provides endpoints to manage notebooks in a Kubernetes cluster.
// @description For more information, visit https://www.kubeflow.org/docs/components/notebooks/
// @host localhost:4000
// @BasePath /api/v1
// @license.name License: Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @schemes http https
// @consumes application/json
// @produces application/json
func main() {
// Define command line flags
cfg := &config.EnvConfig{}
Expand Down
Loading
Loading