From 3c8c5d402ea1c8e448a75a0604d27a0c7d23186d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:35:37 -0600 Subject: [PATCH 1/8] Clean up packaging and add py312 support --- .github/workflows/tests.yml | 12 ++--- Makefile | 81 -------------------------------- docs/source/conf.py | 6 ++- docs/source/http-mode.md | 2 + kernel_gateway/_version.py | 15 +++++- kernel_gateway/gatewayapp.py | 3 +- pyproject.toml | 87 ++++++++++++++++++++++++++++++++++ requirements-doc.txt | 3 -- requirements-test.txt | 6 --- requirements.txt | 6 --- setup.cfg | 5 -- setup.py | 91 +----------------------------------- 12 files changed, 114 insertions(+), 203 deletions(-) delete mode 100644 Makefile create mode 100644 pyproject.toml delete mode 100644 requirements-doc.txt delete mode 100644 requirements-test.txt delete mode 100644 requirements.txt delete mode 100644 setup.cfg diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8d13930..07582ef 100755 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,6 +35,7 @@ jobs: - "3.9" - "3.10" - "3.11" + - "3.12" runs-on: ubuntu-latest @@ -58,23 +59,22 @@ jobs: ${{ runner.os }}-python ${{ runner.os }}- - - name: Upgrade pip - run: python -m pip install --upgrade pip setuptools wheel - - name: Install dependencies run: | - pip install --upgrade -r requirements.txt -r requirements-test.txt - pip install -e . + pip install -e "."" pip freeze - name: Show help run: jupyter kernelgateway --help - name: Run tests - run: pytest -vv -W default --cov kernel_gateway --cov-branch --cov-report term-missing:skip-covered + run: hatch run cov:test env: ASYNC_TEST_TIMEOUT: 10 + - name: Build docs + run: hatch run docs:build + - name: Upload coverage to Codecov uses: codecov/codecov-action@v1 with: diff --git a/Makefile b/Makefile deleted file mode 100644 index 392cd75..0000000 --- a/Makefile +++ /dev/null @@ -1,81 +0,0 @@ -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -.PHONY: help build clean nuke dev dev-http docs install bdist sdist test release - -SA:=source activate -ENV:=kernel-gateway-dev -SHELL:=/bin/bash - -help: -# http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html - @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - -build: -env: ## Make a dev environment - conda create -y -n $(ENV) -c conda-forge --file requirements.txt \ - --file requirements-test.txt - source activate $(ENV) && \ - pip install -r requirements-doc.txt && \ - pip install -e . - -activate: ## eval `make activate` - @echo "$(SA) $(ENV)" - -clean: ## Make a clean source tree - -rm -rf dist - -rm -rf build - -rm -rf *.egg-info - -find kernel_gateway -name __pycache__ -exec rm -fr {} \; - -find kernel_gateway -name '*.pyc' -exec rm -fr {} \; - -$(SA) $(ENV) && make -C docs clean - -nuke: ## Make clean + remove conda env - -conda env remove -n $(ENV) -y - -dev: ## Make a server in jupyter_websocket mode - $(SA) $(ENV) && python kernel_gateway - -dev-http: ## Make a server in notebook_http mode - $(SA) $(ENV) && python kernel_gateway \ - --KernelGatewayApp.api='kernel_gateway.notebook_http' \ - --KernelGatewayApp.seed_uri=etc/api_examples/api_intro.ipynb - -docs: ## Make HTML documentation - $(SA) $(ENV) && make -C docs html - -install: ## Make a conda env with dist/*.whl and dist/*.tar.gz installed - -conda env remove -y -n $(ENV)-install - conda create -y -n $(ENV)-install python=3 pip - $(SA) $(ENV)-install && \ - pip install dist/*.whl && \ - jupyter kernelgateway --help && \ - pip uninstall -y jupyter_kernel_gateway - conda env remove -y -n $(ENV)-install - - conda create -y -n $(ENV)-install python=3 pip - $(SA) $(ENV)-install && \ - pip install dist/*.tar.gz && \ - jupyter kernelgateway --help && \ - pip uninstall -y jupyter_kernel_gateway - conda env remove -y -n $(ENV)-install - -bdist: ## Make a dist/*.whl binary distribution - $(SA) $(ENV) && python setup.py bdist_wheel $(POST_SDIST) \ - && rm -rf *.egg-info - -sdist: ## Make a dist/*.tar.gz source distribution - $(SA) $(ENV) && python setup.py sdist $(POST_SDIST) \ - && rm -rf *.egg-info - -test: TEST?= -test: ## Make a python3 test run -ifeq ($(TEST),) - $(SA) $(ENV) && pytest -vv -else -# e.g., make test TEST="test_gatewayapp.py::TestGatewayAppConfig" - $(SA) $(ENV) && pytest -vv kernel_gateway/tests/$(TEST) -endif - -release: POST_SDIST=register upload -release: bdist sdist ## Make a wheel + source release on PyPI diff --git a/docs/source/conf.py b/docs/source/conf.py index 47bc0a7..1994193 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -35,6 +35,8 @@ "myst_parser" ] +myst_enable_extensions = ["attrs_block", "attrs_inline"] + # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -71,7 +73,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -362,7 +364,7 @@ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/3/': None} +intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} # Read The Docs # on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org diff --git a/docs/source/http-mode.md b/docs/source/http-mode.md index 7eebc5b..67b3203 100644 --- a/docs/source/http-mode.md +++ b/docs/source/http-mode.md @@ -46,6 +46,8 @@ The `REQUEST` object currently contains the following properties: * `path` - An object of key-value pairs representing path parameters and their values. * `headers` - An object of key-value pairs where a key is a HTTP header name and a value is the HTTP header value. If there are multiple values are specified for a header, the value will be an array. +{#request-content-type-and-request-body-processing} + ### Request Content-Type and Request Body Processing If the HTTP request to the kernel gateway has a `Content-Type` header the value of `REQUEST.body` may change. Below is the list of outcomes for various mime-types: diff --git a/kernel_gateway/_version.py b/kernel_gateway/_version.py index a4d06db..9440320 100644 --- a/kernel_gateway/_version.py +++ b/kernel_gateway/_version.py @@ -3,6 +3,17 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. -version_info = (2, 6, 0, 'dev0') +import re +from typing import List -__version__ = '.'.join(map(str, version_info)) +# Version string must appear intact for automatic versioning +__version__ = "2.6.0.dev0" + +# Build up version_info tuple for backwards compatibility +pattern = r"(?P\d+).(?P\d+).(?P\d+)(?P.*)" +match = re.match(pattern, __version__) +assert match is not None +parts: List[object] = [int(match[part]) for part in ["major", "minor", "patch"]] +if match["rest"]: + parts.append(match["rest"]) +version_info = tuple(parts) diff --git a/kernel_gateway/gatewayapp.py b/kernel_gateway/gatewayapp.py index 508721e..2441751 100644 --- a/kernel_gateway/gatewayapp.py +++ b/kernel_gateway/gatewayapp.py @@ -16,7 +16,6 @@ import ssl import threading from base64 import encodebytes -from distutils.util import strtobool import nbformat from jupyter_server.services.kernels.kernelmanager import MappingKernelManager @@ -189,7 +188,7 @@ def expose_headers_default(self): ) @default('trust_xheaders') def trust_xheaders_default(self): - return strtobool(os.getenv(self.trust_xheaders_env, 'False')) + return os.getenv(self.trust_xheaders_env, 'False').lower() == 'true' max_age_env = 'KG_MAX_AGE' diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3c019bf --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,87 @@ +[build-system] +requires = ["hatchling>=1.5"] +build-backend = "hatchling.build" + +[project] +name = "jupyter-kernel-gateway" +dynamic = ["version"] +description = "A web server for spawning and communicating with Jupyter kernels" +readme = "README.md" +license = "BSD" +requires-python = ">=3.8" +authors = [ + { name = "Jupyter Development Team", email = "jupyter@googlegroups.com" }, +] +keywords = [ + "Cloud", + "Interactive", + "Interpreter", + "Kernel", + "Web", +] +classifiers = [ + "Intended Audience :: Developers", + "Intended Audience :: Science/Research", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", +] +dependencies = [ + "jupyter_client>=7.4.4", + "jupyter_core>=4.12,!=5.0.*", + "jupyter_server>=2.0", + "requests>=2.7,<3.0", + "tornado>=6.2.0", + "traitlets>=5.6.0", +] + +[project.scripts] +jupyter-kernelgateway = "kernel_gateway:launch_instance" + +[project.urls] +Homepage = "http://github.com/jupyter-incubator/kernel_gateway" + +[project.optional-dependencies] +test = [ + "coverage", + "pytest", + "pytest-cov", + "pytest_jupyter", + "pytest-timeout", + "ipykernel", +] +docs = [ + "sphinx_rtd_theme", + "sphinx", + "myst-parser", +] + +[tool.hatch.version] +path = "kernel_gateway/_version.py" + +[tool.hatch.build.targets.sdist] +include = [ + "/kernel_gateway", +] + +[tool.hatch.envs.docs] +features = ["docs"] +[tool.hatch.envs.docs.scripts] +build = "make -C docs html SPHINXOPTS='-W'" + +[tool.hatch.envs.test] +features = ["test"] +[tool.hatch.envs.test.scripts] +test = "python -m pytest -vv {args}" + +[tool.hatch.envs.cov] +features = ["test"] +dependencies = ["coverage[toml]", "pytest-cov"] +[tool.hatch.envs.cov.scripts] +test = "python -m pytest -vv --cov kernel_gateway --cov-branch --cov-report term-missing:skip-covered {args}" diff --git a/requirements-doc.txt b/requirements-doc.txt deleted file mode 100644 index 1a45a28..0000000 --- a/requirements-doc.txt +++ /dev/null @@ -1,3 +0,0 @@ -sphinx_rtd_theme -sphinx -myst-parser diff --git a/requirements-test.txt b/requirements-test.txt deleted file mode 100644 index 6284dfd..0000000 --- a/requirements-test.txt +++ /dev/null @@ -1,6 +0,0 @@ -coverage -pytest -pytest-cov -pytest_jupyter -pytest-timeout -ipykernel diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index f5e545d..0000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -jupyter_core>=4.12 -jupyter_client>=7.4.4 -jupyter_server>=2.12.2 -traitlets>=5.6.0 -tornado>=6.2.0 -requests>=2.7,<3.0 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 63be602..0000000 --- a/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[bdist_wheel] -universal=0 - -[metadata] -license_file = LICENSE.md diff --git a/setup.py b/setup.py index afdc0e0..8bf1ba9 100644 --- a/setup.py +++ b/setup.py @@ -1,91 +1,2 @@ -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import os -import sys from setuptools import setup - -here = os.path.abspath(os.path.dirname(__file__)) - -version_ns = {} -with open(os.path.join(here, 'kernel_gateway', '_version.py')) as f: - exec(f.read(), {}, version_ns) - -setup_args = dict( - name='jupyter_kernel_gateway', - author='Jupyter Development Team', - author_email='jupyter@googlegroups.com', - url='http://github.com/jupyter-incubator/kernel_gateway', - description='A web server for spawning and communicating with Jupyter kernels', - long_description='''\ -Jupyter Kernel Gateway is a web server that supports different mechanisms for -spawning and communicating with Jupyter kernels, such as: - -* A Jupyter Notebook server-compatible HTTP API used for requesting kernels - and talking the `Jupyter kernel protocol `_ - with the kernels over Websockets -* A HTTP API defined by annotated notebook cells that maps HTTP verbs and - resources to code to execute on a kernel - -The server launches kernels in its local process/filesystem space. It can be -containerized and scaled out using common technologies like -`tmpnb `_, -`Cloud Foundry `_, and -`Kubernetes `_. -''', - version=version_ns['__version__'], - license='BSD', - platforms="Linux, Mac OS X, Windows", - keywords=['Interactive', 'Interpreter', 'Kernel', 'Web', 'Cloud'], - packages=[ - 'kernel_gateway', - 'kernel_gateway.base', - 'kernel_gateway.jupyter_websocket', - 'kernel_gateway.notebook_http', - 'kernel_gateway.notebook_http.cell', - 'kernel_gateway.notebook_http.swagger', - 'kernel_gateway.services', - 'kernel_gateway.services.kernels', - 'kernel_gateway.services.kernelspecs', - 'kernel_gateway.services.sessions', - ], - scripts=[ - 'scripts/jupyter-kernelgateway' - ], - install_requires=[ - 'jupyter_client>=7.4.4', - 'jupyter_core>=4.12,!=5.0.*', - 'jupyter_server>=2.0', - 'traitlets>=5.6.0', - 'tornado>=6.2.0', - 'requests>=2.7,<3.0' - ], - python_requires='>=3.8', - classifiers=[ - 'Intended Audience :: Developers', - 'Intended Audience :: System Administrators', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - ], - include_package_data=True, -) - -if 'setuptools' in sys.modules: - # setupstools turns entrypoint scripts into executables on windows - setup_args['entry_points'] = { - 'console_scripts': [ - 'jupyter-kernelgateway = kernel_gateway:launch_instance' - ] - } - # Don't bother installing the .py scripts if if we're using entrypoints - setup_args.pop('scripts', None) - -if __name__ == '__main__': - setup(**setup_args) +setup() From 3b0b7107e3d5031e6b4a600f8f678142415e19e0 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:37:05 -0600 Subject: [PATCH 2/8] syntax --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 07582ef..0f8e66f 100755 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -61,7 +61,7 @@ jobs: - name: Install dependencies run: | - pip install -e "."" + pip install -e . pip freeze - name: Show help From 2978c2998dfd381e381d7f164c060fa4d3ddef56 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:38:16 -0600 Subject: [PATCH 3/8] fix metadata --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3c019bf..d880b62 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "jupyter-kernel-gateway" dynamic = ["version"] description = "A web server for spawning and communicating with Jupyter kernels" readme = "README.md" -license = "BSD" +license = { file = "LICENSE.md" } requires-python = ">=3.8" authors = [ { name = "Jupyter Development Team", email = "jupyter@googlegroups.com" }, From 0195ea8da362ac5eb1780248d23f0d732e2aa5d1 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:40:32 -0600 Subject: [PATCH 4/8] fix metadata --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index d880b62..61694c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,9 @@ include = [ "/kernel_gateway", ] +[tool.hatch.build.targets.wheel] +packages = ["kernel_gateway"] + [tool.hatch.envs.docs] features = ["docs"] [tool.hatch.envs.docs.scripts] From 339977b568373333dbab633c08f469501f28720e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:43:29 -0600 Subject: [PATCH 5/8] clean up workflow --- .github/workflows/tests.yml | 38 +++---------------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0f8e66f..c0bf7ec 100755 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,26 +7,8 @@ on: - main jobs: - check_duplicate_runs: - name: Check for duplicate runs - continue-on-error: true - runs-on: ubuntu-latest - outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} - steps: - - id: skip_check - uses: fkirc/skip-duplicate-actions@master - with: - concurrent_skipping: always - cancel_others: true - skip_after_successful_duplicate: true - paths_ignore: '["**/README.md", "**/CHANGELOG.md", "**/LICENSE.md"]' - do_not_skip: '["pull_request"]' - tests: name: Run tests (Python ${{matrix.python}}) - needs: check_duplicate_runs - if: ${{ needs.check_duplicate_runs.outputs.should_skip != 'true' }} strategy: matrix: @@ -39,25 +21,11 @@ jobs: runs-on: ubuntu-latest - steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python }} - - - name: Cache pip - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-python-${{ matrix.python }}-pip-${{ hashFiles('**/requirements*.txt') }} - restore-keys: | - ${{ runner.os }}-python-${{ matrix.python }}-pip-${{ hashFiles('**/requirements*.txt') }} - ${{ runner.os }}-python-${{ matrix.python }}-pip- - ${{ runner.os }}-python - ${{ runner.os }}- + - name: Base Setup + uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Install dependencies run: | From 9e47ac105ebcc31671f567e9e05d2394e3750740 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:45:39 -0600 Subject: [PATCH 6/8] add workflow check --- .pre-commit-config.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0e4239f..d25248c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,3 +3,8 @@ repos: rev: v4.4.0 hooks: - id: end-of-file-fixer + + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.27.3 + hooks: + - id: check-github-workflows From bb45aab9521dbc45708abac53a3eabea9a553d6b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:46:45 -0600 Subject: [PATCH 7/8] add workflow check --- .github/workflows/tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c0bf7ec..3e425fc 100755 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,7 @@ jobs: - "3.12" runs-on: ubuntu-latest + steps: - name: Checkout uses: actions/checkout@v4 From 70302e0fc4cc9b3a27a93cd6321a8c23590062cc Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 15 Jan 2024 21:51:08 -0600 Subject: [PATCH 8/8] remove codecov --- .github/workflows/tests.yml | 6 ------ codecov.yml | 10 ---------- 2 files changed, 16 deletions(-) delete mode 100644 codecov.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3e425fc..a70f2e8 100755 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,9 +43,3 @@ jobs: - name: Build docs run: hatch run docs:build - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 36d97aa..0000000 --- a/codecov.yml +++ /dev/null @@ -1,10 +0,0 @@ -coverage: - status: - project: - default: - target: auto - threshold: 5% - patch: - default: - target: 50% - range: 80..100