From 6ee22dc6a8f6419e127a0f650e58c87a31bc59c9 Mon Sep 17 00:00:00 2001 From: pngwn Date: Thu, 25 Jan 2024 19:03:21 +0000 Subject: [PATCH] Ensure `gradio cc publish` uploads the documentation space, if it exists. (#7159) * changes * add changeset * lint * tweaks --------- Co-authored-by: gradio-pr-bot --- .changeset/some-birds-live.md | 5 ++ gradio/cli/commands/components/publish.py | 68 +++++++++++++++++++---- 2 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 .changeset/some-birds-live.md diff --git a/.changeset/some-birds-live.md b/.changeset/some-birds-live.md new file mode 100644 index 0000000000..922dc73283 --- /dev/null +++ b/.changeset/some-birds-live.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Ensure `gradio cc publish` uploads the documentation space, if it exists. diff --git a/gradio/cli/commands/components/publish.py b/gradio/cli/commands/components/publish.py index 7f40a32a71..c38ec6da9f 100644 --- a/gradio/cli/commands/components/publish.py +++ b/gradio/cli/commands/components/publish.py @@ -5,6 +5,7 @@ import tempfile from pathlib import Path from typing import List, Optional +import httpx import semantic_version from huggingface_hub import HfApi from rich import print @@ -31,7 +32,9 @@ license: apache-2.0 --- """ -DOCKERFILE = """ + +def make_dockerfile(demo): + return f""" FROM python:3.9 WORKDIR /code @@ -51,7 +54,7 @@ ENV PYTHONUNBUFFERED=1 \ GRADIO_SERVER_PORT=7860 \ SYSTEM=spaces -CMD ["python", "app.py"] +CMD ["python", "{demo}"] """ @@ -102,9 +105,7 @@ def _publish( ] = None, source_dir: Annotated[ Optional[Path], - Option( - help="Path to the source directory of the custom component. To share with community." - ), + Option(help="Path to the source directory of the custom component."), ] = None, hf_token: Annotated[ Optional[str], @@ -112,8 +113,19 @@ def _publish( help="HuggingFace token for uploading demo. Can be omitted if already logged in via huggingface cli." ), ] = None, + prefer_local: Annotated[ + bool, + Option( + help="Install the package from the local wheel in the demo space, even if it exists on PyPi." + ), + ] = False, + upload_source: Annotated[ + bool, + Option( + help="Whether to upload the source code of the custom component, to share with the community." + ), + ] = True, ): - upload_source = source_dir is not None console = Console() dist_dir = dist_dir.resolve() name = None @@ -206,7 +218,7 @@ def _publish( demo_dir_ = demo_dir_ or str(Path(".") / "demo") demo_dir = Path(demo_dir_).resolve() - if upload_demo and not source_dir: + if upload_source and not source_dir: panel = Panel( "It is recommended that you share your [magenta]source code[/] so that others can learn from and improve your component." ) @@ -219,10 +231,32 @@ def _publish( source_dir_ = source_dir_ or str(Path(".")) source_dir = Path(source_dir_).resolve() if upload_demo: + pyproject_toml_path = ( + (source_dir / "pyproject.toml") + if source_dir + else Path(".") / "pyproject.toml" + ) + + try: + pyproject_toml = parse(pyproject_toml_path.read_text()) + package_name = pyproject_toml["project"]["name"] # type: ignore + except Exception: + (package_name, version) = wheel_file.name.split("-")[:2] + + try: + latest_release = httpx.get( + f"https://pypi.org/pypi/{package_name}/json" + ).json()["info"]["version"] + except Exception: + latest_release = None + assert demo_dir - if not (demo_dir / "app.py").exists(): - raise FileNotFoundError("app.py not found in demo directory.") - additional_reqs = [wheel_file.name] + demo_path = resolve_demo(demo_dir) + + if prefer_local or not latest_release: + additional_reqs = [wheel_file.name] + else: + additional_reqs = [f"{package_name}=={latest_release}"] if (demo_dir / "requirements.txt").exists(): reqs = (demo_dir / "requirements.txt").read_text().splitlines() reqs += additional_reqs @@ -276,7 +310,7 @@ def _publish( readme.write_text(readme_text) dockerfile = Path(tempdir) / "Dockerfile" - dockerfile.write_text(DOCKERFILE) + dockerfile.write_text(make_dockerfile(demo_path.name)) api = HfApi() new_space = api.create_repo( @@ -302,3 +336,15 @@ def _publish( ) print("\n") print(f"Demo uploaded to {new_space} !") + + +def resolve_demo(demo_dir: Path) -> Path: + _demo_dir = demo_dir.resolve() + if (_demo_dir / "space.py").exists(): + return _demo_dir / "space.py" + elif (_demo_dir / "app.py").exists(): + return _demo_dir / "app.py" + else: + raise FileNotFoundError( + f'Could not find "space.py" or "app.py" in "{demo_dir}".' + )