Categorygithub.com/StatCan/jupyter-apis
modulepackage
0.0.0-20240703125603-b1de1704c8f5
Repository: https://github.com/statcan/jupyter-apis.git
Documentation: pkg.go.dev

# README

(Français)

Jupyter Application Programming Interfaces

A Golang replacement for the Kubeflow Jupyter Web APIs.

How to Contribute

See CONTRIBUTING.md

Development Environment

Note that the frontend will report errors when calling /api/namespaces when run locally. This issue does not arise in production, as the /api/namespaces endpoint is unused.

To initialize the .env file for the development environment, use task env. You will need to fill out your kubeflow cloud account and kubeflow namespace information manually. The thunder-tests folder contains configuration for testing requests against the backend. Use the vscode THUNDER CLIENT extension to load the tests.

Run API Server

The API server will connect to the Kubeflow cluster from your current kubectl context. See Connecting a Kubeflow cluster below for options.

  1. Install Go
  2. Change directory to project root: cd jupyter-apis
  3. Run go run . -spawner-config samples/spawner_ui_config.yaml

Alternatively,

  1. task go:dev -w -- -spawner-config samples/spawner_ui_config.yaml will live-reload the Go server upon changes.

Recommended

You can use the vscode debugger to run the backend, just copy the below contents to a file at path .vscode/launch.json.

{
  "version": "0.2.0",
  "configurations": [
      {
          "name": "Debug jupyter-api backend",
          "type": "go",
          "request": "launch",
          "mode": "debug",
          "program": ".",
          "args": [
              "-spawner-config",
              "samples/spawner_ui_config.yaml",
          ],
          "envFile": "${workspaceFolder}/.env"
      }
  ]
}

Run Front-End

The front-end is configured to proxy requests to the local API server. It requires an environment variable (KF_USER_ID) to specify the current user – this is passed to the API server as an HTTP header.

The following can be pasted in a script and executed. This uses the latest node lts/gallium version(v16.20.0) with npm v8(8.19.4). NOTE: user is when using vagrant. Use the email adress if it is the dev cluser (please never connect to prod directly)

cd frontend/common/kubeflow-common-lib
npm i
npm run build
npm link ./dist/kubeflow

cd ../../jupyter
npm i
npm link kubeflow
KF_USER_ID=user npm start

For the kubecost data to be retrievable when running locally, the following will need to be executed kubectl port-forward -n kubecost-system deployment/kubecost-cost-analyzer 9090

Testing backend Rest API

To test the backend, install the Thunder Client extension. After being installed, it should appear in the vs code sidebar (it might require a restart first). First thing is to make sure that the backend is running. Then, open Thunder Client from the vs code sidebar. You should be able to see multiple requests that can be made against the backend under the "Collections" tab, in the "Golang kubeflow" dropdown. From there, just select a request and hit "Send". Some requests require certain parameters to have values. Those can be filled up under the "Env" tab.

Running intergration tests

We use Cypress to make our end-to-end tests. To run integration tests locally, first make sure that the jupyter-apis app is up and running. Then, from the jupyter-apis/frontend/jupyter directory, run either npm run ui-test to open the Cypress UI, or npm run ui-test-ci to run the cypress tests just in the terminal.

Connecting a Kubeflow Cluster

The API server will connect to the Kubeflow cluster from your current kubectl context. Here are a couple options for setting that up.

Local MiniKF Cluster

This deploys a Kubeflow cluster on your local machine and requires at least 50GB of disk space and the recommanded RAM is 12 Gb. First, create the miniKF cluster:

  1. Install Vagrant and Virtual Box.
  2. Create a new directory and run vagrant init arrikto/minikf and then vagrant up (takes about 20 minutes to boot).
  3. Navigate to http://10.10.10.10.
  4. Follow on-screen steps to start Kubeflow and Rok (takes about another 20 minutes).
  5. From here, you can use Kubeflow and Rok.

Then configure kubectl to connect to your new cluster:

  1. Download the miniKF kubectl config file from http://10.10.10.10.
  2. Use the downloaded configuration for kubectl, either replacing, or merging it into, ~/.kube/config.
  3. Ensure kubectl config current-context is pointing to your local cluster.

Your KF_USER_ID can be the default user that was created for your miniKF cluster (typically user).

Each time you need to start the cluster, navigate to the directory you created and run vagrant up.

Note: after some experimentation, it was found that the vagrant file could be modified on line 57 to use 8gb instead of the default 12.

  config.vm.provider "virtualbox" do |vb|
    # Display the VirtualBox GUI when booting the machine
    #vb.gui = true

    # Customize the amount of memory on the VM:
    vb.memory = "8192"
  end

Remote AKS Cluster

  1. Install Azure CLI az and kubectl
  2. Login with az and set your subscription
  3. Run az aks get-credentials for the desired remote cluster
  4. Ensure kubectl config current-context is pointing to correct cluster

On platform testing

