From b6197f4e1f0723d031404bc2d1b682943bb8a694 Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 17 Dec 2025 18:36:12 -0600 Subject: [PATCH 1/4] refactor: Exclude api-examples from installed package MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove api-examples directory from the wheel distribution to reduce package size by ~400KB. The examples are only needed during documentation builds, which always run from the source repository. Changes: - Update MANIFEST.in to prune api-examples directories - Configure setuptools to explicitly exclude api-examples from package data - Add clear error message when docs are built from installed package - Document that api-examples require source repository The documentation build workflow is unchanged and continues to work from the source tree where api-examples are present. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- MANIFEST.in | 4 +++- pyproject.toml | 11 ++++++++++- shiny/_docstring.py | 10 ++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in index d78ba0416..959c8f9ca 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -9,5 +9,7 @@ recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif recursive-include shiny/www * recursive-include shiny/experimental/www * -recursive-include shiny/api-examples * recursive-include shiny/templates * + +prune shiny/api-examples +prune shiny/experimental/api-examples diff --git a/pyproject.toml b/pyproject.toml index 8115cfa1a..0a3ca5aea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,16 @@ requires = ["setuptools>=60", "wheel", "setuptools_scm>=8.0"] build-backend = "setuptools.build_meta" [tool.setuptools] -packages = { find = { include = ["shiny", "shiny.*"] } } +[tool.setuptools.packages.find] +where = ["."] +include = ["shiny*"] +namespaces = false + +[tool.setuptools.package-data] +"*" = ["www/**/*", "templates/**/*"] + +[tool.setuptools.exclude-package-data] +"*" = ["api-examples/**", "api-examples/**/*"] [tool.setuptools_scm] write_to = "shiny/_version.py" diff --git a/shiny/_docstring.py b/shiny/_docstring.py index 93f7fd747..d012b0d69 100644 --- a/shiny/_docstring.py +++ b/shiny/_docstring.py @@ -8,6 +8,7 @@ def find_api_examples_dir(start_dir: str) -> Optional[str]: current_dir = os.path.abspath(start_dir) + search_start = current_dir while True: api_examples_dir = os.path.join(current_dir, "api-examples") if os.path.isdir(api_examples_dir): @@ -19,6 +20,15 @@ def find_api_examples_dir(start_dir: str) -> Optional[str]: if current_dir == os.path.dirname(current_dir): break # Reached the global root directory current_dir = os.path.dirname(current_dir) + + # Not found - provide helpful error for documentation builders + if os.getenv("SHINY_ADD_EXAMPLES") == "true": + raise FileNotFoundError( + "Could not find 'api-examples/' directory. " + "Documentation must be built from the source repository, " + "not from an installed package. " + f"Searched from: {search_start}" + ) return None From 53d0d31cbc29dfbe4840711a226accb863daeb9a Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 17 Dec 2025 19:42:44 -0600 Subject: [PATCH 2/4] refactor: Simplify glob patterns in pyproject.toml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simplify package-data wildcards from redundant patterns to cleaner syntax: - "www/**/*" → "www/**" - "templates/**/*" → "templates/**" - "api-examples/**/*" → "api-examples/**" The `**` glob pattern already matches all files and subdirectories recursively, making the `/*` suffix redundant. Verified that the wheel still: - Includes 662 www/templates files - Excludes all api-examples files - Maintains same 3.6MB size 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0a3ca5aea..f33b3310f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,10 +9,10 @@ include = ["shiny*"] namespaces = false [tool.setuptools.package-data] -"*" = ["www/**/*", "templates/**/*"] +"*" = ["www/**", "templates/**"] [tool.setuptools.exclude-package-data] -"*" = ["api-examples/**", "api-examples/**/*"] +"*" = ["api-examples/**"] [tool.setuptools_scm] write_to = "shiny/_version.py" From cf43962bfb66434151281253be774b84145840ea Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 17 Dec 2025 19:52:09 -0600 Subject: [PATCH 3/4] refactor: Remove redundant package-data section from pyproject.toml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `[tool.setuptools.package-data]` section specifying `www/**` and `templates/**` was redundant because MANIFEST.in already includes these with `recursive-include` directives. MANIFEST.in directives are respected by both: - Source distribution builds (sdist) - Binary wheel builds (wheel) Only `exclude-package-data` is needed in pyproject.toml to explicitly exclude api-examples, since MANIFEST.in's `prune` directive alone isn't sufficient for wheel builds. Final configuration is now minimal and clean: - MANIFEST.in handles all includes (www, templates) - pyproject.toml handles only the exclude (api-examples) Verified wheel still contains: - 518 www files - 144 template files - 0 api-examples files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f33b3310f..b2a380e11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,9 +8,6 @@ where = ["."] include = ["shiny*"] namespaces = false -[tool.setuptools.package-data] -"*" = ["www/**", "templates/**"] - [tool.setuptools.exclude-package-data] "*" = ["api-examples/**"] From ffafccb506cc52c15bb99b207bc71e124485e867 Mon Sep 17 00:00:00 2001 From: Carson Date: Wed, 17 Dec 2025 19:52:59 -0600 Subject: [PATCH 4/4] docs: Update PR description to reflect simplified pyproject.toml