xray918's picture
Upload folder using huggingface_hub
0ad74ed verified
raw
history blame
6.71 kB
from __future__ import annotations
import importlib
import shutil
import subprocess
from pathlib import Path
from typing import Annotated, Optional
import semantic_version
import typer
from tomlkit import dump, parse
import gradio
from gradio.analytics import custom_component_analytics
from gradio.cli.commands.components._docs_utils import (
get_deep,
)
from gradio.cli.commands.components.docs import run_command
from gradio.cli.commands.components.install_component import _get_executable_path
from gradio.cli.commands.display import LivePanelDisplay
gradio_template_path = Path(gradio.__file__).parent / "templates" / "frontend"
def _build(
path: Annotated[
Path, typer.Argument(help="The directory of the custom component.")
] = Path("."),
build_frontend: Annotated[
bool, typer.Option(help="Whether to build the frontend as well.")
] = True,
bump_version: Annotated[
bool, typer.Option(help="Whether to bump the version number automatically.")
] = False,
generate_docs: Annotated[
bool, typer.Option(help="Whether to generate the documentation as well.")
] = True,
python_path: Annotated[
Optional[str],
typer.Option(
help="Path to python executable. If None, will use the default path found by `which python3`. If python3 is not found, `which python` will be tried. If both fail an error will be raised."
),
] = None,
):
custom_component_analytics(
"build",
None,
None,
None,
None,
generate_docs=generate_docs,
bump_version=bump_version,
)
name = Path(path).resolve()
if not (name / "pyproject.toml").exists():
raise ValueError(f"Cannot find pyproject.toml file in {name}")
with LivePanelDisplay() as live:
live.update(
f":package: Building package in [orange3]{str(name.name)}[/]", add_sleep=0.2
)
pyproject_toml = parse((path / "pyproject.toml").read_text())
package_name = get_deep(pyproject_toml, ["project", "name"])
python_path = _get_executable_path(
"python", python_path, "--python-path", check_3=True
)
if not isinstance(package_name, str):
raise ValueError(
"Your pyproject.toml file does not have a [project] name field!"
)
try:
importlib.import_module(package_name) # type: ignore
except ModuleNotFoundError as e:
raise ValueError(
f"Your custom component package ({package_name}) is not installed! "
"Please install it with the gradio cc install command before building it."
) from e
if bump_version:
pyproject_toml = parse((path / "pyproject.toml").read_text())
version = semantic_version.Version(
pyproject_toml["project"]["version"] # type: ignore
).next_patch()
live.update(
f":1234: Using version [bold][magenta]{version}[/][/]. "
"Set [bold][magenta]--no-bump-version[/][/] to use the version in pyproject.toml file."
)
pyproject_toml["project"]["version"] = str(version) # type: ignore
with open(path / "pyproject.toml", "w", encoding="utf-8") as f:
dump(pyproject_toml, f)
else:
version = pyproject_toml["project"]["version"] # type: ignore
live.update(
f":1234: Package will use version [bold][magenta]{version}[/][/] defined in pyproject.toml file. "
"Set [bold][magenta]--bump-version[/][/] to automatically bump the version number."
)
if generate_docs:
_demo_dir = Path("demo").resolve()
_demo_name = "app.py"
_demo_path = _demo_dir / _demo_name
_readme_path = name / "README.md"
run_command(
live=live,
name=package_name,
suppress_demo_check=False,
pyproject_toml=pyproject_toml,
generate_space=True,
generate_readme=True,
type_mode="simple",
_demo_path=_demo_path,
_demo_dir=_demo_dir,
_readme_path=_readme_path,
space_url=None,
_component_dir=name,
simple=True,
)
if build_frontend:
live.update(":art: Building frontend")
component_directory = path.resolve()
node = shutil.which("node")
if not node:
raise ValueError(
"node must be installed in order to run build command."
)
gradio_node_path = subprocess.run(
[node, "-e", "console.log(require.resolve('@gradio/preview'))"],
cwd=Path(component_directory / "frontend"),
check=False,
capture_output=True,
)
if gradio_node_path.returncode != 0:
raise ValueError(
"Could not find `@gradio/preview`. Run `npm i -D @gradio/preview` in your frontend folder."
)
gradio_node_path = gradio_node_path.stdout.decode("utf-8").strip()
node_cmds = [
node,
gradio_node_path,
"--component-directory",
component_directory,
"--root",
gradio_template_path,
"--mode",
"build",
"--python-path",
python_path,
]
pipe = subprocess.run(
node_cmds, capture_output=True, text=True, check=False
)
if pipe.returncode != 0:
live.update(":red_square: Build failed!")
live.update(pipe.stderr)
live.update(pipe.stdout)
raise SystemExit("Frontend build failed")
else:
live.update(":white_check_mark: Build succeeded!")
cmds = [python_path, "-m", "build", str(name)]
live.update(f":construction_worker: Building... [grey37]({' '.join(cmds)})[/]")
pipe = subprocess.run(cmds, capture_output=True, text=True, check=False)
if pipe.returncode != 0:
live.update(":red_square: Build failed!")
live.update(pipe.stderr)
raise SystemExit("Python build failed")
else:
live.update(":white_check_mark: Build succeeded!")
live.update(
f":ferris_wheel: Wheel located in [orange3]{str(name / 'dist')}[/]"
)