Skip to content

Commit 1a1a2c6

Browse files
authored
feat: install extensions via a button and fix pip wrapper (#611)
* feat: add button to check dependencies in extension management UI * fix: correct command construction in pip_install_wrapper * feat: refactor Gradio UI integration to use main_block function * feat: improve readability and structure in extension external installer * feat: implement install button for extension marketplace * chore: readme * style: format code for consistency and readability in test files * style: format code for consistency and readability in tts_webui files * style: reorganize imports for consistency and readability across test files via isort * style: reorganize imports for consistency and readability across tts_webui files via isort * fix: add missing import for messaging_js in external extensions installer * refactor: remove unnecessary global declarations in config management functions * fix: handle directory changes safely in tests to avoid errors in CI environments * fix: update tests to verify loading of all extension files, including catalog * chore: run black on tests * fix: update tts-webui extensions versions in Dockerfile and CI test * fix: test --only-binary :all: * fix: test --only-binary :all: without antlr4-python3-runtime * fix: quote extension package names in requirements installation * fix: remove deprecated extension package versions from requirements installation * chore: migrate tts-webui-extension.audiocraft and vall-e-x to requirements.txt * chore: migrate tts-webui-extension.audiocraft and vall-e-x to requirements.txt in pip tester * chore: increase TTS WebUI version
1 parent 65ae2dc commit 1a1a2c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+605
-348
lines changed

.github/workflows/test-pip-install.yaml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,10 @@ jobs:
5858
shell: bash
5959
run: |
6060
python -m pip install -r requirements.txt \
61-
tts-webui-extension.bark_voice_clone>=0.0.1 \
62-
tts-webui-extension.rvc>=0.0.3 \
63-
tts-webui-extension.audiocraft>=0.0.2 \
64-
tts-webui-extension.styletts2>=0.1.0 \
65-
tts-webui-extension.vall_e_x>=0.1.0 \
66-
tts-webui-extension.stable_audio>=0.1.1 \
61+
"tts-webui-extension.bark_voice_clone>=0.0.2" \
62+
"tts-webui-extension.rvc>=0.0.5" \
63+
"tts-webui-extension.styletts2>=0.1.0" \
64+
"tts-webui-extension.stable_audio>=0.1.1" \
6765
--extra-index-url https://tts-webui.github.io/extensions-index/
6866
6967
- name: Test tts_webui

Dockerfile

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,10 @@ WORKDIR /app/tts-webui
4040
# Install all requirements
4141
RUN pip3 install --no-cache-dir torch==$TORCH_VERSION -r requirements.txt
4242
# RUN pip install --no-cache-dir --verbose torch==$TORCH_VERSION -r requirements.txt
43-
RUN pip install tts-webui-extension.bark_voice_clone>=0.0.1 --extra-index-url https://tts-webui.github.io/extensions-index/
44-
RUN pip install tts-webui-extension.rvc>=0.0.3 --extra-index-url https://tts-webui.github.io/extensions-index/
45-
RUN pip install tts-webui-extension.audiocraft>=0.0.2 --extra-index-url https://tts-webui.github.io/extensions-index/
46-
RUN pip install tts-webui-extension.styletts2>=0.1.0 --extra-index-url https://tts-webui.github.io/extensions-index/
47-
RUN pip install tts-webui-extension.vall_e_x>=0.1.0 --extra-index-url https://tts-webui.github.io/extensions-index/
48-
# RUN pip install tts-webui-extension.stable_audio>=0.1.1 --extra-index-url https://tts-webui.github.io/extensions-index/
43+
RUN pip install "tts-webui-extension.bark_voice_clone>=0.0.2" --extra-index-url https://tts-webui.github.io/extensions-index/
44+
RUN pip install "tts-webui-extension.rvc>=0.0.6" --extra-index-url https://tts-webui.github.io/extensions-index/
45+
RUN pip install "tts-webui-extension.styletts2>=0.1.0" --extra-index-url https://tts-webui.github.io/extensions-index/
46+
# RUN pip install "tts-webui-extension.stable_audio>=0.1.1" --extra-index-url https://tts-webui.github.io/extensions-index/
4947

5048

5149
# add postgres & run setup

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,8 @@ November:
176176
* Add extension marketplace directly in the Gradio UI using iframe
177177
* Move voices-tortoise to voices/tortoise/ (and maha-tts to voices/maha_tts/)
178178
* feat: add comprehensive test suite for tts_webui modules
179-
179+
* feat: implement install button for extension marketplace
180+
* feat: add button to check dependencies in extension management UI
180181
181182
October:
182183
* Update Gradio to 5.49.1

documentation/manual_installation.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,15 @@ To install the default extensions, run and restart the server:
140140
pip install -r requirements.txt \
141141
tts-webui-extension.bark_voice_clone>=0.0.1 \
142142
tts-webui-extension.rvc>=0.0.3 \
143-
tts-webui-extension.audiocraft>=0.0.2 \
144143
tts-webui-extension.styletts2>=0.1.0 \
145-
tts-webui-extension.vall_e_x>=0.1.0 \
146144
tts-webui-extension.stable_audio>=0.1.1 \
147145
--extra-index-url https://tts-webui.github.io/extensions-index/
148146
```
149147

150148
(One line in case of copy-paste issues)
151149

152150
```bash
153-
pip install -r requirements.txt tts-webui-extension.bark_voice_clone>=0.0.1 tts-webui-extension.rvc>=0.0.3 tts-webui-extension.audiocraft>=0.0.2 tts-webui-extension.styletts2>=0.1.0 tts-webui-extension.vall_e_x>=0.1.0 tts-webui-extension.stable_audio>=0.1.1 hydra-core==1.3.2 nvidia-ml-py --extra-index-url https://tts-webui.github.io/extensions-index/
151+
pip install -r requirements.txt tts-webui-extension.bark_voice_clone>=0.0.1 tts-webui-extension.rvc>=0.0.3 tts-webui-extension.styletts2>=0.1.0 tts-webui-extension.stable_audio>=0.1.1 hydra-core==1.3.2 nvidia-ml-py --extra-index-url https://tts-webui.github.io/extensions-index/
154152
```
155153

156154
In case of failures, try installing the extensions one by one.

extensions/builtin/extension_external_extensions_installer/__init__.py

Whitespace-only changes.

extensions/builtin/extension_external_extensions_installer/main.py

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import gradio as gr
77

88
from tts_webui.utils.pip_install import pip_install_wrapper
9+
from .messaging_js import messaging_js
910

1011
EXTERNAL_EXTENSIONS_FILE = "extensions.external.json"
1112
CATALOG_DIR = os.path.join("data", "extensions-catalog")
@@ -99,17 +100,24 @@ def _render_preview(entries: List[Dict[str, Any]]) -> str:
99100
header = "| Name | Package | Class | Type |\n|---|---|---|---|\n"
100101
rows = []
101102
for e in entries:
102-
rows.append(f"| {e['name']} | {e['package_name']} | {e['extension_class']} | {e['extension_type']} |")
103+
rows.append(
104+
f"| {e['name']} | {e['package_name']} | {e['extension_class']} | {e['extension_type']} |"
105+
)
103106
return gr.Markdown(header + "\n".join(rows))
104107

108+
105109
def _sync_catalog_via_git() -> Tuple[str, str]:
106110
# Try: clone if missing, else pull fast-forward; return output or error.
107111
try:
108-
if not os.path.isdir(CATALOG_DIR) or not os.path.isdir(os.path.join(CATALOG_DIR, ".git")):
112+
if not os.path.isdir(CATALOG_DIR) or not os.path.isdir(
113+
os.path.join(CATALOG_DIR, ".git")
114+
):
109115
cmd = ["git", "clone", "--depth=1", CATALOG_REPO, CATALOG_DIR]
110116
else:
111117
cmd = ["git", "-C", CATALOG_DIR, "pull", "--ff-only"]
112-
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
118+
proc = subprocess.run(
119+
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
120+
)
113121
if proc.returncode != 0:
114122
msg = proc.stderr.strip() or proc.stdout.strip() or "Unknown git error"
115123
return f"Git failed: {msg}", ""
@@ -143,7 +151,10 @@ def _add_to_external(entries: List[Dict[str, Any]]) -> Tuple[str, str]:
143151
added.append(e.get("package_name"))
144152
data["tabs"] = tabs
145153
ok, msg = _save_external_extensions(data)
146-
status = ("Saved" if ok else msg) + f" | Added: {', '.join(added) if added else 'none'} | Skipped (exists): {', '.join(skipped) if skipped else 'none'}"
154+
status = (
155+
("Saved" if ok else msg)
156+
+ f" | Added: {', '.join(added) if added else 'none'} | Skipped (exists): {', '.join(skipped) if skipped else 'none'}"
157+
)
147158
return status, json.dumps(data, indent=2, ensure_ascii=False)
148159

149160

@@ -158,21 +169,44 @@ def _install_selected(entries: List[Dict[str, Any]]):
158169
yield from pip_install_wrapper(req, name)()
159170

160171

172+
EXTENSION_CATALOG_IFRAME_ID = "extension-catalog"
173+
174+
161175
def extension__tts_generation_webui():
162-
gr.Markdown("""
163-
## External Extensions Installer
176+
gr.Markdown(
177+
"""
164178
Paste one or more extension JSON objects below. We'll validate, preview, and let you add them to `extensions.external.json` and optionally install their requirements right away.
179+
"""
180+
)
165181

166-
You can discover and copy extension JSON entries from the [TTS WebUI Extension Catalog](https://rsxdalv.github.io/tts-webui-extension-catalog/).
167-
""")
168-
169182
with gr.Accordion("Browse Extension Catalog", open=True):
170183
gr.HTML(
171-
"""<iframe width="100%" height="600px" src="https://rsxdalv.github.io/tts-webui-extension-catalog/?browse=true" title="TTS WebUI Extension Catalog" frameborder="0" allowfullscreen></iframe>"""
184+
f"""<iframe id={EXTENSION_CATALOG_IFRAME_ID}
185+
width="100%"
186+
height="800px"
187+
src="https://rsxdalv.github.io/tts-webui-extension-catalog/?browse=true&iframe=true"
188+
title="TTS WebUI Extension Catalog"
189+
frameborder="0"
190+
></iframe>
191+
<div id="json-container" hidden></div>
192+
"""
193+
)
194+
195+
init = gr.Timer(0.5)
196+
init.tick(
197+
fn=lambda: gr.Timer(active=False),
198+
inputs=[],
199+
outputs=[init],
200+
js=messaging_js,
172201
)
173202

174203
with gr.Row():
175-
json_input = gr.Textbox(label="Extension JSON", lines=16, placeholder="Paste JSON object or array of objects here")
204+
json_input = gr.Textbox(
205+
label="Extension JSON",
206+
lines=16,
207+
placeholder="Paste JSON object or array of objects here",
208+
)
209+
json_input_automatic = gr.Textbox(visible=False)
176210
with gr.Row():
177211
parse_btn = gr.Button("Parse JSON", variant="primary")
178212
add_btn = gr.Button("Add to external list", variant="secondary")
@@ -199,6 +233,32 @@ def _on_parse(text: str):
199233
entries, info = _parse_json_input(text)
200234
return entries, _render_preview(entries), info
201235

236+
gr.Button("", elem_id="receive_extension_button").click(
237+
fn=None,
238+
inputs=[],
239+
outputs=[json_input, json_input_automatic],
240+
js="""
241+
() => {
242+
json_value = document.getElementById('json-container').innerText;
243+
return [json_value, json_value];
244+
}
245+
""",
246+
)
247+
248+
json_input_automatic.change(
249+
fn=_on_parse,
250+
inputs=[json_input_automatic],
251+
outputs=[parsed_state, preview_md, parse_info],
252+
).then(
253+
fn=_add_to_external,
254+
inputs=[parsed_state],
255+
outputs=[parse_info, current_json],
256+
).then(
257+
fn=_install_selected,
258+
inputs=[parsed_state],
259+
outputs=[console_html],
260+
)
261+
202262
parse_btn.click(
203263
fn=_on_parse,
204264
inputs=[json_input],
@@ -231,7 +291,7 @@ def _on_sync():
231291
"package_name": "extensions.builtin.extension_external_extensions_installer",
232292
"name": "External Extensions Installer",
233293
"requirements": "builtin",
234-
"description": "Add external extension entries via JSON and install them without restarts. Sync and apply the public extensions catalog via Git.",
294+
"description": "Add external extension entries via JSON and install them without restarts. Sync and apply the public extensions catalog via Git.",
235295
"extension_type": "interface",
236296
"extension_class": "settings",
237297
"author": "rsxdalv",
@@ -245,7 +305,7 @@ def _on_sync():
245305

246306
if __name__ == "__main__":
247307
if "demo" in locals():
248-
demo.close() # type: ignore
308+
locals()["demo"].close()
249309
with gr.Blocks() as demo:
250310
with gr.Tab("External Extensions Installer"):
251311
extension__tts_generation_webui()
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
messaging_js = """
3+
() => {{
4+
const iframe = document.getElementById('extension-catalog');
5+
6+
window.addEventListener('message', (event) => {
7+
if (event.source !== iframe.contentWindow) return;
8+
if (event.data.type === 'install-extension') {
9+
const extension = event.data.data;
10+
11+
document.getElementById('json-container').innerText =
12+
JSON.stringify(extension, null, 2);
13+
document.getElementById('receive_extension_button').click();
14+
}
15+
});
16+
17+
console.log("Extension catalog iframe messaging initialized.");
18+
}}
19+
"""

installer_scripts/js/initializeApp.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,8 @@ const extensions = [
174174
name: "Bark Voice Clone",
175175
package: '"tts-webui-extension.bark_voice_clone>=0.0.1"',
176176
},
177-
{ name: "RVC", package: '"tts-webui-extension.rvc>=0.0.3"' },
178-
{ name: "Audiocraft", package: '"tts-webui-extension.audiocraft>=0.0.2"' },
179-
{ name: "StyleTTS", package: '"tts-webui-extension.styletts2>=0.1.0"' },
180-
{ name: "Vall-E-X", package: '"tts-webui-extension.vall_e_x>=0.1.0"' },
177+
{ name: "RVC", package: '"tts-webui-extension.rvc>=0.0.5"' },
178+
{ name: "StyleTTS", package: '"tts-webui-extension.styletts2>=0.1.1"' }, // pypi
181179
{
182180
name: "Stable Audio",
183181
package: '"tts-webui-extension.stable_audio>=0.1.1"',

installer_scripts/versions.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"version": "1.0.0",
3-
"pip_packages": 22,
3+
"pip_packages": 30,
44
"npm_packages": 4,
55
"react_ui": 4
66
}

notebooks/google_colab.ipynb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@
3636
"!pip install uv\n",
3737
"!uv pip install --no-progress --system tts-webui-extension.bark_voice_clone>=0.0.1 --extra-index-url https://tts-webui.github.io/extensions-index/\n",
3838
"!uv pip install --no-progress --system tts-webui-extension.rvc>=0.0.3 --extra-index-url https://tts-webui.github.io/extensions-index/\n",
39-
"!uv pip install --no-progress --system tts-webui-extension.audiocraft>=0.0.2 --extra-index-url https://tts-webui.github.io/extensions-index/\n",
4039
"!uv pip install --no-progress --system tts-webui-extension.styletts2>=0.1.0 --extra-index-url https://tts-webui.github.io/extensions-index/\n",
41-
"!uv pip install --no-progress --system tts-webui-extension.vall_e_x>=0.1.0 --extra-index-url https://tts-webui.github.io/extensions-index/\n",
4240
"!uv pip install --no-progress --system tts-webui-extension.stable_audio>=0.1.1 --extra-index-url https://tts-webui.github.io/extensions-index/\n"
4341
]
4442
},

0 commit comments

Comments
 (0)