Skip to content

Commit e079951

Browse files
committed
fix docs after import source changes
1 parent ea19a07 commit e079951

File tree

10 files changed

+113
-33
lines changed

10 files changed

+113
-33
lines changed

docs/main.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@
55
from sanic import Sanic, response
66

77
import idom
8+
from idom.config import IDOM_CLIENT_IMPORT_SOURCE_URL
89
from idom.server.sanic import PerClientStateServer
910
from idom.widgets.utils import multiview
1011

1112

13+
IDOM_MODEL_SERVER_URL_PREFIX = "/_idom"
14+
15+
IDOM_CLIENT_IMPORT_SOURCE_URL.set_default(
16+
# set_default because scripts/live_docs.py needs to overwrite this
17+
f"{IDOM_MODEL_SERVER_URL_PREFIX}{IDOM_CLIENT_IMPORT_SOURCE_URL.default}"
18+
)
19+
20+
1221
here = Path(__file__).parent
1322

1423
app = Sanic(__name__)
@@ -52,7 +61,11 @@ async def forward_to_index(request):
5261

5362

5463
PerClientStateServer(
55-
component, {"redirect_root_to_index": False, "url_prefix": "/_idom"}
64+
component,
65+
{
66+
"redirect_root_to_index": False,
67+
"url_prefix": IDOM_MODEL_SERVER_URL_PREFIX,
68+
},
5669
).register(app)
5770

5871

docs/source/_exts/interactive_widget.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
from sphinx.application import Sphinx
66

77

8-
_IDOM_SERVER_LOC = os.environ.get("IDOM_DOC_EXAMPLE_SERVER_HOST", "")
8+
_IDOM_EXAMPLE_HOST = os.environ.get("IDOM_DOC_EXAMPLE_SERVER_HOST", "")
9+
_IDOM_EXAMPLE_PATH = os.environ.get("IDOM_DOC_EXAMPLE_SERVER_PATH", "/_idom")
10+
_IDOM_STATIC_HOST = os.environ.get("IDOM_DOC_STATIC_SERVER_HOST", "/docs").rstrip("/")
911

1012

1113
class IteractiveWidget(Directive):
@@ -25,8 +27,8 @@ def run(self):
2527
<div>
2628
<div id="{container_id}" class="interactive widget-container center-content" style="" />
2729
<script async type="module">
28-
import loadWidgetExample from "/docs/_static/js/load-widget-example.js";
29-
loadWidgetExample("{_IDOM_SERVER_LOC}", "/_idom", "{container_id}", "{view_id}");
30+
import loadWidgetExample from "{_IDOM_STATIC_HOST}/_static/js/load-widget-example.js";
31+
loadWidgetExample("{_IDOM_EXAMPLE_HOST}", "{_IDOM_EXAMPLE_PATH}", "{container_id}", "{view_id}");
3032
</script>
3133
</div>
3234
""",

docs/source/examples/matplotlib_plot.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def set_value_at_index(event, index=i):
2828
new_value = float(event["value"] or 0)
2929
set_values(values[:index] + [new_value] + values[index + 1 :])
3030

31-
inputs.append(poly_coef_input(i, set_value_at_index))
31+
inputs.append(poly_coef_input(i + 1, set_value_at_index))
3232

3333
def add_input():
3434
set_values(values + [0])
@@ -75,7 +75,7 @@ def poly_coef_input(index, callback):
7575

7676

7777
def polynomial(x, coefficients):
78-
return sum(c * (x ** i) for i, c in enumerate(coefficients))
78+
return sum(c * (x ** (i + 1)) for i, c in enumerate(coefficients))
7979

8080

8181
def linspace(start, stop, n):

docs/source/examples/simple_dashboard.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,15 @@ async def animate():
5353
}
5454
set_data(data[1:] + [next_data_point])
5555

56-
return victory.VictoryLine({"data": data, "style": {"parent": {"width": "500px"}}})
56+
return victory.VictoryLine(
57+
{
58+
"data": data,
59+
"style": {
60+
"parent": {"width": "500px"},
61+
"data": {"stroke": "#c43a31"},
62+
},
63+
}
64+
)
5765

5866

5967
@idom.component

docs/source/examples/victory_chart.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,5 @@
22

33

44
victory = idom.install("victory", fallback="loading...")
5-
6-
idom.run(
7-
idom.component(
8-
lambda: victory.VictoryBar({"style": {"parent": {"width": "500px"}}}),
9-
)
10-
)
5+
bar_style = {"parent": {"width": "500px"}, "data": {"fill": "#c43a31"}}
6+
idom.run(idom.component(lambda: victory.VictoryBar({"style": bar_style})))

docs/source/package-api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Flask Servers
5454

5555

5656
FastAPI Servers
57-
-------------
57+
---------------
5858

5959
.. automodule:: idom.server.fastapi
6060
:members:

noxfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def docs(session: Session) -> None:
6464
"html",
6565
"docs/source",
6666
"docs/build",
67-
env={"PYTHONPATH": os.getcwd()},
67+
env={"PYTHONPATH": os.getcwd(), "IDOM_DEBUG_MODE": "1"},
6868
)
6969

7070

scripts/live_docs.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@
1010
get_parser,
1111
)
1212

13+
from idom.config import IDOM_CLIENT_IMPORT_SOURCE_URL
1314
from idom.server.sanic import PerClientStateServer
1415

1516

16-
os.environ["IDOM_DOC_EXAMPLE_SERVER_HOST"] = "127.0.0.1:5555"
17+
# these environment variable are used in custom Sphinx extensions
18+
os.environ["IDOM_DOC_EXAMPLE_SERVER_HOST"] = example_server_host = "127.0.0.1:5555"
19+
os.environ["IDOM_DOC_EXAMPLE_SERVER_PATH"] = ""
20+
os.environ["IDOM_DOC_STATIC_SERVER_HOST"] = ""
21+
1722
_running_idom_servers = []
1823

1924

@@ -22,13 +27,16 @@ def wrap_builder(old_builder):
2227
def new_builder():
2328
[s.stop() for s in _running_idom_servers]
2429

30+
# we need to set this before `docs.main` does
31+
IDOM_CLIENT_IMPORT_SOURCE_URL.set(
32+
f"http://{example_server_host}{IDOM_CLIENT_IMPORT_SOURCE_URL.default}"
33+
)
34+
2535
from docs import main
2636

2737
importlib.reload(main)
2838

29-
server = PerClientStateServer(
30-
main.component, {"cors": True, "url_prefix": "_idom"}
31-
)
39+
server = PerClientStateServer(main.component, {"cors": True})
3240
_running_idom_servers.append(server)
3341
server.daemon("127.0.0.1", 5555, debug=True)
3442
old_builder()

src/idom/_option.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from __future__ import annotations
22

33
import os
4+
from logging import getLogger
45
from typing import Any, Callable, Generic, TypeVar, cast
56

67

78
_O = TypeVar("_O")
9+
logger = getLogger(__name__)
810

911

1012
class Option(Generic[_O]):
@@ -17,11 +19,18 @@ def __init__(
1719
mutable: bool = True,
1820
validator: Callable[[Any], _O] = lambda x: cast(_O, x),
1921
) -> None:
20-
self.name = name
22+
self._name = name
2123
self._default = default
2224
self._mutable = mutable
2325
self._validator = validator
24-
self._value = validator(os.environ.get(name, default))
26+
if name in os.environ:
27+
self._value = validator(os.environ[name])
28+
logger.debug(f"{self._name}={self.get()}")
29+
30+
@property
31+
def name(self) -> str:
32+
"""The name of this option (used to load environment variables)"""
33+
return self._name
2534

2635
@property
2736
def mutable(self) -> bool:
@@ -33,24 +42,48 @@ def default(self) -> _O:
3342
"""This option's default value"""
3443
return self._default
3544

