Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion acestep/ui/gradio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
"""Gradio package: web UI composition for ACE-Step controls and outputs."""
from acestep.ui.gradio.interfaces import create_gradio_interface # noqa: F401

from __future__ import annotations

from typing import Any


def create_gradio_interface(*args: Any, **kwargs: Any) -> Any:
"""Create the Gradio interface using a lazy import.

This keeps package imports lightweight for environments that run unit tests
without Gradio installed, while preserving the existing public facade.
"""
from acestep.ui.gradio.interfaces import create_gradio_interface as _create_gradio_interface

return _create_gradio_interface(*args, **kwargs)
113 changes: 96 additions & 17 deletions acestep/ui/gradio/events/wiring/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,109 @@
event wiring facade in ``acestep.ui.gradio.events``.
"""

from __future__ import annotations

from typing import Any

from .context import (
GenerationWiringContext,
TrainingWiringContext,
build_auto_checkbox_inputs,
build_auto_checkbox_outputs,
build_mode_ui_outputs,
)
from .generation_metadata_wiring import register_generation_metadata_handlers
from .generation_metadata_file_wiring import register_generation_metadata_file_handlers
from .generation_batch_navigation_wiring import register_generation_batch_navigation_handlers
from .generation_mode_wiring import register_generation_mode_handlers
from .generation_run_wiring import register_generation_run_handlers
from .results_aux_wiring import register_results_aux_handlers
from .results_display_wiring import (
register_results_restore_and_lrc_handlers,
register_results_save_button_handlers,
)
from .generation_service_wiring import register_generation_service_handlers
from .training_dataset_builder_wiring import register_training_dataset_builder_handlers
from .training_dataset_preprocess_wiring import (
register_training_dataset_load_handler,
register_training_preprocess_handler,
)
from .training_run_wiring import register_training_run_handlers


def register_generation_metadata_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register metadata-related generation handlers via lazy import."""
from .generation_metadata_wiring import register_generation_metadata_handlers as _register

return _register(*args, **kwargs)


def register_generation_metadata_file_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register generation metadata file handlers via lazy import."""
from .generation_metadata_file_wiring import register_generation_metadata_file_handlers as _register

return _register(*args, **kwargs)


def register_generation_batch_navigation_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register generation batch-navigation handlers via lazy import."""
from .generation_batch_navigation_wiring import register_generation_batch_navigation_handlers as _register

return _register(*args, **kwargs)


def register_generation_mode_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register generation mode handlers via lazy import."""
from .generation_mode_wiring import register_generation_mode_handlers as _register

return _register(*args, **kwargs)


def register_generation_run_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register generation run handlers via lazy import."""
from .generation_run_wiring import register_generation_run_handlers as _register

return _register(*args, **kwargs)


def register_results_aux_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register results auxiliary handlers via lazy import."""
from .results_aux_wiring import register_results_aux_handlers as _register

return _register(*args, **kwargs)


def register_results_restore_and_lrc_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register results restore/LRC handlers via lazy import."""
from .results_display_wiring import register_results_restore_and_lrc_handlers as _register

return _register(*args, **kwargs)


def register_results_save_button_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register results save-button handlers via lazy import."""
from .results_display_wiring import register_results_save_button_handlers as _register

return _register(*args, **kwargs)


def register_generation_service_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register generation service handlers via lazy import."""
from .generation_service_wiring import register_generation_service_handlers as _register

return _register(*args, **kwargs)


def register_training_dataset_builder_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register training dataset builder handlers via lazy import."""
from .training_dataset_builder_wiring import register_training_dataset_builder_handlers as _register

return _register(*args, **kwargs)


def register_training_dataset_load_handler(*args: Any, **kwargs: Any) -> Any:
"""Register training dataset load handlers via lazy import."""
from .training_dataset_preprocess_wiring import register_training_dataset_load_handler as _register

return _register(*args, **kwargs)


def register_training_preprocess_handler(*args: Any, **kwargs: Any) -> Any:
"""Register training preprocess handlers via lazy import."""
from .training_dataset_preprocess_wiring import register_training_preprocess_handler as _register

return _register(*args, **kwargs)


def register_training_run_handlers(*args: Any, **kwargs: Any) -> Any:
"""Register training run handlers via lazy import."""
from .training_run_wiring import register_training_run_handlers as _register

return _register(*args, **kwargs)


__all__ = [
"GenerationWiringContext",
Expand Down
17 changes: 17 additions & 0 deletions acestep/ui/gradio/gradio_package_init_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Tests for lazy-import behavior in the Gradio package facade."""

