From 7b9843a86252aebd3d9463e0a22182b49f2c03fe Mon Sep 17 00:00:00 2001 From: David Feltell Date: Tue, 2 Sep 2025 18:10:02 +0100 Subject: [PATCH] [Lint] Set 99 char line length and bulk reformat Set up ruff to enforce a 99 char line limit, mirroring other OpenAssetIO projects. Configure yml with 2-space tabs, mirroring other OpenAssetIO projects (and the ComfyUI cookiecutter project's defaults). Bulk reformat using PyCharm configured to use ruff - i.e. Python files are reformatted using ruff, whilst other files are reformatted according to .editorconfig and/or PyCharm defaults. Signed-off-by: David Feltell --- .editorconfig | 5 +- .github/workflows/build-pipeline.yml | 4 +- README.md | 47 ++++++++++---- pyproject.toml | 2 +- src/openassetio_comfyui/nodes.py | 93 +++++++++++++++------------- tests/conftest.py | 2 +- tests/test_openassetio_comfyui.py | 3 + 7 files changed, 96 insertions(+), 60 deletions(-) diff --git a/.editorconfig b/.editorconfig index 1b8f4df..2f1d858 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,7 +13,7 @@ trim_trailing_whitespace = true insert_final_newline = true charset = utf-8 end_of_line = lf -max_line_length = 140 +max_line_length = 99 # For docstrings and comments. ij_visual_guides = 72 @@ -26,3 +26,6 @@ insert_final_newline = false [Makefile] indent_style = tab + +[{*.yml,*.yaml}] +indent_size = 2 diff --git a/.github/workflows/build-pipeline.yml b/.github/workflows/build-pipeline.yml index 223678a..32c49b9 100644 --- a/.github/workflows/build-pipeline.yml +++ b/.github/workflows/build-pipeline.yml @@ -16,8 +16,8 @@ jobs: PYTHONIOENCODING: "utf8" strategy: matrix: - os: [ubuntu-latest] - python-version: ["3.12"] + os: [ ubuntu-latest ] + python-version: [ "3.12" ] steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index fb65fb2..fdb1246 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,17 @@ OpenAssetIO ingress and egress > [!NOTE] -> This projected was created with a [cookiecutter](https://github.com/Comfy-Org/cookiecutter-comfy-extension) template. It helps you start writing custom nodes without worrying about the Python setup. +> This projected was created with +> a [cookiecutter](https://github.com/Comfy-Org/cookiecutter-comfy-extension) template. It helps you +> start +> writing custom nodes without worrying about the Python setup. ## Quickstart 1. Install [ComfyUI](https://docs.comfy.org/get_started). 1. Install [ComfyUI-Manager](https://github.com/ltdrdata/ComfyUI-Manager) -1. Look up this extension in ComfyUI-Manager. If you are installing manually, clone this repository under `ComfyUI/custom_nodes`. +1. Look up this extension in ComfyUI-Manager. If you are installing manually, clone this repository + under `ComfyUI/custom_nodes`. 1. Restart ComfyUI. # Features @@ -26,14 +30,19 @@ pip install -e .[dev] pre-commit install ``` -The `-e` flag above will result in a "live" install, in the sense that any changes you make to your node extension will automatically be picked up the next time you run ComfyUI. +The `-e` flag above will result in a "live" install, in the sense that any changes you make to your +node extension will automatically be +picked up the next time you run ComfyUI. ## Publish to Github -Install Github Desktop or follow these [instructions](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) for ssh. +Install Github Desktop or follow +these [instructions](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent) +for ssh. 1. Create a Github repository that matches the directory name. 2. Push the files to Git + ``` git add . git commit -m "project scaffolding" @@ -42,26 +51,38 @@ git push ## Writing custom nodes -An example custom node is located in [node.py](src/openassetio-comfyui/nodes.py). To learn more, read the [docs](https://docs.comfy.org/essentials/custom_node_overview). - +An example custom node is located in [node.py](src/openassetio-comfyui/nodes.py). To learn more, +read +the [docs](https://docs.comfy.org/essentials/custom_node_overview). ## Tests -This repo contains unit tests written in Pytest in the `tests/` directory. It is recommended to unit test your custom node. +This repo contains unit tests written in Pytest in the `tests/` directory. It is recommended to +unit test your custom node. -- [build-pipeline.yml](.github/workflows/build-pipeline.yml) will run pytest and linter on any open PRs -- [validate.yml](.github/workflows/validate.yml) will run [node-diff](https://github.com/Comfy-Org/node-diff) to check for breaking changes +- [build-pipeline.yml](.github/workflows/build-pipeline.yml) will run pytest and linter on any open + PRs +- [validate.yml](.github/workflows/validate.yml) will + run [node-diff](https://github.com/Comfy-Org/node-diff) to check for breaking changes ## Publishing to Registry -If you wish to share this custom node with others in the community, you can publish it to the registry. We've already auto-populated some fields in `pyproject.toml` under `tool.comfy`, but please double-check that they are correct. +If you wish to share this custom node with others in the community, you can publish it to the +registry. We've already auto-populated some +fields in `pyproject.toml` under `tool.comfy`, but please double-check that they are correct. You need to make an account on https://registry.comfy.org and create an API key token. -- [ ] Go to the [registry](https://registry.comfy.org). Login and create a publisher id (everything after the `@` sign on your registry profile). +- [ ] Go to the [registry](https://registry.comfy.org). Login and create a publisher id (everything + after the `@` sign on your registry + profile). - [ ] Add the publisher id into the pyproject.toml file. -- [ ] Create an api key on the Registry for publishing from Github. [Instructions](https://docs.comfy.org/registry/publishing#create-an-api-key-for-publishing). +- [ ] Create an api key on the Registry for publishing from + Github. [Instructions](https://docs.comfy.org/registry/publishing#create-an-api-key-for-publishing). - [ ] Add it to your Github Repository Secrets as `REGISTRY_ACCESS_TOKEN`. -A Github action will run on every git push. You can also run the Github action manually. Full instructions [here](https://docs.comfy.org/registry/publishing). Join our [discord](https://discord.com/invite/comfyorg) if you have any questions! +A Github action will run on every git push. You can also run the Github action manually. Full +instructions [here](https://docs.comfy.org/registry/publishing). Join +our [discord](https://discord.com/invite/comfyorg) if you have any +questions! diff --git a/pyproject.toml b/pyproject.toml index 492f4bd..a827261 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,7 +70,7 @@ disable_error_code = "attr-defined" [tool.ruff] # extend-exclude = ["static", "ci/templates"] -line-length = 140 +line-length = 99 src = ["src", "tests"] target-version = "py311" diff --git a/src/openassetio_comfyui/nodes.py b/src/openassetio_comfyui/nodes.py index c824df3..6720fe1 100644 --- a/src/openassetio_comfyui/nodes.py +++ b/src/openassetio_comfyui/nodes.py @@ -3,6 +3,8 @@ # SPDX-License-Identifier: Apache-2.0 from inspect import cleandoc + + class Example: """ A example node @@ -32,57 +34,68 @@ class Example: The entry point method. The name of this method must be the same as the value of property `FUNCTION`. For example, if `FUNCTION = "execute"` then this method's name must be `execute`, if `FUNCTION = "foo"` then it must be `foo`. """ + def __init__(self): pass @classmethod def INPUT_TYPES(s): """ - Return a dictionary which contains config for all input fields. - Some types (string): "MODEL", "VAE", "CLIP", "CONDITIONING", "LATENT", "IMAGE", "INT", "STRING", "FLOAT". - Input types "INT", "STRING" or "FLOAT" are special values for fields on the node. - The type can be a list for selection. + Return a dictionary which contains config for all input fields. + Some types (string): "MODEL", "VAE", "CLIP", "CONDITIONING", "LATENT", "IMAGE", "INT", "STRING", "FLOAT". + Input types "INT", "STRING" or "FLOAT" are special values for fields on the node. + The type can be a list for selection. - Returns: `dict`: - - Key input_fields_group (`string`): Can be either required, hidden or optional. A node class must have property `required` - - Value input_fields (`dict`): Contains input fields config: - * Key field_name (`string`): Name of a entry-point method's argument - * Value field_config (`tuple`): - + First value is a string indicate the type of field or a list for selection. - + Secound value is a config for type "INT", "STRING" or "FLOAT". + Returns: `dict`: + - Key input_fields_group (`string`): Can be either required, hidden or optional. A node class must have property `required` + - Value input_fields (`dict`): Contains input fields config: + * Key field_name (`string`): Name of a entry-point method's argument + * Value field_config (`tuple`): + + First value is a string indicate the type of field or a list for selection. + + Secound value is a config for type "INT", "STRING" or "FLOAT". """ return { "required": { - "image": ("Image", { "tooltip": "This is an image"}), - "int_field": ("INT", { - "default": 0, - "min": 0, #Minimum value - "max": 4096, #Maximum value - "step": 64, #Slider's step - "display": "number" # Cosmetic only: display as "number" or "slider" - }), - "float_field": ("FLOAT", { - "default": 1.0, - "min": 0.0, - "max": 10.0, - "step": 0.01, - "round": 0.001, #The value represeting the precision to round to, will be set to the step value by default. Can be set to False to disable rounding. - "display": "number"}), + "image": ("Image", {"tooltip": "This is an image"}), + "int_field": ( + "INT", + { + "default": 0, + "min": 0, # Minimum value + "max": 4096, # Maximum value + "step": 64, # Slider's step + "display": "number", # Cosmetic only: display as "number" or "slider" + }, + ), + "float_field": ( + "FLOAT", + { + "default": 1.0, + "min": 0.0, + "max": 10.0, + "step": 0.01, + "round": 0.001, # The value represeting the precision to round to, will be set to the step value by default. Can be set to False to disable rounding. + "display": "number", + }, + ), "print_to_screen": (["enable", "disable"],), - "string_field": ("STRING", { - "multiline": False, #True if you want the field to look like the one on the ClipTextEncode node - "default": "Hello World!" - }), + "string_field": ( + "STRING", + { + "multiline": False, # True if you want the field to look like the one on the ClipTextEncode node + "default": "Hello World!", + }, + ), }, } RETURN_TYPES = ("IMAGE",) - #RETURN_NAMES = ("image_output_name",) + # RETURN_NAMES = ("image_output_name",) DESCRIPTION = cleandoc(__doc__) FUNCTION = "test" - #OUTPUT_NODE = False - #OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node + # OUTPUT_NODE = False + # OUTPUT_TOOLTIPS = ("",) # Tooltips for the output node CATEGORY = "Example" @@ -93,7 +106,7 @@ class Example: int_field: {int_field} float_field: {float_field} """) - #do some processing on the image, in this example I just invert it + # do some processing on the image, in this example I just invert it image = 1.0 - image return (image,) @@ -105,18 +118,14 @@ class Example: This method is used in the core repo for the LoadImage node where they return the image hash as a string, if the image hash changes between executions the LoadImage node is executed again. """ - #@classmethod - #def IS_CHANGED(s, image, string_field, int_field, float_field, print_to_screen): + # @classmethod + # def IS_CHANGED(s, image, string_field, int_field, float_field, print_to_screen): # return "" # A dictionary that contains all nodes you want to export with their names # NOTE: names should be globally unique -NODE_CLASS_MAPPINGS = { - "Example": Example -} +NODE_CLASS_MAPPINGS = {"Example": Example} # A dictionary that contains the friendly/humanly readable titles for the nodes -NODE_DISPLAY_NAME_MAPPINGS = { - "Example": "Example Node" -} +NODE_DISPLAY_NAME_MAPPINGS = {"Example": "Example Node"} diff --git a/tests/conftest.py b/tests/conftest.py index 378122e..ed9c8f5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,4 +7,4 @@ import sys # Add the project root directory to Python path # This allows the tests to import the project -sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) diff --git a/tests/test_openassetio_comfyui.py b/tests/test_openassetio_comfyui.py index 2d9373c..d89e69d 100644 --- a/tests/test_openassetio_comfyui.py +++ b/tests/test_openassetio_comfyui.py @@ -8,15 +8,18 @@ import pytest from src.openassetio_comfyui.nodes import Example + @pytest.fixture def example_node(): """Fixture to create an Example node instance.""" return Example() + def test_example_node_initialization(example_node): """Test that the node can be instantiated.""" assert isinstance(example_node, Example) + def test_return_types(): """Test the node's metadata.""" assert Example.RETURN_TYPES == ("IMAGE",)