45+
def is_set(self) -> bool:
46+
"""Whether this option has a value other than its default."""
47+
return hasattr(self, "_value")
48+
3649
def get(self) -> _O:
3750
"""Get the current value of this option."""
38-
return self._value
51+
return getattr(self, "_value", self._default)
3952

40-
def set(self, new: _O) -> _O:
41-
"""Set the value of this configuration option
53+
def set(self, new: _O) -> None:
54+
"""Set the value of this option
4255
4356
Raises a ``TypeError`` if this option is not :attr:`Option.mutable`.
4457
"""
4558
if not self._mutable:
4659
raise TypeError(f"{self} cannot be modified after initial load")
47-
old = self._value
4860
self._value = self._validator(new)
49-
return old
61+
logger.debug(f"{self._name}={self._value}")
62+
63+
def set_default(self, new: _O) -> _O:
64+
"""Set the value of this option if :meth:`Option.is_default`
65+
66+
Returns the current value (a la :meth:`dict.set_default`)
67+
"""
68+
if not hasattr(self, "_value"):
69+
self.set(new)
70+
return self._value
5071

51-
def reset(self) -> _O:
52-
"""Reset the value of this option to its default setting"""
53-
return self.set(self._default)
72+
def reload(self) -> None:
73+
"""Reload this option from its environment variable
74+
75+
Returns the old value of the option.
76+
"""
77+
self.set(os.environ.get(self._name, self._default))
78+
79+
def reset(self) -> None:
80+
"""Reset the value of this option to its default setting
81+
82+
Returns the old value of the option.
83+
"""
84+
if not self._mutable:
85+
raise TypeError(f"{self} cannot be modified after initial load")
86+
delattr(self, "_value")
5487

5588
def __repr__(self) -> str:
56-
return f"Option({self.name}={self._value!r})"
89+
return f"Option({self._name}={self.get()!r})"

tests/test__option.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
def test_option_repr():
1010
opt = Option("A_FAKE_OPTION", "some-value")
11+
assert opt.name == "A_FAKE_OPTION"
1112
assert repr(opt) == "Option(A_FAKE_OPTION='some-value')"
1213

1314

@@ -41,16 +42,35 @@ def test_immutable_option():
4142
assert not opt.mutable
4243
with pytest.raises(TypeError, match="cannot be modified after initial load"):
4344
opt.set("a-new-value")
45+
with pytest.raises(TypeError, match="cannot be modified after initial load"):
46+
opt.reset()
4447

4548

4649
def test_option_reset():
4750
opt = Option("A_FAKE_OPTION", "default-value")
4851
opt.set("a-new-value")
49-
assert opt.get() == "a-new-value"
5052
opt.reset()
5153
assert opt.get() is opt.default
54+
assert not opt.is_set()
55+
56+
57+
@mock.patch.dict(os.environ, {"A_FAKE_OPTION": "value-from-environ"})
58+
def test_option_reload():
59+
opt = Option("A_FAKE_OPTION", "default-value")
60+
opt.set("some-other-value")
61+
opt.reload()
62+
assert opt.get() == "value-from-environ"
63+
64+
65+
def test_option_set():
66+
opt = Option("A_FAKE_OPTION", "default-value")
67+
assert not opt.is_set()
68+
opt.set("a-new-value")
69+
assert opt.is_set()
5270

5371

54-
def test_option_set_returns_last_value():
72+
def test_option_set_default():
5573
opt = Option("A_FAKE_OPTION", "default-value")
56-
assert opt.set("a-new-value") == "default-value"
74+
assert not opt.is_set()
75+
assert opt.set_default("new-value") == "new-value"
76+
assert opt.is_set()

0 commit comments

Comments
 (0)