mirror of
https://github.com/gradio-app/gradio.git
synced 2024-11-27 01:40:20 +08:00
Add a stand-alone install command and tidy-up the fallback template (#6092)
* Add code * add changeset * Add test * Make install default * Better error message --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
This commit is contained in:
parent
cd8146ba05
commit
11d67ae752
6
.changeset/mighty-coats-do.md
Normal file
6
.changeset/mighty-coats-do.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"@gradio/fallback": minor
|
||||
"gradio": minor
|
||||
---
|
||||
|
||||
feat:Add a stand-alone install command and tidy-up the fallback template
|
@ -2,6 +2,7 @@ import sys
|
||||
|
||||
import typer
|
||||
from gradio_client.cli import deploy_discord # type: ignore
|
||||
from rich.console import Console
|
||||
|
||||
from .commands import custom_component, deploy, print_environment_info, reload
|
||||
|
||||
@ -27,5 +28,12 @@ def cli():
|
||||
elif args[0] in {"cc", "component"}:
|
||||
sys.argv = sys.argv[1:]
|
||||
custom_component()
|
||||
elif args[0] in {"build", "dev", "create", "show", "publish"}:
|
||||
try:
|
||||
error = f"gradio {args[0]} is not a valid command. Did you mean `gradio cc {args[0]}` or `gradio component {args[0]}`?."
|
||||
raise ValueError(error)
|
||||
except ValueError:
|
||||
console = Console()
|
||||
console.print_exception()
|
||||
else:
|
||||
typer.run(reload)
|
||||
|
@ -3,6 +3,7 @@ from typer import Typer
|
||||
from .build import _build
|
||||
from .create import _create
|
||||
from .dev import _dev
|
||||
from .install_component import _install
|
||||
from .show import _show
|
||||
|
||||
app = Typer(help="Create and publish a new Gradio component")
|
||||
@ -14,3 +15,6 @@ app.command(
|
||||
)(_build)
|
||||
app.command("dev", help="Launch the custom component demo in development mode.")(_dev)
|
||||
app.command("show", help="Show the list of available templates")(_show)
|
||||
app.command("install", help="Install the custom component in the current environment")(
|
||||
_install
|
||||
)
|
||||
|
@ -1,14 +1,12 @@
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import typer
|
||||
from rich.markup import escape
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from gradio.cli.commands.components.install_component import _get_npm, _install_command
|
||||
from gradio.cli.commands.display import LivePanelDisplay
|
||||
from gradio.utils import set_directory
|
||||
|
||||
from . import _create_utils
|
||||
|
||||
@ -41,7 +39,7 @@ def _create(
|
||||
typer.Option(
|
||||
help="Whether to install the component in your current environment as a development install. Recommended for development."
|
||||
),
|
||||
] = False,
|
||||
] = True,
|
||||
npm_install: Annotated[
|
||||
str,
|
||||
typer.Option(help="NPM install command to use. Default is 'npm install'."),
|
||||
@ -69,17 +67,8 @@ def _create(
|
||||
|
||||
if _create_utils._in_test_dir():
|
||||
npm_install = f"{shutil.which('pnpm')} i --ignore-scripts"
|
||||
|
||||
npm_install = npm_install.strip()
|
||||
if npm_install == "npm install":
|
||||
npm = shutil.which("npm")
|
||||
if not npm:
|
||||
raise ValueError(
|
||||
"By default, the install command uses npm to install "
|
||||
"the frontend dependencies. Please install npm or pass your own install command "
|
||||
"via the --npm-install option."
|
||||
)
|
||||
npm_install = f"{npm} install"
|
||||
else:
|
||||
npm_install = _get_npm(npm_install)
|
||||
|
||||
with LivePanelDisplay() as live:
|
||||
live.update(
|
||||
@ -102,28 +91,4 @@ def _create(
|
||||
live.update(":art: Created frontend code", add_sleep=0.2)
|
||||
|
||||
if install:
|
||||
cmds = [shutil.which("pip"), "install", "-e", f"{str(directory)}[dev]"]
|
||||
live.update(
|
||||
f":construction_worker: Installing python... [grey37]({escape(' '.join(cmds))})[/]"
|
||||
)
|
||||
pipe = subprocess.run(cmds, capture_output=True, text=True)
|
||||
|
||||
if pipe.returncode != 0:
|
||||
live.update(":red_square: Python installation [bold][red]failed[/][/]")
|
||||
live.update(pipe.stderr)
|
||||
else:
|
||||
live.update(":white_check_mark: Python install succeeded!")
|
||||
|
||||
live.update(
|
||||
f":construction_worker: Installing javascript... [grey37]({npm_install})[/]"
|
||||
)
|
||||
with set_directory(directory / "frontend"):
|
||||
pipe = subprocess.run(
|
||||
npm_install.split(), capture_output=True, text=True
|
||||
)
|
||||
if pipe.returncode != 0:
|
||||
live.update(":red_square: NPM install [bold][red]failed[/][/]")
|
||||
live.update(pipe.stdout)
|
||||
live.update(pipe.stderr)
|
||||
else:
|
||||
live.update(":white_check_mark: NPM install succeeded!")
|
||||
_install_command(directory, live, npm_install)
|
||||
|
63
gradio/cli/commands/components/install_component.py
Normal file
63
gradio/cli/commands/components/install_component.py
Normal file
@ -0,0 +1,63 @@
|
||||
import shutil
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from rich.markup import escape
|
||||
from typer import Argument, Option
|
||||
from typing_extensions import Annotated
|
||||
|
||||
from gradio.cli.commands.display import LivePanelDisplay
|
||||
from gradio.utils import set_directory
|
||||
|
||||
|
||||
def _get_npm(npm_install: str):
|
||||
npm_install = npm_install.strip()
|
||||
if npm_install == "npm install":
|
||||
npm = shutil.which("npm")
|
||||
if not npm:
|
||||
raise ValueError(
|
||||
"By default, the install command uses npm to install "
|
||||
"the frontend dependencies. Please install npm or pass your own install command "
|
||||
"via the --npm-install option."
|
||||
)
|
||||
npm_install = f"{npm} install"
|
||||
return npm_install
|
||||
|
||||
|
||||
def _install_command(directory: Path, live: LivePanelDisplay, npm_install: str):
|
||||
cmds = [shutil.which("pip"), "install", "-e", f"{str(directory)}[dev]"]
|
||||
live.update(
|
||||
f":construction_worker: Installing python... [grey37]({escape(' '.join(cmds))})[/]"
|
||||
)
|
||||
pipe = subprocess.run(cmds, capture_output=True, text=True)
|
||||
|
||||
if pipe.returncode != 0:
|
||||
live.update(":red_square: Python installation [bold][red]failed[/][/]")
|
||||
live.update(pipe.stderr)
|
||||
else:
|
||||
live.update(":white_check_mark: Python install succeeded!")
|
||||
|
||||
live.update(
|
||||
f":construction_worker: Installing javascript... [grey37]({npm_install})[/]"
|
||||
)
|
||||
with set_directory(directory / "frontend"):
|
||||
pipe = subprocess.run(npm_install.split(), capture_output=True, text=True)
|
||||
if pipe.returncode != 0:
|
||||
live.update(":red_square: NPM install [bold][red]failed[/][/]")
|
||||
live.update(pipe.stdout)
|
||||
live.update(pipe.stderr)
|
||||
else:
|
||||
live.update(":white_check_mark: NPM install succeeded!")
|
||||
|
||||
|
||||
def _install(
|
||||
directory: Annotated[
|
||||
Path, Argument(help="The directory containing the custom components.")
|
||||
] = Path("."),
|
||||
npm_install: Annotated[
|
||||
str, Option(help="NPM install command to use. Default is 'npm install'.")
|
||||
] = "npm install",
|
||||
):
|
||||
npm_install = _get_npm(npm_install)
|
||||
with LivePanelDisplay() as live:
|
||||
_install_command(directory, live, npm_install)
|
@ -11,9 +11,6 @@
|
||||
export let elem_classes: string[] = [];
|
||||
export let visible = true;
|
||||
export let value = false;
|
||||
// export let value_is_output = false;
|
||||
// export let label = "Checkbox";
|
||||
// export let info: string | undefined = undefined;
|
||||
export let container = true;
|
||||
export let scale: number | null = null;
|
||||
export let min_width: number | undefined = undefined;
|
||||
|
@ -6,6 +6,7 @@ import pytest
|
||||
from gradio.cli.commands.components._create_utils import OVERRIDES
|
||||
from gradio.cli.commands.components.build import _build
|
||||
from gradio.cli.commands.components.create import _create
|
||||
from gradio.cli.commands.components.install_component import _install
|
||||
from gradio.cli.commands.components.show import _show
|
||||
|
||||
|
||||
@ -33,7 +34,7 @@ from gradio.cli.commands.components.show import _show
|
||||
],
|
||||
)
|
||||
def test_template_override_component(template, tmp_path):
|
||||
_create("MyComponent", tmp_path, template=template, overwrite=True)
|
||||
_create("MyComponent", tmp_path, template=template, overwrite=True, install=False)
|
||||
app = (tmp_path / "demo" / "app.py").read_text()
|
||||
answer = textwrap.dedent(
|
||||
f"""
|
||||
@ -55,12 +56,18 @@ def test_raise_error_component_template_does_not_exist(tmp_path):
|
||||
match="Cannot find NonExistentComponent in gradio.components or gradio.layouts",
|
||||
):
|
||||
_create(
|
||||
"MyComponent", tmp_path, template="NonExistentComponent", overwrite=True
|
||||
"MyComponent",
|
||||
tmp_path,
|
||||
template="NonExistentComponent",
|
||||
overwrite=True,
|
||||
install=False,
|
||||
)
|
||||
|
||||
|
||||
def test_do_not_replace_class_name_in_import_statement(tmp_path):
|
||||
_create("MyImage", template="Image", directory=tmp_path, overwrite=True)
|
||||
_create(
|
||||
"MyImage", template="Image", directory=tmp_path, overwrite=True, install=False
|
||||
)
|
||||
code = (tmp_path / "backend" / "gradio_myimage" / "myimage.py").read_text()
|
||||
assert "from PIL import Image as _Image" in code
|
||||
assert "class MyImage" in code
|
||||
@ -100,3 +107,17 @@ def test_build(tmp_path):
|
||||
assert template_dir.exists() and template_dir.is_dir()
|
||||
assert list(template_dir.glob("**/index.js"))
|
||||
assert (tmp_path / "dist").exists() and list((tmp_path / "dist").glob("*.whl"))
|
||||
|
||||
|
||||
def test_install(tmp_path):
|
||||
_create(
|
||||
"TestTextbox",
|
||||
template="Textbox",
|
||||
directory=tmp_path,
|
||||
overwrite=True,
|
||||
install=False,
|
||||
)
|
||||
|
||||
assert not (tmp_path / "frontend" / "node_modules").exists()
|
||||
_install(tmp_path)
|
||||
assert (tmp_path / "frontend" / "node_modules").exists()
|
||||
|
Loading…
Reference in New Issue
Block a user