Any push to an open PR that has the auto-deploy label on it allows developers to opt-in to on-platform testing. For example, when you need to build in github and test on platform (or want someone else to be able to pull your image):

  1. open a PR and add the auto-deploy label
  2. push to your PR and watch the GitHub Action CI
  3. access your image in Kubeflow DEV via a custom image from any of:
    • k8scc01covidacrdev.azurecr.io/IMAGENAME:SHA
    • k8scc01covidacrdev.azurecr.io/IMAGENAME:SHORT_SHA

Whats Different?

Routes are defined in this repository here.

Upstream, the endpoints are structures via request type (e.g. GET, PUT, DELETE).

Note

  • that not all endpoints are included in the golang implementation
  • to find the upstream endpoint, load the Upstream and use search with the endpoint text!
Request TypeGolang EndpointUpstream Python EndpointPurpose
GET/api/config/api/configGets the spawner_ui_config.yaml
GET/api/gpus/api/gpusReads the GPU vendors from the spawner config
GET/api/storageclasses/api/storageclasseslist all storageclasses
GET/api/storageclasses/default/api/storageclasses/defaultgets the storage class with the is-default-class annotation
GET/api/namespaces/{namespace}/cost/allocationNot foundGet the kubecost Allocation API
GET/api/namespaces/api/namespacesGet the list of namespaces
GET/api/namespaces/{namespace}Not foundGet namespace metadata
GET/api/namespaces/{namespace}/notebooks/api/namespaces/<namespace>/notebooksGet the list of notebooks
POST/api/namespaces/{namespace}/notebooks/api/namespaces/<namespace>/notebooksCreate a notebook
GET/api/namespaces/{namespace}/notebooks/{notebook}/api/namespaces/<namespace>/notebooks/<name>Get a notebook
GET/api/namespaces/{namespace}/notebooks/{notebook}/pod/api/namespaces/<namespace>/notebooks/<notebook_name>/podGets pod of notebook
GET/api/namespaces/{namespace}/notebooks/{notebook}/pod/{pod_name}/logs/api/namespaces/<namespace>/notebooks/<notebook_name>/pod/<pod_name>/logsGets logs of pod of notebook
GET/api/namespaces/{namespace}/notebooks/{notebook}/events/api/namespaces/<namespace>/notebooks/<notebook_name>/eventsGets events of notebook
DELETE/api/namespaces/{namespace}/notebooks/{notebook}/api/namespaces/<namespace>/notebooks/<notebook>Delete a notebook
PATCH/api/namespaces/{namespace}/notebooks/{notebook}/api/namespaces/<namespace>/notebooks/<notebook>Update a notebook
GET/api/namespaces/{namespace}/pvcs/api/namespaces/<namespace>/pvcsList PVCs
GET/api/namespaces/{namespace}/pvcs/{pvc}/api/namespaces/<namespace>/pvcs/<pvc_name>Gets a PVC
DELETE/api/namespaces/{namespace}/pvcs/{pvc}/api/namespaces/<namespace>/pvcs/<pvc>Delete a PVC
GET/api/namespaces/{namespace}/pvcs/{pvc}/pods/api/namespaces/<namespace>/pvcs/<pvc_name>/podsGets pods of a PVC
GET/api/namespaces/{namespace}/pvcs/{pvc}/events/api/namespaces/<namespace>/pvcs/<pvc_name>/eventsGets events of a PVC
GET/api/namespaces/{namespace}/poddefaults/api/namespaces/<namespace>/poddefaultsGet PodDefaults for a given namespace

# Functions

No description provided by the author
No description provided by the author
Set the status of the pvc https://github.com/kubeflow/kubeflow/blob/v1.7.0/components/crud-web-apps/volumes/backend/apps/common/status.py#L4.

# Constants

AutoMountLabel is the label name to automount blob-csi volumes.
DefaultServiceAccountName String.
EnvKfLanguage String.
LastActivityAnnotation is the annotation name for the last activity value.
NotebookPhaseError represents the error phase of a notebook.
NotebookPhaseReady represents the ready phase of a notebook.
NotebookPhaseStopped represents the stopped phase of a notebook.
NotebookPhaseTerminating represents the terminating phase of a notebook.
NotebookPhaseUnavailable represents the unavailable phase of a notebook.
NotebookPhaseUnitialized represents the uninitialized phase of a notebook.
NotebookPhaseWaiting represents the waiting phase of a notebook.
NotebookPhaseWarning represents the warning phase of a notebook.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
ServerTypeAnnotation is the annotation name representing the server type of the notebook.
SharedMemoryVolumeName String.
SharedMemoryVolumePath String.
StoppedAnnotation is the annotation name present on stopped resources.

# Structs

No description provided by the author
No description provided by the author
APIResponseBase contains the basic fields of a response from the APIs.
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
No description provided by the author
Structs for the yaml versions of definitions, minimalistic as it is just a default can't re-use structs from go since this is yaml and not json.
No description provided by the author

# Interfaces

APIResponse represents the response to an API call.