From b9e7146f99bac42d56d57fcf8cdb961cf4a1f466 Mon Sep 17 00:00:00 2001 From: Thor Whalen <1906276+thorwhalen@users.noreply.github.com> Date: Thu, 30 Jul 2026 10:58:49 +0100 Subject: [PATCH 1/2] fix(specs): unwrap ju rjsf form spec (nest_under_field=None) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ju.rjsf.func_to_form_spec` defaults to `nest_under_field="rjsf"`, so it returns `{"rjsf": {"schema": ..., "uiSchema": ...}}`. `_generate_spec` then read `form_spec.get("schema", {})`, which always yielded `{}` — meaning every generated RJSF form was empty whenever `ju` imported successfully. The empty schema is served straight to the browser by `uf/routes.py` (`spec["schema"]`), so this was user-facing, not just a test artifact. Pass `nest_under_field=None` (via a dict merge, so caller overrides in `_rjsf_config` still win) to get the flat shape `uf` expects — the same shape the `_generate_basic_spec` fallback already emits. Tests: 2 failed / 27 passed -> 29 passed. Claude-Session: https://claude.ai/code/session_01VipiLaG4xy7WctqY9w2475 --- uf/specs.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/uf/specs.py b/uf/specs.py index 635eb4f..cc9ba97 100644 --- a/uf/specs.py +++ b/uf/specs.py @@ -93,7 +93,9 @@ def _generate_spec(self, func_name: str) -> dict: from ju.rjsf import func_to_form_spec # Generate form spec - form_spec = func_to_form_spec(func, **self._rjsf_config) + # ju nests the spec under a "rjsf" field by default; uf wants it flat + rjsf_config = {"nest_under_field": None, **self._rjsf_config} + form_spec = func_to_form_spec(func, **rjsf_config) # Apply custom UI schema factory if provided if self._ui_schema_factory: From 41f770f5bfdf0eb6d3b3dad9bc3a09d05a11ec5f Mon Sep 17 00:00:00 2001 From: Thor Whalen <1906276+thorwhalen@users.noreply.github.com> Date: Thu, 30 Jul 2026 10:59:01 +0100 Subject: [PATCH 2/2] chore(metadata): modernize packaging metadata + add .editorconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - license: replace the deprecated `[project.license] text = "mit"` table with the PEP 639 SPDX string `license = "MIT"` (canonical case). No `License :: OSI Approved ::` trove classifier is added — PyPI rejects that combination alongside an SPDX expression. - keywords: fill in the empty placeholder. - authors: fill in the empty placeholder. - classifiers: add (were absent entirely, so the PyPI page had no trove metadata). - description: "UI Fast" -> the README tagline, which actually says what the package does. The GitHub repo description is set to the same string so the two do not drift. - urls: add `Documentation = "https://i2mint.github.io/uf/"` (already live on the gh-pages branch). - .editorconfig: new, copied verbatim from the fleet reference. Verified with `uv build`: METADATA emits `License-Expression: MIT` and the eight classifiers, with no conflicting license classifier. Claude-Session: https://claude.ai/code/session_01VipiLaG4xy7WctqY9w2475 --- .editorconfig | 17 +++++++++++++++++ pyproject.toml | 32 ++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..88bf4d0 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{py,toml,yml,yaml}] +indent_style = space +indent_size = 4 + +[*.md] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/pyproject.toml b/pyproject.toml index 7a4490e..340ab6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,19 +5,39 @@ build-backend = "hatchling.build" [project] name = "uf" version = "0.1.2" -description = "UI Fast" +description = "Minimal-boilerplate web UIs for Python functions" readme = "README.md" requires-python = ">=3.10" -keywords = [] -authors = [] +license = "MIT" +keywords = [ + "ui", + "forms", + "rjsf", + "json-schema", + "web-ui", + "fastapi", + "bottle", + "python-functions", +] +authors = [ + { name = "Thor Whalen" }, +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.12", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: User Interfaces", + "Framework :: FastAPI", +] dependencies = ["qh", "ju", "i2", "dol", "meshed"] -[project.license] -text = "mit" - [project.urls] Homepage = "https://github.com/i2mint/uf" Repository = "https://github.com/i2mint/uf" +Documentation = "https://i2mint.github.io/uf/" [project.optional-dependencies] dev = ["pytest>=7.0", "pytest-cov>=4.0", "ruff>=0.1.0"]