From f7696f28280a5560ec31436c478ed6c7c307c3c8 Mon Sep 17 00:00:00 2001 From: lhyliu Date: Thu, 7 May 2026 00:21:37 +0800 Subject: [PATCH] =?UTF-8?q?1.0=20=E5=8F=91=E5=B8=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 21 ++++++++++++++++++ README.md | 10 +++++++-- examples/example.png | Bin 0 -> 1155 bytes pyproject.toml | 33 +++++++++++++++++++++++++++++ tests/test_examples.py | 47 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 LICENSE create mode 100644 examples/example.png create mode 100644 pyproject.toml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e8c6262 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 lhyliu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 9348a08..18f5029 100644 --- a/README.md +++ b/README.md @@ -112,9 +112,15 @@ MB values are decimal. Start with `balanced` for most workflows. - `examples/text_only_workflow.json` - `examples/image_chat_workflow.json` -示例使用 `api_key_env` 占位,不包含 API key。 +示例使用 `api_key_env` 占位,不包含 API key。图片示例包含 `examples/example.png` 作为可直接加载的占位图。 -Examples use `api_key_env` placeholders and contain no API keys. +Examples use `api_key_env` placeholders and contain no API keys. The image example includes `examples/example.png` as a loadable placeholder image. + +## 发布 / Release + +Registry metadata lives in `pyproject.toml`, including `[project]` and `[tool.comfy]`. Before publishing, confirm `PublisherId`, `Repository`, `version`, and `LICENSE` match your target release account and repository. + +Registry 发布元数据位于 `pyproject.toml`,包含 `[project]` 与 `[tool.comfy]`。发布前请确认 `PublisherId`、`Repository`、`version` 与 `LICENSE` 符合目标发布账号和仓库。 ## 手动测试 / Manual Smoke Test diff --git a/examples/example.png b/examples/example.png new file mode 100644 index 0000000000000000000000000000000000000000..1436d933339a3afe70442211301d20a00fa4f94c GIT binary patch literal 1155 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K57H}{D$((A{Yz77vFHaZ8kcv5P@9yop6C%@| z=s)GP=X7m`bqZZgE{r7$dpMdxI0LtrufbM&mp^St$F(B|F53&Rch_^^Zs6UT($c7^XFU7Gp^bh^qXaY8l!+OgNrc3 z#XBs*XSp0qU|bdllidz3o0*`pKrW-eSv`S^YZzR1@48SJU-|iOYoE^=`F;PE{4nJA z|Nn3M8^KGga2uGc^OJ<+6))LE`)exk7Aqc44Y$N42w7$ zGME%*F?6UgEV{{>#IM%>F=#&5#x2qDe=08apUaDn{_JyOi!N)y$qVsc&L27OberIT z&c*c?^-nc)Z;?Cjk89uDUR!23<0jfj92#ZM6*mX6=b*)WZxjBcR+UzbEwH*9f3I+?dO>ea*q(+w+>(Wm)x=z7$awW4XPigNh}jUczQGU5xJaF@fCCZ(=(p?L`FVE3QP*&hQt>a4_n9pG4eKB8FrKtiXd z>0g=5LRN`6clU)A$VMdnGXMTY+&yYPr{1Tc6Rq{%)%puB1JxC=xy?VFtK4v}VwQgA z!3)K^bXg73PH8T>8>R4+1GA8#^9|ER_OiwVE?CmM!?Kw@uPG7E z*V?c8sn`Act9cBiwZ)(7?h1oEc7wG^6OS1{DWI1cV-;pB`tJ zd5Ehk=HKp3+6`=61"] +build-backend = "setuptools.build_meta" + +[project] +name = "ComfyUI_LLM_API" +version = "0.1.0" +description = "OpenAI-compatible Chat Completions node for ComfyUI with text and image input support." +readme = "README.md" +requires-python = ">=3.10" +license = { file = "LICENSE" } +dependencies = [ + "openai>=1.0.0", + "Pillow", + "numpy", +] +classifiers = [ + "Operating System :: OS Independent", +] + +[project.optional-dependencies] +dev = [ + "comfy-cli", + "pytest", +] + +[project.urls] +Repository = "https://github.com/lhyliu/ComfyUI_LLM_API" +"Bug Tracker" = "https://github.com/lhyliu/ComfyUI_LLM_API/issues" + +[tool.comfy] +PublisherId = "lhyliu" +DisplayName = "ComfyUI LLM API" diff --git a/tests/test_examples.py b/tests/test_examples.py index c2868fe..19f7929 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -1,5 +1,6 @@ import json import os +import tomllib import unittest try: @@ -10,6 +11,8 @@ except ImportError: ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) EXAMPLES_DIR = os.path.join(ROOT_DIR, "examples") +PYPROJECT_PATH = os.path.join(ROOT_DIR, "pyproject.toml") +LICENSE_PATH = os.path.join(ROOT_DIR, "LICENSE") class ExampleWorkflowTests(unittest.TestCase): @@ -48,6 +51,50 @@ class ExampleWorkflowTests(unittest.TestCase): output_names = [output["name"] for output in node.get("outputs", [])] self.assertEqual(output_names, ["response", "error"]) + def test_load_image_examples_reference_tracked_assets(self): + paths = [ + os.path.join(EXAMPLES_DIR, name) + for name in os.listdir(EXAMPLES_DIR) + if name.endswith(".json") + ] + + for path in paths: + with self.subTest(path=path): + with open(path, "r", encoding="utf-8") as handle: + workflow = json.load(handle) + for node in workflow.get("nodes", []): + if node.get("type") != "LoadImage": + continue + image_name = node.get("widgets_values", [""])[0] + image_path = os.path.join(EXAMPLES_DIR, image_name) + self.assertTrue( + os.path.isfile(image_path), + f"{image_name} is missing for {path}", + ) + + def test_registry_release_metadata_is_present(self): + self.assertTrue(os.path.isfile(PYPROJECT_PATH), "pyproject.toml is missing") + self.assertTrue(os.path.isfile(LICENSE_PATH), "LICENSE is missing") + + with open(PYPROJECT_PATH, "rb") as handle: + metadata = tomllib.load(handle) + + project = metadata["project"] + self.assertEqual(project["name"], "ComfyUI_LLM_API") + self.assertRegex(project["version"], r"^\d+\.\d+\.\d+$") + self.assertEqual(project["license"]["file"], "LICENSE") + self.assertIn("openai>=1.0.0", project["dependencies"]) + self.assertIn("Pillow", project["dependencies"]) + self.assertIn("numpy", project["dependencies"]) + self.assertIn("Repository", project["urls"]) + dev_dependencies = metadata["project"]["optional-dependencies"]["dev"] + self.assertIn("pytest", dev_dependencies) + self.assertIn("comfy-cli", dev_dependencies) + + comfy = metadata["tool"]["comfy"] + self.assertEqual(comfy["PublisherId"], "lhyliu") + self.assertEqual(comfy["DisplayName"], "ComfyUI LLM API") + if __name__ == "__main__": unittest.main()