Skip to content

Commit 6fd73fd

Browse files
committed
avoid sanic import
Sanic was accidentally imported when not explicitely requested. This means `pip install idom[sanic]` is currently required. To avoid this we add a find_builtin_server_type() function to help in testing and internal utilities.
1 parent f6196f1 commit 6fd73fd

File tree

7 files changed

+44
-29
lines changed

7 files changed

+44
-29
lines changed

idom/server/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from .base import AbstractRenderServer
22
from .prefab import run, multiview_server, hotswap_server
3-
from . import default
3+
44

55
__all__ = [
66
"default",

idom/server/default.py

Lines changed: 0 additions & 4 deletions
This file was deleted.

idom/server/prefab.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
1-
from importlib import import_module
2-
from typing import Any, Dict, Optional, Tuple, Type, TypeVar, cast
1+
from typing import Any, Dict, Optional, Tuple, Type, TypeVar
32

43
from idom.core.element import ElementConstructor
54
from idom.widgets.utils import multiview, hotswap, MultiViewMount, MountFunc
65

76
from .base import AbstractRenderServer
8-
from .utils import find_available_port
7+
from .utils import find_available_port, find_builtin_server_type
98

109

1110
_S = TypeVar("_S", bound=AbstractRenderServer[Any, Any])
1211

1312

14-
def _find_default_server_type() -> Optional[Type[_S]]:
15-
for name in ["sanic.PerClientStateServer"]:
16-
module_name, server_name = name.split(".")
17-
try:
18-
module = import_module(f"idom.server.{module_name}")
19-
except ImportError: # pragma: no cover
20-
pass
21-
else:
22-
return cast(Type[_S], getattr(module, server_name))
23-
else: # pragma: no cover
24-
return None
25-
26-
2713
def run(
2814
element: ElementConstructor,
29-
server_type: Optional[Type[_S]] = _find_default_server_type(),
15+
server_type: Optional[Type[_S]] = find_builtin_server_type("PerClientStateServer"),
3016
host: str = "127.0.0.1",
3117
port: Optional[int] = None,
3218
server_config: Optional[Any] = None,

idom/server/utils.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,37 @@
11
from socket import socket
2-
from typing import cast
2+
from types import ModuleType
3+
from typing import Type, Any, List, cast
4+
from importlib import import_module
5+
6+
7+
def find_builtin_server_type(type_name: str) -> Type[Any]:
8+
"""Find first installed server implementation"""
9+
builtin_module_names = ["sanic", "flask", "tornado"]
10+
11+
installed_builtin_modules: List[ModuleType] = []
12+
for module_name in builtin_module_names:
13+
try:
14+
installed_builtin_modules.append(
15+
import_module(f"idom.server.{module_name}")
16+
)
17+
except ImportError: # pragma: no cover
18+
pass
19+
20+
if not installed_builtin_modules: # pragma: no cover
21+
raise RuntimeError(
22+
f"Found none of the following builtin server implementations {builtin_module_names}"
23+
)
24+
25+
for builtin_module in installed_builtin_modules:
26+
try:
27+
return getattr(builtin_module, type_name)
28+
except AttributeError: # pragma: no cover
29+
pass
30+
else: # pragma: no cover
31+
installed_names = [m.__name__ for m in installed_builtin_modules]
32+
raise ImportError(
33+
f"No server type {type_name!r} found in installed implementations {installed_names}"
34+
)
335

436

537
def find_available_port(host: str) -> int:

idom/testing.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from selenium.webdriver.remote.webdriver import WebDriver
1717
from selenium.webdriver import Chrome
1818

19-
from idom import server
19+
from idom.server.utils import find_builtin_server_type
2020
from idom.server.base import AbstractRenderServer
2121
from idom.server.prefab import hotswap_server
2222
from idom.server.utils import find_available_port
@@ -59,7 +59,7 @@ class ServerMountPoint(Generic[_Mount, _Server]):
5959

6060
def __init__(
6161
self,
62-
server_type: Type[_Server] = server.default.PerClientStateServer,
62+
server_type: Type[_Server] = find_builtin_server_type("PerClientStateServer"),
6363
host: str = "127.0.0.1",
6464
port: Optional[int] = None,
6565
server_config: Optional[Any] = None,

tests/test_server/test_base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import pytest
22

33
import idom
4-
from idom.server.default import PerClientStateServer
4+
from idom.server.utils import find_builtin_server_type
55

66

77
def test_no_application_until_running():
88
@idom.element
99
def AnyElement():
1010
pass
1111

12-
server = PerClientStateServer(AnyElement)
12+
server = find_builtin_server_type("PerClientStateServer")(AnyElement)
1313

1414
with pytest.raises(RuntimeError, match="No application"):
1515
server.application

tests/test_server/test_prefab.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22

33
import idom
4-
from idom.server.default import PerClientStateServer
4+
from idom.server.utils import find_builtin_server_type
55
from idom.server.prefab import multiview_server
66
from idom.testing import ServerMountPoint
77

@@ -11,7 +11,8 @@
1111
@pytest.fixture
1212
def server_mount_point():
1313
return ServerMountPoint(
14-
PerClientStateServer, mount_and_server_constructor=multiview_server
14+
find_builtin_server_type("PerClientStateServer"),
15+
mount_and_server_constructor=multiview_server,
1516
)
1617

1718

0 commit comments

Comments
 (0)