mirror of
https://github.com/Ladebeze66/projetcbaollm.git
synced 2025-12-18 12:07:48 +01:00
197 lines
7.2 KiB
Python
197 lines
7.2 KiB
Python
from __future__ import annotations
|
|
|
|
import shutil
|
|
from pathlib import Path
|
|
from typing import Annotated, Optional
|
|
|
|
import typer
|
|
from rich import print
|
|
from rich.panel import Panel
|
|
from rich.prompt import Confirm, Prompt
|
|
from tomlkit import dump, parse
|
|
|
|
from gradio.analytics import custom_component_analytics
|
|
|
|
from ..display import LivePanelDisplay
|
|
from . import _create_utils
|
|
from .install_component import _get_npm, _install_command
|
|
|
|
|
|
def _create(
|
|
name: Annotated[
|
|
str,
|
|
typer.Argument(
|
|
help="Name of the component. Preferably in camel case, i.e. MyTextBox."
|
|
),
|
|
],
|
|
directory: Annotated[
|
|
Optional[Path],
|
|
typer.Option(
|
|
help="Directory to create the component in. Default is None. If None, will be created in <component-name> directory in the current directory."
|
|
),
|
|
] = None,
|
|
package_name: Annotated[
|
|
Optional[str],
|
|
typer.Option(help="Name of the package. Default is gradio_{name.lower()}"),
|
|
] = None,
|
|
template: Annotated[
|
|
str,
|
|
typer.Option(
|
|
help="Component to use as a template. Should use exact name of python class."
|
|
),
|
|
] = "",
|
|
install: Annotated[
|
|
bool,
|
|
typer.Option(
|
|
help="Whether to install the component in your current environment as a development install. Recommended for development."
|
|
),
|
|
] = True,
|
|
npm_install: Annotated[
|
|
str,
|
|
typer.Option(help="NPM install command to use. Default is 'npm install'."),
|
|
] = "npm install",
|
|
pip_path: Annotated[
|
|
Optional[str],
|
|
typer.Option(
|
|
help="Path to pip executable. If None, will use the default path found by `which pip3`. If pip3 is not found, `which pip` will be tried. If both fail an error will be raised."
|
|
),
|
|
] = None,
|
|
overwrite: Annotated[
|
|
bool,
|
|
typer.Option(help="Whether to overwrite the existing component if it exists."),
|
|
] = False,
|
|
configure_metadata: Annotated[
|
|
bool,
|
|
typer.Option(
|
|
help="Whether to interactively configure project metadata based on user input"
|
|
),
|
|
] = True,
|
|
):
|
|
custom_component_analytics(
|
|
"create",
|
|
template,
|
|
None,
|
|
None,
|
|
None,
|
|
npm_install=npm_install,
|
|
)
|
|
if not directory:
|
|
directory = Path(name.lower())
|
|
if not package_name:
|
|
package_name = f"gradio_{name.lower()}"
|
|
|
|
if directory.exists() and not overwrite:
|
|
raise ValueError(
|
|
f"The directory {directory.resolve()} already exists. "
|
|
"Please set --overwrite flag or pass in the name "
|
|
"of a directory that does not already exist via the --directory option."
|
|
)
|
|
elif directory.exists() and overwrite:
|
|
_create_utils.delete_contents(directory)
|
|
|
|
directory.mkdir(exist_ok=overwrite)
|
|
|
|
if _create_utils._in_test_dir():
|
|
npm_install = f"{shutil.which('pnpm')} i --ignore-scripts"
|
|
else:
|
|
npm_install = _get_npm(npm_install)
|
|
|
|
with LivePanelDisplay() as live:
|
|
live.update(
|
|
f":building_construction: Creating component [orange3]{name}[/] in directory [orange3]{directory}[/]",
|
|
add_sleep=0.2,
|
|
)
|
|
if template:
|
|
live.update(f":fax: Starting from template [orange3]{template}[/]")
|
|
else:
|
|
live.update(":page_facing_up: Creating a new component from scratch.")
|
|
|
|
component = _create_utils._get_component_code(template)
|
|
|
|
_create_utils._create_backend(name, component, directory, package_name)
|
|
live.update(":snake: Created backend code", add_sleep=0.2)
|
|
|
|
_create_utils._create_frontend(
|
|
name.lower(), component, directory=directory, package_name=package_name
|
|
)
|
|
live.update(":art: Created frontend code", add_sleep=0.2)
|
|
|
|
if install:
|
|
_install_command(directory, live, npm_install, pip_path)
|
|
|
|
live._panel.stop()
|
|
|
|
description = "A gradio custom component"
|
|
keywords = []
|
|
|
|
if configure_metadata:
|
|
print(
|
|
Panel(
|
|
"It is recommended to answer the following [bold][magenta]4 questions[/][/] to finish configuring your custom component's metadata."
|
|
"\nYou can also answer them later by editing the [bold][magenta]pyproject.toml[/][/] file in your component directory."
|
|
)
|
|
)
|
|
|
|
answer_qs = Confirm.ask("\nDo you want to answer them now?")
|
|
|
|
pyproject_toml = parse((directory / "pyproject.toml").read_text())
|
|
|
|
if answer_qs:
|
|
name = pyproject_toml["project"]["name"] # type: ignore
|
|
|
|
description = Prompt.ask(
|
|
"\n:pencil: Please enter a one sentence [bold][magenta]description[/][/] for your component"
|
|
)
|
|
if description:
|
|
pyproject_toml["project"]["description"] = description # type: ignore
|
|
|
|
license_ = (
|
|
Prompt.ask(
|
|
"\n:bookmark_tabs: Please enter a [bold][magenta]software license[/][/] for your component. Leave blank for 'apache-2.0'"
|
|
)
|
|
or "apache-2.0"
|
|
)
|
|
print(f":bookmark_tabs: Using license [bold][magenta]{license_}[/][/]")
|
|
pyproject_toml["project"]["license"] = license_ # type: ignore
|
|
|
|
requires_python = Prompt.ask(
|
|
"\n:snake: Please enter the [bold][magenta]allowed python[/][/] versions for your component. Leave blank for '>=3.10'"
|
|
)
|
|
requires_python = requires_python or ">=3.10"
|
|
print(
|
|
f":snake: Using requires-python of [bold][magenta]{requires_python}[/][/]"
|
|
)
|
|
pyproject_toml["project"]["requires-python"] = ( # type: ignore
|
|
requires_python or ">=3.10"
|
|
)
|
|
|
|
print(
|
|
"\n:label: Please add some keywords to help others discover your component."
|
|
)
|
|
while True:
|
|
keyword = Prompt.ask(":label: Leave blank to stop adding keywords")
|
|
if keyword:
|
|
keywords.append(keyword)
|
|
else:
|
|
break
|
|
current_keywords = pyproject_toml["project"].get("keywords", []) # type: ignore
|
|
pyproject_toml["project"]["keywords"] = current_keywords + keywords # type: ignore
|
|
with open(directory / "pyproject.toml", "w", encoding="utf-8") as f:
|
|
dump(pyproject_toml, f)
|
|
|
|
(directory / "demo" / "requirements.txt").write_text(package_name)
|
|
readme_path = Path(__file__).parent / "files" / "README.md"
|
|
|
|
readme_contents = readme_path.read_text()
|
|
tags = f", {', '.join(keywords)}" if keywords else ""
|
|
template = f", {template}"
|
|
readme_contents = (
|
|
readme_contents.replace("<<title>>", package_name)
|
|
.replace("<<short-description>>", description)
|
|
.replace("<<tags>>", tags)
|
|
.replace("<<template>>", template)
|
|
)
|
|
(directory / "README.md").write_text(readme_contents)
|
|
|
|
print("\nComponent creation [bold][magenta]complete[/][/]!")
|