Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "aeaec312",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"import os\n",
"import subprocess\n",
"\n",
"import requests\n",
"\n",
"\n",
"# API token is always available in the jupyterhub environment\n",
"\n",
"token = os.environ[\"JUPYTERHUB_API_TOKEN\"]\n",
"# create a requests Session object with our auth token\n",
"s = requests.Session()\n",
"s.headers = {\"Authorization\": f\"token {token}\"}"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "f77a894b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'base_url': '/user/test-1/',\n",
" 'hostname': '127.0.0.1',\n",
" 'notebook_dir': '/private/tmp/test-1',\n",
" 'password': False,\n",
" 'pid': 94573,\n",
" 'port': 50632,\n",
" 'secure': False,\n",
" 'sock': '',\n",
" 'token': '',\n",
" 'url': 'http://127.0.0.1:50632/user/test-1/'}]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# get the running server(s) from `jupyter notebook list`\n",
"p = subprocess.run([\"jupyter\", \"notebook\", \"list\", \"--json\"], capture_output=True, text=True)\n",
"servers = []\n",
"for line in p.stdout.splitlines():\n",
" servers.append(json.loads(line))\n",
"servers"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "dfa5e287",
"metadata": {},
"outputs": [],
"source": [
"# assume one server for now\n",
"# can select by comparing base_url to $JUPYTERHUB_SERVICE_PREFIX\n",
"server = servers[0]\n",
"jupyter_api = f\"{server['url']}api\""
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "650901b3",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'id': '42481fdd-c6a8-4e69-ae9f-c2c2b6b2c233',\n",
" 'path': 'cull-kernels.ipynb',\n",
" 'name': 'cull-kernels.ipynb',\n",
" 'type': 'notebook',\n",
" 'kernel': {'id': '1e884864-3de1-4cad-a1f1-8f4a055888e4',\n",
" 'name': 'python3',\n",
" 'last_activity': '2021-04-27T09:41:09.657388Z',\n",
" 'execution_state': 'busy',\n",
" 'connections': 2},\n",
" 'notebook': {'path': 'cull-kernels.ipynb', 'name': 'cull-kernels.ipynb'}},\n",
" {'id': '812efebf-4221-41a8-ab3e-524d197e0909',\n",
" 'path': 'still-connected.ipynb',\n",
" 'name': 'still-connected.ipynb',\n",
" 'type': 'notebook',\n",
" 'kernel': {'id': '751818eb-246d-45bc-8de8-d0a13c1777e1',\n",
" 'name': 'python3',\n",
" 'last_activity': '2021-04-27T09:41:01.450770Z',\n",
" 'execution_state': 'idle',\n",
" 'connections': 1},\n",
" 'notebook': {'path': 'still-connected.ipynb',\n",
" 'name': 'still-connected.ipynb'}},\n",
" {'id': '75e31fcc-948b-4021-adb1-af3bdbfe8630',\n",
" 'path': 'idle-notebook.ipynb',\n",
" 'name': 'idle-notebook.ipynb',\n",
" 'type': 'notebook',\n",
" 'kernel': {'id': 'ef4bd7f8-ea09-45fe-bfdb-01abcee02bdb',\n",
" 'name': 'python3',\n",
" 'last_activity': '2021-04-27T09:40:45.354849Z',\n",
" 'execution_state': 'idle',\n",
" 'connections': 0},\n",
" 'notebook': {'path': 'idle-notebook.ipynb', 'name': 'idle-notebook.ipynb'}}]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# List sessions using jupyter REST API\n",
"\n",
"sessions = s.get(f\"{jupyter_api}/sessions\").json()\n",
"\n",
"# sort by activity\n",
"# last_activity is ISO8601 strings, sortable without parsing\n",
"sessions = sorted(sessions, key=lambda s: s[\"kernel\"][\"last_activity\"], reverse=True)\n",
"sessions"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "5809499d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Not shutting down most recently active session: cull-kernels.ipynb\n",
"Not shutting down kernel with 1 connections: still-connected.ipynb\n",
"Shutting down session idle-notebook.ipynb idle since 2021-04-27T09:40:45.354849Z\n"
]
}
],
"source": [
"# don't shutdown the most recently active kernel, but shut down all others\n",
"if sessions:\n",
" print(f\"Not shutting down most recently active session: {sessions[0]['name']}\")\n",
"\n",
"for session in sessions[1:]:\n",
" kernel = session['kernel']\n",
" name = session['name']\n",
" if kernel['execution_state'] == 'busy':\n",
" print(f\"Not shutting down busy kernel for {name}\")\n",
" continue\n",
" if kernel['connections']:\n",
" print(f\"Not shutting down kernel with {kernel['connections']} connections: {name}\")\n",
" continue\n",
" print(f\"Shutting down session {name} idle since {kernel['last_activity']}\")\n",
" r = s.delete(f\"{jupyter_api}/sessions/{session['id']}\")\n",
" r.raise_for_status()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.8"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment