igerasimov commited on
Commit
9b9b1cd
·
1 Parent(s): 4f5afca

Gradio MVP launcher works both locally and on Hugging Face Spaces

Browse files
Files changed (2) hide show
  1. app.py +24 -1
  2. tests/test_ui.py +45 -1
app.py CHANGED
@@ -1,5 +1,6 @@
1
  """Hugging Face Spaces launcher for the GCMD classifier MVP."""
2
 
 
3
  import sys
4
  from pathlib import Path
5
 
@@ -11,5 +12,27 @@ from gcmd_classifier.ui.gradio_app import GRADIO_CSS, create_demo # noqa: E402
11
 
12
  demo = create_demo()
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  if __name__ == "__main__":
15
- demo.launch(css=GRADIO_CSS)
 
1
  """Hugging Face Spaces launcher for the GCMD classifier MVP."""
2
 
3
+ import os
4
  import sys
5
  from pathlib import Path
6
 
 
12
 
13
  demo = create_demo()
14
 
15
+
16
+ def gradio_server_name() -> str:
17
+ """Return the configured Gradio bind host for local and Spaces runtime."""
18
+ return os.environ.get("GRADIO_SERVER_NAME", "0.0.0.0")
19
+
20
+
21
+ def gradio_server_port() -> int:
22
+ """Return the configured Gradio bind port for local and Spaces runtime."""
23
+ return int(os.environ.get("GRADIO_SERVER_PORT", "7860"))
24
+
25
+
26
+ def launch() -> None:
27
+ """Launch the Gradio demo with Hugging Face compatible server settings."""
28
+ demo.queue().launch(
29
+ css=GRADIO_CSS,
30
+ server_name=gradio_server_name(),
31
+ server_port=gradio_server_port(),
32
+ share=False,
33
+ prevent_thread_lock=False,
34
+ )
35
+
36
+
37
  if __name__ == "__main__":
38
+ launch()
tests/test_ui.py CHANGED
@@ -53,6 +53,11 @@ class FakeLayout:
53
 
54
  class FakeBlocks(FakeLayout):
55
  launched = 0
 
 
 
 
 
56
 
57
  def launch(self, **kwargs: Any) -> None:
58
  self.launch_kwargs = kwargs
@@ -168,6 +173,7 @@ def test_ui_module_does_not_classify_or_call_model_at_import_time(monkeypatch) -
168
 
169
  def test_root_app_imports_without_launching_server(monkeypatch) -> None:
170
  FakeBlocks.launched = 0
 
171
  monkeypatch.setitem(sys.modules, "gradio", _fake_gradio_module())
172
  sys.modules.pop("app", None)
173
 
@@ -175,6 +181,40 @@ def test_root_app_imports_without_launching_server(monkeypatch) -> None:
175
 
176
  assert isinstance(module.demo, FakeBlocks)
177
  assert FakeBlocks.launched == 0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
 
179
 
180
  def test_root_app_is_thin_launcher_without_classification_logic() -> None:
@@ -184,7 +224,11 @@ def test_root_app_is_thin_launcher_without_classification_logic() -> None:
184
  assert "classify_article" not in text
185
  assert "route_topics" not in text
186
  assert "OpenAI" not in text
187
- assert "demo.launch(css=GRADIO_CSS)" in text
 
 
 
 
188
 
189
 
190
  def test_ui_calls_pipeline_service(monkeypatch) -> None:
 
53
 
54
  class FakeBlocks(FakeLayout):
55
  launched = 0
56
+ queued = 0
57
+
58
+ def queue(self):
59
+ type(self).queued += 1
60
+ return self
61
 
62
  def launch(self, **kwargs: Any) -> None:
63
  self.launch_kwargs = kwargs
 
173
 
174
  def test_root_app_imports_without_launching_server(monkeypatch) -> None:
175
  FakeBlocks.launched = 0
176
+ FakeBlocks.queued = 0
177
  monkeypatch.setitem(sys.modules, "gradio", _fake_gradio_module())
178
  sys.modules.pop("app", None)
179
 
 
181
 
182
  assert isinstance(module.demo, FakeBlocks)
183
  assert FakeBlocks.launched == 0
184
+ assert FakeBlocks.queued == 0
185
+
186
+
187
+ def test_root_app_launch_uses_spaces_compatible_settings(monkeypatch) -> None:
188
+ FakeBlocks.launched = 0
189
+ FakeBlocks.queued = 0
190
+ monkeypatch.setitem(sys.modules, "gradio", _fake_gradio_module())
191
+ monkeypatch.setenv("GRADIO_SERVER_NAME", "127.0.0.1")
192
+ monkeypatch.setenv("GRADIO_SERVER_PORT", "9999")
193
+ sys.modules.pop("app", None)
194
+ module = importlib.import_module("app")
195
+
196
+ module.launch()
197
+
198
+ assert FakeBlocks.queued == 1
199
+ assert FakeBlocks.launched == 1
200
+ assert module.demo.launch_kwargs == {
201
+ "css": module.GRADIO_CSS,
202
+ "server_name": "127.0.0.1",
203
+ "server_port": 9999,
204
+ "share": False,
205
+ "prevent_thread_lock": False,
206
+ }
207
+
208
+
209
+ def test_root_app_uses_spaces_default_server_settings(monkeypatch) -> None:
210
+ monkeypatch.setitem(sys.modules, "gradio", _fake_gradio_module())
211
+ monkeypatch.delenv("GRADIO_SERVER_NAME", raising=False)
212
+ monkeypatch.delenv("GRADIO_SERVER_PORT", raising=False)
213
+ sys.modules.pop("app", None)
214
+ module = importlib.import_module("app")
215
+
216
+ assert module.gradio_server_name() == "0.0.0.0"
217
+ assert module.gradio_server_port() == 7860
218
 
219
 
220
  def test_root_app_is_thin_launcher_without_classification_logic() -> None:
 
224
  assert "classify_article" not in text
225
  assert "route_topics" not in text
226
  assert "OpenAI" not in text
227
+ assert "demo.queue().launch" in text
228
+ assert "server_name=gradio_server_name()" in text
229
+ assert "server_port=gradio_server_port()" in text
230
+ assert "share=False" in text
231
+ assert "prevent_thread_lock=False" in text
232
 
233
 
234
  def test_ui_calls_pipeline_service(monkeypatch) -> None: