Last active
July 30, 2026 19:42
-
-
Save minrk/c61083dc4e3636cb175a286ae1e902d6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "id": "0083c175-690f-417b-96a2-42d14f165087", | |
| "metadata": {}, | |
| "source": [ | |
| "# Check which JupyterHub repos need updating\n", | |
| "\n", | |
| "1. get all repos (exclude private and archived repos)\n", | |
| "2. get the contents of `pyproject.toml` and check the existence of `setup.py`\n", | |
| "3. a project is a package if `setup.py` exists _OR_ `pyproject.toml` contains `build-system`\n", | |
| "4. a repo needs updating if it is a package and does _not_ define `build-system` in `pyproject.toml`\n", | |
| "\n", | |
| "This notebook is published at https://gist.github.com/minrk/c61083dc4e3636cb175a286ae1e902d6\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "id": "be8b273d-7645-4371-a424-c1e4e82fd079", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "from subprocess import check_output\n", | |
| "import requests\n", | |
| "\n", | |
| "# get an API token from the gh cli\n", | |
| "gh_token = check_output([\"gh\", \"auth\", \"token\"], text=True).strip()\n", | |
| "s = requests.Session()\n", | |
| "s.headers = {\"Authorization\": f\"Bearer {gh_token}\"}" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "id": "69c8edb5-778d-4f8a-a7c3-792cbdade7a7", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "pyproject_gql = \"\"\"\n", | |
| "query ($owner: String!, $after: String) {\n", | |
| " organization(login: $owner) {\n", | |
| " repositories(first: 100, after:$after, privacy: PUBLIC, isArchived: false) {\n", | |
| " totalCount\n", | |
| " pageInfo {\n", | |
| " startCursor\n", | |
| " endCursor\n", | |
| " hasNextPage\n", | |
| " hasPreviousPage\n", | |
| " }\n", | |
| " nodes {\n", | |
| " name\n", | |
| " nameWithOwner\n", | |
| " isTemplate\n", | |
| " pyproject: object(expression: \"HEAD:pyproject.toml\") {\n", | |
| " ... on Blob {\n", | |
| " text\n", | |
| " byteSize\n", | |
| " }\n", | |
| " }\n", | |
| " setup: object(expression: \"HEAD:setup.py\") {\n", | |
| " ... on Blob {\n", | |
| " byteSize\n", | |
| " }\n", | |
| " }\n", | |
| " setup_cfg: object(expression: \"HEAD:setup.cfg\") {\n", | |
| " ... on Blob {\n", | |
| " text\n", | |
| " }\n", | |
| " }\n", | |
| " workflows: object(expression: \"HEAD:.github/workflows/\") {\n", | |
| " ... on Tree {\n", | |
| " entries {\n", | |
| " name\n", | |
| " object {\n", | |
| " ... on Blob {\n", | |
| " text\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| " }\n", | |
| "}\n", | |
| "\"\"\"" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "id": "5824f340-28b1-4f18-85f3-d04c0441130d", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "b9e0f250d7ec443fb5cc55940ddb3bda", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| "0it [00:00, ?it/s]" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "from operator import itemgetter\n", | |
| "\n", | |
| "from tqdm.notebook import tqdm\n", | |
| "\n", | |
| "github_gql = \"https://api.github.com/graphql\"\n", | |
| "\n", | |
| "\n", | |
| "def fetch_repos(owner):\n", | |
| " variables = {\"owner\": owner}\n", | |
| " has_next_page = True\n", | |
| " while has_next_page:\n", | |
| " r = s.post(\n", | |
| " github_gql,\n", | |
| " json={\n", | |
| " \"query\": pyproject_gql,\n", | |
| " \"variables\": variables,\n", | |
| " },\n", | |
| " )\n", | |
| " if not r.ok:\n", | |
| " print(r.json())\n", | |
| " r.raise_for_status()\n", | |
| " response = r.json()\n", | |
| " repos = response[\"data\"][\"organization\"][\"repositories\"]\n", | |
| " repos[\"pageInfo\"]\n", | |
| " for repo in repos[\"nodes\"]:\n", | |
| " if not repo[\"isTemplate\"]:\n", | |
| " # exclude templates, not available in filters apparently\n", | |
| " yield repo\n", | |
| " has_next_page = repos[\"pageInfo\"][\"hasNextPage\"]\n", | |
| " if has_next_page:\n", | |
| " variables[\"after\"] = repos[\"pageInfo\"][\"endCursor\"]\n", | |
| "\n", | |
| "\n", | |
| "repos = list(tqdm(fetch_repos(\"jupyterhub\")))\n", | |
| "repos = sorted(repos, key=itemgetter(\"name\"))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "id": "3489ab7a-0e39-4d87-ad57-d6da062f6723", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import yaml\n", | |
| "\n", | |
| "trusted_publish = 'pypa/gh-action-pypi-publish'\n", | |
| "\n", | |
| "def has_trusted_publishing(repo):\n", | |
| " if not repo[\"workflows\"]:\n", | |
| " return False\n", | |
| " for workflow_blob in repo[\"workflows\"][\"entries\"]:\n", | |
| " workflow = yaml.safe_load(workflow_blob[\"object\"][\"text\"])\n", | |
| " for job in workflow[\"jobs\"].values():\n", | |
| " for step in job[\"steps\"]:\n", | |
| " if \"uses\" not in step:\n", | |
| " continue\n", | |
| " action = step[\"uses\"]\n", | |
| " action_repo = action.partition(\"@\")[0]\n", | |
| " if action_repo == trusted_publish:\n", | |
| " if 'with' in step and 'password' in step['with']:\n", | |
| " # upload with credentials, not Trusted Publishing\n", | |
| " return False\n", | |
| " else:\n", | |
| " return True\n", | |
| " return False\n", | |
| " " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "id": "257707dc-e39f-40b6-9f43-58faf7f43d60", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import configparser\n", | |
| "import tomllib\n", | |
| "import requests_cache\n", | |
| "\n", | |
| "requests_cache.install_cache()\n", | |
| "\n", | |
| "\n", | |
| "def process_repo(repo):\n", | |
| " info = {\n", | |
| " \"name\": repo[\"name\"],\n", | |
| " \"package_name\": None,\n", | |
| " \"has_setup\": False,\n", | |
| " \"has_setup_cfg\": False,\n", | |
| " \"has_pyproject\": False,\n", | |
| " \"is_package\": False,\n", | |
| " \"build_system\": False,\n", | |
| " \"project\": False,\n", | |
| " \"has_trusted_publishing\": False,\n", | |
| " \"on_pypi\": False,\n", | |
| " }\n", | |
| " info[\"has_setup\"] = bool(repo[\"setup\"])\n", | |
| " info[\"has_setup_cfg\"] = bool(repo[\"setup_cfg\"])\n", | |
| " info[\"has_pyproject\"] = bool(repo[\"pyproject\"])\n", | |
| " if repo[\"pyproject\"]:\n", | |
| " pyproject = tomllib.loads(repo[\"pyproject\"][\"text\"])\n", | |
| " if \"build-system\" in pyproject:\n", | |
| " info[\"build_system\"] = True\n", | |
| " if \"project\" in pyproject:\n", | |
| " info[\"project\"] = True\n", | |
| " info[\"package_name\"] = pyproject[\"project\"][\"name\"]\n", | |
| " elif repo[\"setup_cfg\"]:\n", | |
| " cfg = configparser.ConfigParser()\n", | |
| " cfg.read_string(repo[\"setup_cfg\"][\"text\"])\n", | |
| " if \"metadata\" in cfg and \"name\" in cfg[\"metadata\"]:\n", | |
| " info[\"package_name\"] = cfg[\"metadata\"][\"name\"]\n", | |
| " info[\"is_package\"] = bool(repo[\"setup\"]) or bool(info.get(\"build_system\"))\n", | |
| " if info[\"is_package\"]:\n", | |
| " info[\"has_trusted_publishing\"] = has_trusted_publishing(repo)\n", | |
| " if info[\"package_name\"]:\n", | |
| " r = requests.get(f\"https://pypi.org/pypi/{info['package_name']}/json\")\n", | |
| " info[\"on_pypi\"] = r.status_code == 200\n", | |
| "\n", | |
| " return info\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "id": "b20ffa34-c8f8-4ebd-a0a3-24510670636c", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "{'name': 'jupyterhub',\n", | |
| " 'package_name': 'jupyterhub',\n", | |
| " 'has_setup': True,\n", | |
| " 'has_setup_cfg': False,\n", | |
| " 'has_pyproject': True,\n", | |
| " 'is_package': True,\n", | |
| " 'build_system': True,\n", | |
| " 'project': True,\n", | |
| " 'has_trusted_publishing': True,\n", | |
| " 'on_pypi': True}" | |
| ] | |
| }, | |
| "execution_count": 6, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "for repo in repos:\n", | |
| " if repo[\"name\"] == \"jupyterhub\":\n", | |
| " info = process_repo(repo)\n", | |
| "info" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "id": "63271cbb-3d94-4991-b477-474a660f136e", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "application/vnd.jupyter.widget-view+json": { | |
| "model_id": "527a0bf822d34643a4443636a017abfc", | |
| "version_major": 2, | |
| "version_minor": 0 | |
| }, | |
| "text/plain": [ | |
| " 0%| | 0/63 [00:00<?, ?it/s]" | |
| ] | |
| }, | |
| "metadata": {}, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "repo_info = [process_repo(repo) for repo in tqdm(repos)]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "id": "abcf10a4-8786-49f5-b503-bdb055491549", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>.github</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>action-get-quayio-tags</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2</th>\n", | |
| " <td>action-k3s-helm</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>3</th>\n", | |
| " <td>action-k8s-await-workloads</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>4</th>\n", | |
| " <td>action-k8s-namespace-report</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>...</th>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>58</th>\n", | |
| " <td>the-littlest-jupyterhub</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>59</th>\n", | |
| " <td>tmpauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>60</th>\n", | |
| " <td>traefik-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>61</th>\n", | |
| " <td>wrapspawner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>62</th>\n", | |
| " <td>zero-to-jupyterhub-k8s</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "<p>63 rows × 10 columns</p>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name has_setup has_setup_cfg \\\n", | |
| "0 .github None False False \n", | |
| "1 action-get-quayio-tags None False False \n", | |
| "2 action-k3s-helm None False False \n", | |
| "3 action-k8s-await-workloads None False False \n", | |
| "4 action-k8s-namespace-report None False False \n", | |
| ".. ... ... ... ... \n", | |
| "58 the-littlest-jupyterhub None True False \n", | |
| "59 tmpauthenticator None True False \n", | |
| "60 traefik-proxy None True True \n", | |
| "61 wrapspawner None True False \n", | |
| "62 zero-to-jupyterhub-k8s None False False \n", | |
| "\n", | |
| " has_pyproject is_package build_system project has_trusted_publishing \\\n", | |
| "0 False False False False False \n", | |
| "1 False False False False False \n", | |
| "2 False False False False False \n", | |
| "3 False False False False False \n", | |
| "4 False False False False False \n", | |
| ".. ... ... ... ... ... \n", | |
| "58 True True False False False \n", | |
| "59 True True False False True \n", | |
| "60 True True True False False \n", | |
| "61 False True False False False \n", | |
| "62 False False False False False \n", | |
| "\n", | |
| " on_pypi \n", | |
| "0 False \n", | |
| "1 False \n", | |
| "2 False \n", | |
| "3 False \n", | |
| "4 False \n", | |
| ".. ... \n", | |
| "58 False \n", | |
| "59 False \n", | |
| "60 False \n", | |
| "61 False \n", | |
| "62 False \n", | |
| "\n", | |
| "[63 rows x 10 columns]" | |
| ] | |
| }, | |
| "execution_count": 8, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "import pandas as pd\n", | |
| "df = pd.DataFrame.from_records(repo_info)\n", | |
| "df" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "00212fc6-ed94-4611-858f-9198009224df", | |
| "metadata": {}, | |
| "source": [ | |
| "Sanity check. The following repos do not appear to be Python packages" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 9, | |
| "id": "769f5a71-dc62-44dc-b4ea-e0195c36b146", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>.github</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>action-get-quayio-tags</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2</th>\n", | |
| " <td>action-k3s-helm</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>3</th>\n", | |
| " <td>action-k8s-await-workloads</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>4</th>\n", | |
| " <td>action-k8s-namespace-report</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>5</th>\n", | |
| " <td>action-major-minor-tag-calculator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>8</th>\n", | |
| " <td>binder-billing</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>9</th>\n", | |
| " <td>binder-data</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>12</th>\n", | |
| " <td>configurable-http-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>13</th>\n", | |
| " <td>design</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>19</th>\n", | |
| " <td>grafana-dashboards</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>20</th>\n", | |
| " <td>helm-chart</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>25</th>\n", | |
| " <td>jupyterhub-container-images</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>26</th>\n", | |
| " <td>jupyterhub-deploy-docker</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>27</th>\n", | |
| " <td>jupyterhub-deploy-hpc</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>28</th>\n", | |
| " <td>jupyterhub-deploy-teaching</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>30</th>\n", | |
| " <td>jupyterhub-on-hadoop</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>32</th>\n", | |
| " <td>jupyterhub-the-hard-way</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>33</th>\n", | |
| " <td>jupyterhub.github.io</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>38</th>\n", | |
| " <td>mybinder-tools</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>39</th>\n", | |
| " <td>mybinder.org-deploy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>40</th>\n", | |
| " <td>mybinder.org-user-guide</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>49</th>\n", | |
| " <td>pebble-helm-chart</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>52</th>\n", | |
| " <td>repo2docker-action</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>53</th>\n", | |
| " <td>roadmap</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>57</th>\n", | |
| " <td>team-compass</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>62</th>\n", | |
| " <td>zero-to-jupyterhub-k8s</td>\n", | |
| " <td>None</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name has_setup has_setup_cfg \\\n", | |
| "0 .github None False False \n", | |
| "1 action-get-quayio-tags None False False \n", | |
| "2 action-k3s-helm None False False \n", | |
| "3 action-k8s-await-workloads None False False \n", | |
| "4 action-k8s-namespace-report None False False \n", | |
| "5 action-major-minor-tag-calculator None False False \n", | |
| "8 binder-billing None False False \n", | |
| "9 binder-data None False False \n", | |
| "12 configurable-http-proxy None False False \n", | |
| "13 design None False False \n", | |
| "19 grafana-dashboards None False False \n", | |
| "20 helm-chart None False False \n", | |
| "25 jupyterhub-container-images None False False \n", | |
| "26 jupyterhub-deploy-docker None False False \n", | |
| "27 jupyterhub-deploy-hpc None False False \n", | |
| "28 jupyterhub-deploy-teaching None False False \n", | |
| "30 jupyterhub-on-hadoop None False False \n", | |
| "32 jupyterhub-the-hard-way None False False \n", | |
| "33 jupyterhub.github.io None False False \n", | |
| "38 mybinder-tools None False False \n", | |
| "39 mybinder.org-deploy None False False \n", | |
| "40 mybinder.org-user-guide None False False \n", | |
| "49 pebble-helm-chart None False False \n", | |
| "52 repo2docker-action None False False \n", | |
| "53 roadmap None False False \n", | |
| "57 team-compass None False False \n", | |
| "62 zero-to-jupyterhub-k8s None False False \n", | |
| "\n", | |
| " has_pyproject is_package build_system project has_trusted_publishing \\\n", | |
| "0 False False False False False \n", | |
| "1 False False False False False \n", | |
| "2 False False False False False \n", | |
| "3 False False False False False \n", | |
| "4 False False False False False \n", | |
| "5 False False False False False \n", | |
| "8 False False False False False \n", | |
| "9 False False False False False \n", | |
| "12 False False False False False \n", | |
| "13 False False False False False \n", | |
| "19 True False False False False \n", | |
| "20 False False False False False \n", | |
| "25 False False False False False \n", | |
| "26 False False False False False \n", | |
| "27 False False False False False \n", | |
| "28 False False False False False \n", | |
| "30 False False False False False \n", | |
| "32 False False False False False \n", | |
| "33 False False False False False \n", | |
| "38 False False False False False \n", | |
| "39 False False False False False \n", | |
| "40 False False False False False \n", | |
| "49 False False False False False \n", | |
| "52 False False False False False \n", | |
| "53 False False False False False \n", | |
| "57 False False False False False \n", | |
| "62 False False False False False \n", | |
| "\n", | |
| " on_pypi \n", | |
| "0 False \n", | |
| "1 False \n", | |
| "2 False \n", | |
| "3 False \n", | |
| "4 False \n", | |
| "5 False \n", | |
| "8 False \n", | |
| "9 False \n", | |
| "12 False \n", | |
| "13 False \n", | |
| "19 False \n", | |
| "20 False \n", | |
| "25 False \n", | |
| "26 False \n", | |
| "27 False \n", | |
| "28 False \n", | |
| "30 False \n", | |
| "32 False \n", | |
| "33 False \n", | |
| "38 False \n", | |
| "39 False \n", | |
| "40 False \n", | |
| "49 False \n", | |
| "52 False \n", | |
| "53 False \n", | |
| "57 False \n", | |
| "62 False " | |
| ] | |
| }, | |
| "execution_count": 9, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "df[~df.is_package]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "195c79aa-b270-4c95-b684-d8c87716efe0", | |
| "metadata": {}, | |
| "source": [ | |
| "The following repos appear to be packages without PEP 621 build system metadata.\n", | |
| "\n", | |
| "These repos will stop being installable from source with pip." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 10, | |
| "id": "370966dc-aa90-420e-a637-0cb145340039", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>14</th>\n", | |
| " <td>docker-image-cleaner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>17</th>\n", | |
| " <td>firstuseauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>18</th>\n", | |
| " <td>gh-scoped-creds</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>21</th>\n", | |
| " <td>jupyter-remote-desktop-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>22</th>\n", | |
| " <td>jupyter-rsession-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>36</th>\n", | |
| " <td>ldapauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>41</th>\n", | |
| " <td>nativeauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>58</th>\n", | |
| " <td>the-littlest-jupyterhub</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>59</th>\n", | |
| " <td>tmpauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>61</th>\n", | |
| " <td>wrapspawner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name has_setup has_setup_cfg \\\n", | |
| "14 docker-image-cleaner None True False \n", | |
| "17 firstuseauthenticator None True False \n", | |
| "18 gh-scoped-creds None True False \n", | |
| "21 jupyter-remote-desktop-proxy None True False \n", | |
| "22 jupyter-rsession-proxy None True True \n", | |
| "36 ldapauthenticator None True False \n", | |
| "41 nativeauthenticator None True False \n", | |
| "58 the-littlest-jupyterhub None True False \n", | |
| "59 tmpauthenticator None True False \n", | |
| "61 wrapspawner None True False \n", | |
| "\n", | |
| " has_pyproject is_package build_system project has_trusted_publishing \\\n", | |
| "14 True True False False False \n", | |
| "17 False True False False False \n", | |
| "18 False True False False True \n", | |
| "21 True True False False True \n", | |
| "22 True True False False True \n", | |
| "36 True True False False False \n", | |
| "41 True True False False True \n", | |
| "58 True True False False False \n", | |
| "59 True True False False True \n", | |
| "61 False True False False False \n", | |
| "\n", | |
| " on_pypi \n", | |
| "14 False \n", | |
| "17 False \n", | |
| "18 False \n", | |
| "21 False \n", | |
| "22 False \n", | |
| "36 False \n", | |
| "41 False \n", | |
| "58 False \n", | |
| "59 False \n", | |
| "61 False " | |
| ] | |
| }, | |
| "execution_count": 10, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "needs_update = df[df.is_package & (~df.build_system)]\n", | |
| "needs_update" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 11, | |
| "id": "3e9f32ab-8340-4d35-b8dc-05dfe30d7b50", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "- [ ] https://github.com/jupyterhub/docker-image-cleaner\n", | |
| "- [ ] https://github.com/jupyterhub/firstuseauthenticator\n", | |
| "- [ ] https://github.com/jupyterhub/gh-scoped-creds\n", | |
| "- [ ] https://github.com/jupyterhub/jupyter-remote-desktop-proxy\n", | |
| "- [ ] https://github.com/jupyterhub/jupyter-rsession-proxy\n", | |
| "- [ ] https://github.com/jupyterhub/ldapauthenticator\n", | |
| "- [ ] https://github.com/jupyterhub/nativeauthenticator\n", | |
| "- [ ] https://github.com/jupyterhub/the-littlest-jupyterhub\n", | |
| "- [ ] https://github.com/jupyterhub/tmpauthenticator\n", | |
| "- [ ] https://github.com/jupyterhub/wrapspawner\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# make a todo list I can copy/paste\n", | |
| "def todo_list(subsection):\n", | |
| " for name in subsection.name.sort_values():\n", | |
| " print(f\"- [ ] https://github.com/jupyterhub/{name}\")\n", | |
| "\n", | |
| "todo_list(needs_update)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "4db569c3-417c-49e4-a85e-039d501ac01a", | |
| "metadata": {}, | |
| "source": [ | |
| "These repos define `build-system`, so they will work, but don't define `project`, which means they could probably use some modernization, but it's less pressing:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 12, | |
| "id": "f4f13f31-8cab-4161-a01c-f4310fe4d867", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>7</th>\n", | |
| " <td>batchspawner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>10</th>\n", | |
| " <td>binderhub</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>42</th>\n", | |
| " <td>nbgitpuller</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>43</th>\n", | |
| " <td>nbgitpuller-downloader-dropbox</td>\n", | |
| " <td>nbgitpuller-downloader-dropbox</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>44</th>\n", | |
| " <td>nbgitpuller-downloader-generic-web</td>\n", | |
| " <td>nbgitpuller-downloader-generic-web</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>45</th>\n", | |
| " <td>nbgitpuller-downloader-googledrive</td>\n", | |
| " <td>nbgitpuller-downloader-googledrive</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>46</th>\n", | |
| " <td>nbgitpuller-downloader-plugins</td>\n", | |
| " <td>nbgitpuller-downloader-plugins</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>60</th>\n", | |
| " <td>traefik-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name \\\n", | |
| "7 batchspawner None \n", | |
| "10 binderhub None \n", | |
| "42 nbgitpuller None \n", | |
| "43 nbgitpuller-downloader-dropbox nbgitpuller-downloader-dropbox \n", | |
| "44 nbgitpuller-downloader-generic-web nbgitpuller-downloader-generic-web \n", | |
| "45 nbgitpuller-downloader-googledrive nbgitpuller-downloader-googledrive \n", | |
| "46 nbgitpuller-downloader-plugins nbgitpuller-downloader-plugins \n", | |
| "60 traefik-proxy None \n", | |
| "\n", | |
| " has_setup has_setup_cfg has_pyproject is_package build_system \\\n", | |
| "7 True False True True True \n", | |
| "10 True True True True True \n", | |
| "42 True True True True True \n", | |
| "43 False True True True True \n", | |
| "44 False True True True True \n", | |
| "45 False True True True True \n", | |
| "46 False True True True True \n", | |
| "60 True True True True True \n", | |
| "\n", | |
| " project has_trusted_publishing on_pypi \n", | |
| "7 False False False \n", | |
| "10 False False False \n", | |
| "42 False True False \n", | |
| "43 False False True \n", | |
| "44 False False True \n", | |
| "45 False False True \n", | |
| "46 False False False \n", | |
| "60 False False False " | |
| ] | |
| }, | |
| "execution_count": 12, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "should_update = df[df.is_package & df.build_system & ~df.project]\n", | |
| "should_update" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 13, | |
| "id": "e954c780-73fc-403f-98b9-bfcf36bd4a4f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "- [ ] https://github.com/jupyterhub/batchspawner\n", | |
| "- [ ] https://github.com/jupyterhub/binderhub\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller-downloader-dropbox\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller-downloader-generic-web\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller-downloader-googledrive\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller-downloader-plugins\n", | |
| "- [ ] https://github.com/jupyterhub/traefik-proxy\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "todo_list(should_update)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "dc44eb83-3cdc-4814-abc5-553d2b3e4c37", | |
| "metadata": {}, | |
| "source": [ | |
| "## Trusted Publishing\n", | |
| "\n", | |
| "Check for trusted publishing is a check for `pypa/gh-action-pypi-publish` action without a `password` argument.\n", | |
| "\n", | |
| "1. is it a package?\n", | |
| "2. is it on PyPI?\n", | |
| "3. does it have trusted publishing enabled?\n", | |
| "\n", | |
| "Note: Some packages are not meant to be published and built directly into container images.\n", | |
| "\n", | |
| "Further note: to check if a package is published, we need to know its package name. Repos that specify package name in setup.py don't get picked up, which will need up\n", | |
| "which will be updated " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 14, | |
| "id": "e37f8d04-38d6-4bf8-907f-bbe274698bab", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>7</th>\n", | |
| " <td>batchspawner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>10</th>\n", | |
| " <td>binderhub</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>14</th>\n", | |
| " <td>docker-image-cleaner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>17</th>\n", | |
| " <td>firstuseauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>18</th>\n", | |
| " <td>gh-scoped-creds</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>21</th>\n", | |
| " <td>jupyter-remote-desktop-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>22</th>\n", | |
| " <td>jupyter-rsession-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>36</th>\n", | |
| " <td>ldapauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>41</th>\n", | |
| " <td>nativeauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>42</th>\n", | |
| " <td>nbgitpuller</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>46</th>\n", | |
| " <td>nbgitpuller-downloader-plugins</td>\n", | |
| " <td>nbgitpuller-downloader-plugins</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>58</th>\n", | |
| " <td>the-littlest-jupyterhub</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>59</th>\n", | |
| " <td>tmpauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>60</th>\n", | |
| " <td>traefik-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>61</th>\n", | |
| " <td>wrapspawner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name has_setup \\\n", | |
| "7 batchspawner None True \n", | |
| "10 binderhub None True \n", | |
| "14 docker-image-cleaner None True \n", | |
| "17 firstuseauthenticator None True \n", | |
| "18 gh-scoped-creds None True \n", | |
| "21 jupyter-remote-desktop-proxy None True \n", | |
| "22 jupyter-rsession-proxy None True \n", | |
| "36 ldapauthenticator None True \n", | |
| "41 nativeauthenticator None True \n", | |
| "42 nbgitpuller None True \n", | |
| "46 nbgitpuller-downloader-plugins nbgitpuller-downloader-plugins False \n", | |
| "58 the-littlest-jupyterhub None True \n", | |
| "59 tmpauthenticator None True \n", | |
| "60 traefik-proxy None True \n", | |
| "61 wrapspawner None True \n", | |
| "\n", | |
| " has_setup_cfg has_pyproject is_package build_system project \\\n", | |
| "7 False True True True False \n", | |
| "10 True True True True False \n", | |
| "14 False True True False False \n", | |
| "17 False False True False False \n", | |
| "18 False False True False False \n", | |
| "21 False True True False False \n", | |
| "22 True True True False False \n", | |
| "36 False True True False False \n", | |
| "41 False True True False False \n", | |
| "42 True True True True False \n", | |
| "46 True True True True False \n", | |
| "58 False True True False False \n", | |
| "59 False True True False False \n", | |
| "60 True True True True False \n", | |
| "61 False False True False False \n", | |
| "\n", | |
| " has_trusted_publishing on_pypi \n", | |
| "7 False False \n", | |
| "10 False False \n", | |
| "14 False False \n", | |
| "17 False False \n", | |
| "18 True False \n", | |
| "21 True False \n", | |
| "22 True False \n", | |
| "36 False False \n", | |
| "41 True False \n", | |
| "42 True False \n", | |
| "46 False False \n", | |
| "58 False False \n", | |
| "59 True False \n", | |
| "60 False False \n", | |
| "61 False False " | |
| ] | |
| }, | |
| "execution_count": 14, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "df[df.is_package & ~df.on_pypi]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 15, | |
| "id": "919cd0ec-c8c8-4691-a2a9-e4367258d65f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>6</th>\n", | |
| " <td>autodoc-traits</td>\n", | |
| " <td>autodoc-traits</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>11</th>\n", | |
| " <td>chartpress</td>\n", | |
| " <td>chartpress</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>15</th>\n", | |
| " <td>dockerspawner</td>\n", | |
| " <td>dockerspawner</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>16</th>\n", | |
| " <td>escapism</td>\n", | |
| " <td>escapism</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>18</th>\n", | |
| " <td>gh-scoped-creds</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>21</th>\n", | |
| " <td>jupyter-remote-desktop-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>22</th>\n", | |
| " <td>jupyter-rsession-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>23</th>\n", | |
| " <td>jupyter-server-proxy</td>\n", | |
| " <td>jupyter_server_proxy</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>24</th>\n", | |
| " <td>jupyterhub</td>\n", | |
| " <td>jupyterhub</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>29</th>\n", | |
| " <td>jupyterhub-idle-culler</td>\n", | |
| " <td>jupyterhub-idle-culler</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>31</th>\n", | |
| " <td>jupyterhub-sphinx-theme</td>\n", | |
| " <td>jupyterhub-sphinx-theme</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>34</th>\n", | |
| " <td>kerberosauthenticator</td>\n", | |
| " <td>jupyterhub-kerberosauthenticator</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>37</th>\n", | |
| " <td>ltiauthenticator</td>\n", | |
| " <td>jupyterhub-ltiauthenticator</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>41</th>\n", | |
| " <td>nativeauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>42</th>\n", | |
| " <td>nbgitpuller</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>47</th>\n", | |
| " <td>oauthenticator</td>\n", | |
| " <td>oauthenticator</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>48</th>\n", | |
| " <td>pamela</td>\n", | |
| " <td>pamela</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>50</th>\n", | |
| " <td>pytest-jupyterhub</td>\n", | |
| " <td>pytest-jupyterhub</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>55</th>\n", | |
| " <td>sudospawner</td>\n", | |
| " <td>sudospawner</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>56</th>\n", | |
| " <td>systemdspawner</td>\n", | |
| " <td>jupyterhub-systemdspawner</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>59</th>\n", | |
| " <td>tmpauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name has_setup \\\n", | |
| "6 autodoc-traits autodoc-traits False \n", | |
| "11 chartpress chartpress False \n", | |
| "15 dockerspawner dockerspawner False \n", | |
| "16 escapism escapism False \n", | |
| "18 gh-scoped-creds None True \n", | |
| "21 jupyter-remote-desktop-proxy None True \n", | |
| "22 jupyter-rsession-proxy None True \n", | |
| "23 jupyter-server-proxy jupyter_server_proxy True \n", | |
| "24 jupyterhub jupyterhub True \n", | |
| "29 jupyterhub-idle-culler jupyterhub-idle-culler False \n", | |
| "31 jupyterhub-sphinx-theme jupyterhub-sphinx-theme False \n", | |
| "34 kerberosauthenticator jupyterhub-kerberosauthenticator False \n", | |
| "37 ltiauthenticator jupyterhub-ltiauthenticator False \n", | |
| "41 nativeauthenticator None True \n", | |
| "42 nbgitpuller None True \n", | |
| "47 oauthenticator oauthenticator False \n", | |
| "48 pamela pamela False \n", | |
| "50 pytest-jupyterhub pytest-jupyterhub False \n", | |
| "55 sudospawner sudospawner False \n", | |
| "56 systemdspawner jupyterhub-systemdspawner False \n", | |
| "59 tmpauthenticator None True \n", | |
| "\n", | |
| " has_setup_cfg has_pyproject is_package build_system project \\\n", | |
| "6 False True True True True \n", | |
| "11 False True True True True \n", | |
| "15 False True True True True \n", | |
| "16 False True True True True \n", | |
| "18 False False True False False \n", | |
| "21 False True True False False \n", | |
| "22 True True True False False \n", | |
| "23 False True True True True \n", | |
| "24 False True True True True \n", | |
| "29 False True True True True \n", | |
| "31 False True True True True \n", | |
| "34 False True True True True \n", | |
| "37 False True True True True \n", | |
| "41 False True True False False \n", | |
| "42 True True True True False \n", | |
| "47 False True True True True \n", | |
| "48 False True True True True \n", | |
| "50 False True True True True \n", | |
| "55 False True True True True \n", | |
| "56 False True True True True \n", | |
| "59 False True True False False \n", | |
| "\n", | |
| " has_trusted_publishing on_pypi \n", | |
| "6 True True \n", | |
| "11 True True \n", | |
| "15 True True \n", | |
| "16 True True \n", | |
| "18 True False \n", | |
| "21 True False \n", | |
| "22 True False \n", | |
| "23 True True \n", | |
| "24 True True \n", | |
| "29 True True \n", | |
| "31 True True \n", | |
| "34 True True \n", | |
| "37 True True \n", | |
| "41 True False \n", | |
| "42 True False \n", | |
| "47 True True \n", | |
| "48 True True \n", | |
| "50 True True \n", | |
| "55 True True \n", | |
| "56 True True \n", | |
| "59 True False " | |
| ] | |
| }, | |
| "execution_count": 15, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "has_tp = df[df.has_trusted_publishing]\n", | |
| "has_tp " | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 16, | |
| "id": "b46c79a2-d895-428c-92c2-262f868c38cb", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>35</th>\n", | |
| " <td>kubespawner</td>\n", | |
| " <td>jupyterhub-kubespawner</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>43</th>\n", | |
| " <td>nbgitpuller-downloader-dropbox</td>\n", | |
| " <td>nbgitpuller-downloader-dropbox</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>44</th>\n", | |
| " <td>nbgitpuller-downloader-generic-web</td>\n", | |
| " <td>nbgitpuller-downloader-generic-web</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>45</th>\n", | |
| " <td>nbgitpuller-downloader-googledrive</td>\n", | |
| " <td>nbgitpuller-downloader-googledrive</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>51</th>\n", | |
| " <td>repo2docker</td>\n", | |
| " <td>jupyter-repo2docker</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>54</th>\n", | |
| " <td>simpervisor</td>\n", | |
| " <td>simpervisor</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name \\\n", | |
| "35 kubespawner jupyterhub-kubespawner \n", | |
| "43 nbgitpuller-downloader-dropbox nbgitpuller-downloader-dropbox \n", | |
| "44 nbgitpuller-downloader-generic-web nbgitpuller-downloader-generic-web \n", | |
| "45 nbgitpuller-downloader-googledrive nbgitpuller-downloader-googledrive \n", | |
| "51 repo2docker jupyter-repo2docker \n", | |
| "54 simpervisor simpervisor \n", | |
| "\n", | |
| " has_setup has_setup_cfg has_pyproject is_package build_system \\\n", | |
| "35 False False True True True \n", | |
| "43 False True True True True \n", | |
| "44 False True True True True \n", | |
| "45 False True True True True \n", | |
| "51 False False True True True \n", | |
| "54 False False True True True \n", | |
| "\n", | |
| " project has_trusted_publishing on_pypi \n", | |
| "35 True False True \n", | |
| "43 False False True \n", | |
| "44 False False True \n", | |
| "45 False False True \n", | |
| "51 True False True \n", | |
| "54 True False True " | |
| ] | |
| }, | |
| "execution_count": 16, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "published = df[df.is_package & df.on_pypi]\n", | |
| "needs_tp = published[~published.has_trusted_publishing]\n", | |
| "needs_tp" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 17, | |
| "id": "39018fe8-93f3-40e7-9575-2820504069c3", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "- [ ] https://github.com/jupyterhub/kubespawner\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller-downloader-dropbox\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller-downloader-generic-web\n", | |
| "- [ ] https://github.com/jupyterhub/nbgitpuller-downloader-googledrive\n", | |
| "- [ ] https://github.com/jupyterhub/repo2docker\n", | |
| "- [ ] https://github.com/jupyterhub/simpervisor\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "todo_list(needs_tp)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "afaa747b-892f-414f-b53c-ffd69fe458b4", | |
| "metadata": {}, | |
| "source": [ | |
| "These are packages which lack trusted publishing where `package_name` is not derived, which means our data is inconclusive.\n", | |
| "Most of these need trusted publishing enabled _and_ metadata updates" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 18, | |
| "id": "d31073f1-3c8b-4636-8f0c-f026515b818f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>name</th>\n", | |
| " <th>package_name</th>\n", | |
| " <th>has_setup</th>\n", | |
| " <th>has_setup_cfg</th>\n", | |
| " <th>has_pyproject</th>\n", | |
| " <th>is_package</th>\n", | |
| " <th>build_system</th>\n", | |
| " <th>project</th>\n", | |
| " <th>has_trusted_publishing</th>\n", | |
| " <th>on_pypi</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>7</th>\n", | |
| " <td>batchspawner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>10</th>\n", | |
| " <td>binderhub</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>14</th>\n", | |
| " <td>docker-image-cleaner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>17</th>\n", | |
| " <td>firstuseauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>36</th>\n", | |
| " <td>ldapauthenticator</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>58</th>\n", | |
| " <td>the-littlest-jupyterhub</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>60</th>\n", | |
| " <td>traefik-proxy</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>61</th>\n", | |
| " <td>wrapspawner</td>\n", | |
| " <td>None</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>True</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " name package_name has_setup has_setup_cfg \\\n", | |
| "7 batchspawner None True False \n", | |
| "10 binderhub None True True \n", | |
| "14 docker-image-cleaner None True False \n", | |
| "17 firstuseauthenticator None True False \n", | |
| "36 ldapauthenticator None True False \n", | |
| "58 the-littlest-jupyterhub None True False \n", | |
| "60 traefik-proxy None True True \n", | |
| "61 wrapspawner None True False \n", | |
| "\n", | |
| " has_pyproject is_package build_system project has_trusted_publishing \\\n", | |
| "7 True True True False False \n", | |
| "10 True True True False False \n", | |
| "14 True True False False False \n", | |
| "17 False True False False False \n", | |
| "36 True True False False False \n", | |
| "58 True True False False False \n", | |
| "60 True True True False False \n", | |
| "61 False True False False False \n", | |
| "\n", | |
| " on_pypi \n", | |
| "7 False \n", | |
| "10 False \n", | |
| "14 False \n", | |
| "17 False \n", | |
| "36 False \n", | |
| "58 False \n", | |
| "60 False \n", | |
| "61 False " | |
| ] | |
| }, | |
| "execution_count": 18, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "probably_needs_tp = df[df.is_package & ~df.on_pypi & ~df.package_name.astype(bool) & ~df.has_trusted_publishing]\n", | |
| "probably_needs_tp" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 19, | |
| "id": "00644538-057b-41f2-a05c-a28f411b9477", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "- [ ] https://github.com/jupyterhub/batchspawner\n", | |
| "- [ ] https://github.com/jupyterhub/binderhub\n", | |
| "- [ ] https://github.com/jupyterhub/docker-image-cleaner\n", | |
| "- [ ] https://github.com/jupyterhub/firstuseauthenticator\n", | |
| "- [ ] https://github.com/jupyterhub/ldapauthenticator\n", | |
| "- [ ] https://github.com/jupyterhub/the-littlest-jupyterhub\n", | |
| "- [ ] https://github.com/jupyterhub/traefik-proxy\n", | |
| "- [ ] https://github.com/jupyterhub/wrapspawner\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "todo_list(probably_needs_tp)" | |
| ] | |
| } | |
| ], | |
| "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.12.11" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment