From 279a0c814ac072b046ae6ae894e863b352eff204 Mon Sep 17 00:00:00 2001 From: Sebastien Jourdain Date: Sun, 29 Dec 2024 19:12:06 -0700 Subject: [PATCH] fix(ci): use pyproject and ruff --- .github/workflows/test_and_release.yml | 41 +++++++----- .pre-commit-config.yaml | 13 ++-- CONTRIBUTING.rst | 3 +- MANIFEST.in | 7 ++ examples/vue2/namespace_prefix.py | 4 +- examples/vue3/namespace_prefix.py | 4 +- pyproject.toml | 90 ++++++++++++++++++++++++++ setup.cfg | 41 ------------ setup.py | 3 - trame/modules/www.py | 2 +- trame/ui/html.py | 2 +- trame/widgets/client.py | 2 +- trame/widgets/html.py | 2 +- trame_client/ui/core.py | 35 +++++++--- trame_client/utils/web_module.py | 3 +- trame_client/widgets/core.py | 10 ++- trame_client/widgets/html.py | 2 +- 17 files changed, 172 insertions(+), 92 deletions(-) create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/.github/workflows/test_and_release.yml b/.github/workflows/test_and_release.yml index ef28d82..016307d 100644 --- a/.github/workflows/test_and_release.yml +++ b/.github/workflows/test_and_release.yml @@ -10,9 +10,9 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - uses: actions/setup-python@v2 + - uses: actions/setup-python@v5 with: python-version: "3.9" @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.9] + python-version: ["3.9"] config: - { name: "Linux", @@ -49,10 +49,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -71,9 +71,9 @@ jobs: seleniumbase install chromedriver - name: Set Up Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 18 - name: Build Vue2 App run: | @@ -105,12 +105,12 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set Up Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 18 - name: Build Vue2 App run: | @@ -128,17 +128,23 @@ jobs: needs: [pre-commit, pytest, test-npm-build] runs-on: ubuntu-latest if: github.event_name == 'push' + environment: + name: pypi + url: https://pypi.org/p/trame-client + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + contents: write # IMPORTANT: mandatory for making GitHub Releases steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set Up Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: - node-version: 14 + node-version: 18 - name: Build Vue2 App run: | @@ -153,8 +159,11 @@ jobs: npm run build - name: Python Semantic Release - uses: relekang/python-semantic-release@v7.34.6 + id: release + uses: relekang/python-semantic-release@v9.15.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} - repository_username: __token__ - repository_password: ${{ secrets.PYPI_API_TOKEN }} + + - name: Publish package distributions to PyPI + if: steps.release.outputs.released == 'true' + uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f96e764..3c12fcf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,16 +1,11 @@ repos: - - repo: https://github.com/psf/black - rev: 24.2.0 - hooks: - - id: black - entry: black --check - - repo: https://github.com/codespell-project/codespell rev: v2.1.0 hooks: - id: codespell - - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.8.4 hooks: - - id: flake8 + - id: ruff + - id: ruff-format \ No newline at end of file diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 3e6006e..456732d 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -13,7 +13,6 @@ Tips #### #. When first creating a new project, it is helpful to run ``pre-commit run --all-files`` to ensure all files pass the pre-commit checks. -#. A quick way to fix ``black`` issues is by installing black (``pip install black``) and running the ``black`` command at the root of your repository. -#. Sometimes, ``black`` and ``flake8`` do not agree. Add options to your ``.flake8`` file to fix these things. See the `flake8 configuration docs `_ for more details. +#. A quick way to fix ``ruff`` issues is by installing ruff (``pip install ruff``) and running the ``ruff check --fix .`` or ``ruff format`` command at the root of your repository. #. A quick way to fix ``codespell`` issues is by installing codespell (``pip install codespell``) and running the ``codespell -w`` command at the root of your directory. #. The `.codespellrc file `_ can be used fix any other codespell issues, such as ignoring certain files, directories, words, or regular expressions. diff --git a/MANIFEST.in b/MANIFEST.in index 7851142..8dc6ffb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -4,3 +4,10 @@ graft trame_client/module/vue3-www recursive-exclude trame_client/module/vue2-www *.map recursive-exclude trame_client/module/vue3-www *.map include trame_client/LICENSE +prune examples +prune js-lib +prune tests +prune visual_baseline +prune vue-app +prune vue2-app +prune vue3-app diff --git a/examples/vue2/namespace_prefix.py b/examples/vue2/namespace_prefix.py index 0c3dfa0..94aae7b 100644 --- a/examples/vue2/namespace_prefix.py +++ b/examples/vue2/namespace_prefix.py @@ -20,7 +20,9 @@ def main(): app.ctrl.plus() one_of_the_app = app - # root_server.controller.on_server_ready.add(lambda **kwargs: print(json.dumps(root_server.state.to_dict(), indent=2))) + # root_server.controller.on_server_ready.add( + # lambda **kwargs: print(json.dumps(root_server.state.to_dict(), indent=2)) + # ) root_server.controller.on_server_ready.add( lambda **kwargs: print("Root server ready") ) diff --git a/examples/vue3/namespace_prefix.py b/examples/vue3/namespace_prefix.py index a53997f..86df0ce 100644 --- a/examples/vue3/namespace_prefix.py +++ b/examples/vue3/namespace_prefix.py @@ -20,7 +20,9 @@ def main(): app.ctrl.plus() one_of_the_app = app - # root_server.controller.on_server_ready.add(lambda **kwargs: print(json.dumps(root_server.state.to_dict(), indent=2))) + # root_server.controller.on_server_ready.add( + # lambda **kwargs: print(json.dumps(root_server.state.to_dict(), indent=2)) + # ) root_server.controller.on_server_ready.add( lambda **kwargs: print("Root server ready") ) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d7e3dbb --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,90 @@ +[project] +name = "trame-client" +version = "3.5.0" +description = "Internal client of trame" +authors = [ + {name = "Kitware Inc."}, +] +dependencies = [ +] +requires-python = ">=3.9" +readme = "README.rst" +license = {text = "MIT"} +keywords = ["Python", "Interactive", "Web", "Application", "Framework"] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Web Environment", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Software Development :: Libraries :: Application Frameworks", + "Topic :: Software Development :: Libraries :: Python Modules", +] + +[project.optional-dependencies] +test = [ + "pytest", + "seleniumbase", + "pytest-xprocess", + "Pillow", + "pixelmatch", +] +dev = [ + "pre-commit", + "ruff", +] + +[build-system] +requires = ['setuptools', 'wheel'] +build-backend = 'setuptools.build_meta' + +[tool.setuptools.packages.find] +where = ["."] + +[tool.setuptools.package-data] + + +[tool.semantic_release] +version_toml = [ + "pyproject.toml:project.version", +] +build_command = """ + python -m venv .venv + source .venv/bin/activate + pip install -U pip build + python -m build . +""" + +[semantic_release.publish] +dist_glob_patterns = ["dist/*"] +upload_to_vcs_release = true + +[tool.ruff] +line-length = 88 +indent-width = 4 +target-version = "py39" + +[tool.ruff.lint] +select = ["E", "W", "F"] +ignore = [] +fixable = ["ALL"] +unfixable = [] + + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" +skip-magic-trailing-comma = false +line-ending = "auto" +docstring-code-format = true + +# This only has an effect when the `docstring-code-format` setting is +# enabled. +docstring-code-line-length = "dynamic" + +[tool.ruff.lint.pycodestyle] +max-line-length = 120 + +[lint.pydocstyle] +convention = "google" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index ed263b7..0000000 --- a/setup.cfg +++ /dev/null @@ -1,41 +0,0 @@ -[metadata] -name = trame-client -version = 3.5.0 -description = Internal client of trame -long_description = file: README.rst -long_description_content_type = text/x-rst -author = Kitware Inc. -license = MIT -classifiers = - Development Status :: 5 - Production/Stable - Environment :: Web Environment - License :: OSI Approved :: MIT License - Natural Language :: English - Operating System :: OS Independent - Programming Language :: Python :: 3 :: Only - Programming Language :: JavaScript - Topic :: Software Development :: Libraries :: Application Frameworks - Topic :: Software Development :: Libraries :: Python Modules -keywords = - Python - Interactive - Web - Application - Framework - -[options] -packages = find: -include_package_data = True - - -[options.extras_require] -test = - pytest - seleniumbase - pytest-xprocess - Pillow - pixelmatch - - -[semantic_release] -version_pattern = setup.cfg:version = (\d+\.\d+\.\d+) diff --git a/setup.py b/setup.py deleted file mode 100644 index 6068493..0000000 --- a/setup.py +++ /dev/null @@ -1,3 +0,0 @@ -from setuptools import setup - -setup() diff --git a/trame/modules/www.py b/trame/modules/www.py index 313dc9f..c003360 100644 --- a/trame/modules/www.py +++ b/trame/modules/www.py @@ -1 +1 @@ -from trame_client.module import * +from trame_client.module import * # noqa F403 diff --git a/trame/ui/html.py b/trame/ui/html.py index e970d4e..d04e569 100644 --- a/trame/ui/html.py +++ b/trame/ui/html.py @@ -1 +1 @@ -from trame_client.ui.html import * +from trame_client.ui.html import * # noqa F403 diff --git a/trame/widgets/client.py b/trame/widgets/client.py index e31b6d3..620ce7d 100644 --- a/trame/widgets/client.py +++ b/trame/widgets/client.py @@ -1,4 +1,4 @@ -from trame_client.widgets.trame import * +from trame_client.widgets.trame import * # noqa F403 def initialize(server): diff --git a/trame/widgets/html.py b/trame/widgets/html.py index b19dcb2..39e7e6f 100644 --- a/trame/widgets/html.py +++ b/trame/widgets/html.py @@ -1,4 +1,4 @@ -from trame_client.widgets.html import * +from trame_client.widgets.html import * # noqa F403 def initialize(server): diff --git a/trame_client/ui/core.py b/trame_client/ui/core.py index 3ff9bc3..99036bf 100644 --- a/trame_client/ui/core.py +++ b/trame_client/ui/core.py @@ -54,7 +54,9 @@ def iframe_url_builder_jupyter_extension(layout): www_endpoint = os.environ.get("TRAME_JUPYTER_ENDPOINT", "/trame-jupyter-server") server = layout.server template_name = layout._template_name - src = f"{www_endpoint}/{server.client_type}/index.html?ui={template_name[16:]}&server={server.name}&wsProxy&reconnect=auto" + url_base = f"{www_endpoint}/{server.client_type}/index.html" + url_query = f"ui={template_name[16:]}&server={server.name}&wsProxy&reconnect=auto" + src = f"{url_base}?{url_query}" elem_id = f"{server.name}_{template_name}" # Check if server/kernel are collocated @@ -62,7 +64,11 @@ def iframe_url_builder_jupyter_extension(layout): if www_path and Path(www_path).exists(): server_www = Path(www_path) / "servers" / server.name - src = f"{www_endpoint}/servers/{server.name}/index.html?ui={template_name[16:]}&server={server.name}&wsProxy&reconnect=auto" + url_base = f"{www_endpoint}/servers/{server.name}/index.html" + url_query = ( + f"ui={template_name[16:]}&server={server.name}&wsProxy&reconnect=auto" + ) + src = f"{url_base}?{url_query}" if not server_www.exists(): shutil.copytree(server._www, str(server_www.resolve()), dirs_exist_ok=True) for sub_path, src_dir in server.serve.items(): @@ -81,7 +87,11 @@ def iframe_url_builder_jupyter_extension(layout): def iframe_url_builder_jupyter_hub(layout): server = layout.server template_name = layout._template_name - src = f"{os.environ['JUPYTERHUB_SERVICE_PREFIX']}proxy/{server.port}/index.html?ui={template_name[16:]}&reconnect=auto" + url_base = ( + f"{os.environ['JUPYTERHUB_SERVICE_PREFIX']}proxy/{server.port}/index.html" + ) + url_query = f"ui={template_name[16:]}&reconnect=auto" + src = f"{url_base}?{url_query}" elem_id = f"{server.name}_{template_name}" return { @@ -96,7 +106,9 @@ def iframe_url_builder_jupyter_hub_host(layout): host = os.environ.get("HOSTNAME") server = layout.server template_name = layout._template_name - src = f"{os.environ['JUPYTERHUB_SERVICE_PREFIX']}proxy/{host}:{server.port}/index.html?ui={template_name[16:]}&reconnect=auto" + url_base = f"{os.environ['JUPYTERHUB_SERVICE_PREFIX']}proxy/{host}:{server.port}/index.html" + url_query = f"ui={template_name[16:]}&reconnect=auto" + src = f"{url_base}?{url_query}" elem_id = f"{server.name}_{template_name}" return { @@ -181,7 +193,8 @@ def iframe_builder(self, name_or_fn): @property def root(self): """ - Top level Vue component. Useful for providing / injecting into children components. Setting makes old root child of new root. + Top level Vue component. Useful for providing / injecting into children components. + Setting makes old root child of new root. """ return self._current_root @@ -255,11 +268,13 @@ def __exit__(self, exc_type, exc_value, exc_traceback): def _jupyter_content(self): if not self.server.running: - return """
- The server is not running. Before displaying a trame layout you should await it to make sure it is ready. - You should run the following code before displaying a layout. -
await layout.ready
-
""" + return """ +
+The server is not running. +Before displaying a trame layout you should await it to make sure it is ready. +You should run the following code before displaying a layout. +
await layout.ready
+
""" attributes = self.iframe_builder(self) attributes_str = " ".join( diff --git a/trame_client/utils/web_module.py b/trame_client/utils/web_module.py index 5943749..79a1e57 100644 --- a/trame_client/utils/web_module.py +++ b/trame_client/utils/web_module.py @@ -85,7 +85,8 @@ def serve_directory(self, directory_to_serve, www_base_name): ) if www_base_name in self._serve: raise ValueError( - f"Entry for {www_base_name} is already set for {self._serve[www_base_name]} and want to override with {fs_path}" + f"Entry for {www_base_name} is already set for {self._serve[www_base_name]}" + f"and want to override with {fs_path}" ) self._serving_entries.append((fs_path, www_base_name)) diff --git a/trame_client/widgets/core.py b/trame_client/widgets/core.py index 72427e1..2cbb648 100644 --- a/trame_client/widgets/core.py +++ b/trame_client/widgets/core.py @@ -449,7 +449,9 @@ def attrs(self, *names): and not isinstance(value, (tuple, list)) ): logger.warn( - f'Warning: A Vue directive is evaluating your expression and trame would expect a tuple instead of a plain type. <{self._elem_name} {js_key}="{value}" ... />' + "Warning: A Vue directive is evaluating your expression " + "and trame would expect a tuple instead of a plain type. " + f'<{self._elem_name} {js_key}="{value}" ... />' ) if isinstance(value, (tuple, list)): @@ -501,7 +503,8 @@ def attrs(self, *names): self._attributes[name] = f'{js_key}="{value}"' else: print( - f"Error: Don't know how to handle attribute name '{name}' with value '{value}' in {self.__class__}::{self._elem_name}" + "Error: Don't know how to handle attribute name " + f"'{name}' with value '{value}' in {self.__class__}::{self._elem_name}" ) return self @@ -569,7 +572,8 @@ def events(self, *names): ) else: print( - f"Error: Don't know how to handle event name '{name}' with value '{value}' in {self.__class__}::{self._elem_name}" + "Error: Don't know how to handle event name " + f"'{name}' with value '{value}' in {self.__class__}::{self._elem_name}" ) return self diff --git a/trame_client/widgets/html.py b/trame_client/widgets/html.py index 5df3b84..e8e4cd4 100644 --- a/trame_client/widgets/html.py +++ b/trame_client/widgets/html.py @@ -6556,7 +6556,7 @@ def __init__(self, children=None, **kwargs): ] -class I(HtmlElement): +class I(HtmlElement): # noqa E742 """ Properties: