python-3.xjupyterjupyter-labgoogle-cloud-vertex-ai

Programmatically shutting down jupyterlab kernels


My team is trying to cut our cloud cost budget via shutting down all kernels, open terminals inside Jupyterlab. This can be easily done by navigating to the open kernels section, then clicking Shut Down All for both kernels and terminals. While this works, other users are working and they would just restart their kernels. Our idea is to have a script shut down all kernels and terminals at some point when everyone is stopped working.

This being said, I have had some difficulty with just shutting down a single jupyterlab kernel in the command line. Is it possible to shut down a jupyter kernel through command line? I would like something similar to the following:

jupyter --change_kernel None file.ipynb

Attempts

  1. kill -9 {ipynb_pid}.
    Killing a jupyterlab pid does not shut down the kernel. Jupyter thinks this is an error, and subsequently restarts it in another pid.

  2. modify the metadata to have No kernel.
    As per this post, I have tried to change the kernel by editing the json of the ipynb files that I want to kill. I.e. jq '.metadata.kernel="None"' my_file.ipynb > my_file.ipynb. This leads to very spicy overwrite issues. Also, if there are unsaved changes, this does not play nice.


Solution

  • Here is a PowerShell function I wrote to solve just this -

    function DeleteJupyterKernel {
        param (
            [string]$baseUrl = "http://localhost:8888" ,    # Base URL of your Jupyter server
            [string]$token = "mytoken",      # Your Jupyter access token
            [string]$kernelId    # ID of the kernel to delete
        )
        
        # Create a web session
        $session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
    
        # Initial GET request to set the XSRF token
        $getResponse = Invoke-WebRequest -Uri "$baseUrl/tree?" -WebSession $session -UseBasicParsing
    
        # Extract the XSRF token
        $xsrfToken = $session.Cookies.GetCookies($baseUrl)['_xsrf'].Value
    
        # Define headers for DELETE request
        $headers = @{
            "X-XSRFToken" = $xsrfToken
            "Authorization" = "token $token"
        }
    
        # DELETE request URL
        $deleteUri = "$baseUrl/api/kernels/$kernelId"
    
        # Perform the DELETE request
        $response = Invoke-RestMethod -Uri $deleteUri -Method Delete -Headers $headers -WebSession $session -SkipCertificateCheck
    
        return $response
    }
    

    Then you can call this function by passing the kernel_id to this function like this -

    DeleteJupyterKernel -kernelId "<kernelid>"
    

    You can fetch the kernel id, doing something similar, see below -

    function listjupytersessions{
    
        # Define the URL for GET request
        $getUri = "http://localhost:8888/api/sessions/?token=mytoken"
        
        # Send the GET request
        $response = Invoke-RestMethod -Uri $getUri -Method Get -SkipCertificateCheck
        # Initialize the Counter
        $counter = 1
        # Process each session
        foreach ($session in $response) {
            $name = $session.name
            $kernelId = $session.kernel.id
            $kernelName = $session.kernel.name
            $executionState = $session.kernel.execution_state
        
            # Output the extracted information
            Write-Host ""
            Write-Host "------KernelInfo for Kernel $counter with Id $kernelId Starts------"
            Write-Host "Notebook Name: $name"
            Write-Host "Kernel ID: $kernelId"
            Write-Host "Kernel Name: $kernelName"
            Write-Host "Execution State: $executionState"
            Write-Host "------KernelInfo for Kernel $counter with Id $kernelId Ends------"
            $counter++
        }
        $counter = 1
    }
    

    Let me know how it goes.