mattkevan commited on
Commit
4576e13
·
1 Parent(s): cd0ff97

add modal endpoint and magpietts

Browse files
README.md CHANGED
@@ -12,3 +12,12 @@ short_description: Convert your library to the spoken word
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
15
+
16
+ ## Modal backend configuration
17
+
18
+ Set these as Hugging Face Space secrets if you want to use the optional Modal backend:
19
+
20
+ - `SCRIPTORIUM_MODAL_BASE_URL`
21
+ - `SCRIPTORIUM_MODAL_AUTH_TOKEN`
22
+
23
+ `SCRIPTORIUM_MODAL_BASE_URL` must be the deployed `modal.run` web endpoint, not the Modal dashboard URL under `modal.com/apps/...`.
app.py CHANGED
@@ -39,6 +39,15 @@ store = SessionStore(root=TEMP_ROOT, ttl_seconds=SESSION_TTL_SECONDS)
39
  synthesis_service = SynthesisService(session_root=TEMP_ROOT)
40
 
41
 
 
 
 
 
 
 
 
 
 
42
  def _session_root(session_id: str) -> Path:
43
  return store.ensure_session(session_id).root
44
 
 
39
  synthesis_service = SynthesisService(session_root=TEMP_ROOT)
40
 
41
 
42
+ def _warn_about_modal_configuration() -> None:
43
+ warning = synthesis_service.modal_client.configuration_warning()
44
+ if warning:
45
+ print(f"Modal configuration warning: {warning}")
46
+
47
+
48
+ _warn_about_modal_configuration()
49
+
50
+
51
  def _session_root(session_id: str) -> Path:
52
  return store.ensure_session(session_id).root
53
 
backend/modal_client.py CHANGED
@@ -3,6 +3,7 @@ import os
3
  import time
4
  from pathlib import Path
5
  from typing import Dict, Iterable, List, Optional
 
6
 
7
  import requests
8
 
@@ -36,6 +37,21 @@ class ModalSynthesisClient:
36
  def is_configured(self) -> bool:
37
  return bool(self.base_url)
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  def generate_preview(
40
  self,
41
  *,
 
3
  import time
4
  from pathlib import Path
5
  from typing import Dict, Iterable, List, Optional
6
+ from urllib.parse import urlparse
7
 
8
  import requests
9
 
 
37
  def is_configured(self) -> bool:
38
  return bool(self.base_url)
39
 
40
+ def configuration_warning(self) -> Optional[str]:
41
+ if not self.base_url:
42
+ return None
43
+
44
+ parsed = urlparse(self.base_url)
45
+ host = (parsed.netloc or "").lower()
46
+ path = parsed.path or ""
47
+ if host == "modal.com" and path.startswith("/apps/"):
48
+ return (
49
+ "SCRIPTORIUM_MODAL_BASE_URL points to a Modal dashboard URL, not a callable web endpoint. "
50
+ "Use the deployed modal.run base URL instead, for example "
51
+ "'https://<your-app>.modal.run'."
52
+ )
53
+ return None
54
+
55
  def generate_preview(
56
  self,
57
  *,
tests/test_app_startup.py CHANGED
@@ -1,5 +1,6 @@
1
  import importlib
2
  import sys
 
3
 
4
  import gradio as gr
5
 
@@ -31,3 +32,19 @@ def test_launch_app_disables_ssr_for_custom_server_mode(monkeypatch) -> None:
31
  assert captured["server_port"] == 7860
32
  assert captured["ssr_mode"] is False
33
  assert captured["_app"] is module.app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import importlib
2
  import sys
3
+ from types import SimpleNamespace
4
 
5
  import gradio as gr
6
 
 
32
  assert captured["server_port"] == 7860
33
  assert captured["ssr_mode"] is False
34
  assert captured["_app"] is module.app
35
+
36
+
37
+ def test_app_import_warns_for_modal_dashboard_url(monkeypatch) -> None:
38
+ sys.modules.pop("app", None)
39
+ printed = []
40
+
41
+ monkeypatch.setenv(
42
+ "SCRIPTORIUM_MODAL_BASE_URL",
43
+ "https://modal.com/apps/mattkevan/main/deployed/scriptorium-tts",
44
+ )
45
+ monkeypatch.setattr("builtins.print", lambda *args, **kwargs: printed.append(" ".join(str(arg) for arg in args)))
46
+
47
+ importlib.import_module("app")
48
+
49
+ assert any("SCRIPTORIUM_MODAL_BASE_URL" in line for line in printed)
50
+ assert any("modal.run" in line for line in printed)
tests/test_modal_client.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from backend.modal_client import ModalSynthesisClient
2
+
3
+
4
+ def test_modal_client_warns_when_configured_with_dashboard_url() -> None:
5
+ client = ModalSynthesisClient(base_url="https://modal.com/apps/mattkevan/main/deployed/scriptorium-tts")
6
+
7
+ warning = client.configuration_warning()
8
+
9
+ assert warning is not None
10
+ assert "modal.run" in warning
11
+ assert "dashboard" in warning.lower()
12
+
13
+
14
+ def test_modal_client_accepts_modal_run_base_url() -> None:
15
+ client = ModalSynthesisClient(base_url="https://scriptorium-tts--mattkevan.modal.run")
16
+
17
+ assert client.configuration_warning() is None