import importlib
import unittest


class GradioPackageInitTests(unittest.TestCase):
"""Verify `acestep.ui.gradio` imports without requiring Gradio at import time."""

def test_package_import_exposes_interface_factory_without_gradio_dependency(self):
"""Importing package should succeed and expose the create facade callable."""
module = importlib.import_module("acestep.ui.gradio")
self.assertTrue(callable(module.create_gradio_interface))
Comment on lines +10 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Test does not enforce the "without Gradio" invariant it claims to verify.

importlib.import_module here runs in an environment where Gradio is installed, so the test passes even if __init__.py eagerly imports Gradio. If the lazy-import pattern were reverted, nothing would break this test. The method name and docstring assert a property that is never actually tested.

To enforce the contract, block the gradio import via sys.modules before re-importing the module under test.

🛡️ Proposed fix
 import importlib
+import sys
 import unittest
+from unittest.mock import patch


 class GradioPackageInitTests(unittest.TestCase):
     """Verify `acestep.ui.gradio` imports without requiring Gradio at import time."""

     def test_package_import_exposes_interface_factory_without_gradio_dependency(self):
-        """Importing package should succeed and expose the create facade callable."""
-        module = importlib.import_module("acestep.ui.gradio")
-        self.assertTrue(callable(module.create_gradio_interface))
+        """Package import succeeds and exposes a callable facade even when Gradio is absent."""
+        # Evict the cached module so the import actually re-executes.
+        sys.modules.pop("acestep.ui.gradio", None)
+        # Setting the key to None makes `import gradio` raise ImportError,
+        # simulating an environment without Gradio installed.
+        with patch.dict(sys.modules, {"gradio": None}):
+            module = importlib.import_module("acestep.ui.gradio")
+            self.assertTrue(callable(module.create_gradio_interface))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_package_import_exposes_interface_factory_without_gradio_dependency(self):
"""Importing package should succeed and expose the create facade callable."""
module = importlib.import_module("acestep.ui.gradio")
self.assertTrue(callable(module.create_gradio_interface))
import importlib
import sys
import unittest
from unittest.mock import patch
class GradioPackageInitTests(unittest.TestCase):
"""Verify `acestep.ui.gradio` imports without requiring Gradio at import time."""
def test_package_import_exposes_interface_factory_without_gradio_dependency(self):
"""Package import succeeds and exposes a callable facade even when Gradio is absent."""
# Evict the cached module so the import actually re-executes.
sys.modules.pop("acestep.ui.gradio", None)
# Setting the key to None makes `import gradio` raise ImportError,
# simulating an environment without Gradio installed.
with patch.dict(sys.modules, {"gradio": None}):
module = importlib.import_module("acestep.ui.gradio")
self.assertTrue(callable(module.create_gradio_interface))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@acestep/ui/gradio/gradio_package_init_test.py` around lines 10 - 13, The test
test_package_import_exposes_interface_factory_without_gradio_dependency
currently imports the real package so it never verifies the "without Gradio"
invariant; update the test to simulate Gradio being absent by inserting a
sentinel into sys.modules for the name "gradio" (or otherwise preventing import)
before importing or reloading the target module "acestep.ui.gradio", then
importlib.import_module("acestep.ui.gradio") and assert that
callable(module.create_gradio_interface) still holds; finally, restore or remove
the sys.modules entry so other tests aren’t affected. Ensure these steps
reference the module "acestep.ui.gradio" and the attribute
create_gradio_interface in the test.



if __name__ == "__main__":
unittest.main()