Skip to content

Commit f2c1070

Browse files
authored
Rework How IDOM Integrates With Servers (#703)
* initial work to move away from run func * initial work converting to new server interface * finish up flask conversion * convert tornado + begin reworking test utils * remove shared dispatchers and rename to serve module * misc fixes * start to switch test suite to playwright * get basic tests working * get some tests working * slight optimization * misc minor improvements * fix test_html * implement test_module * implement connection context * fix playwright install in nox * add minimal docstrings * remove pytest-playwright * get suite to run (with failures) * fix log assertion problems * misc fixes in order to get reconnect test to work * expose use_scope instead of use_connection * fix test common * fix test_client * test use_scope * remove unused imports * fix live docs * fix typing issues * fix rest of tests * improve coverage * import protocol from typing extensions * fix syntax error * fix docs test * fix flake8 * test run function * use selector event loop * try to fix loop * only install chromium * remove unused import * fix shutdown code * skip browser tests on windows * fix coverage + reorg testing utils * minor logging changes * fix live docs script * fix log message * fix types * documentation updates * use dataclasses for options instead of typeddict * move section * add note to changelog * fix missing refs * fix ref * fix fastapi alias * fix tornado redirect * remove unused imports * changelog entry * fix noxfile tag commit msg * improve changelog entry * fix typo in old cl entry
1 parent ad49f29 commit f2c1070

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+2295
-2758
lines changed

.github/workflows/test.yml

+2-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- uses: actions/checkout@v2
18-
- uses: nanasess/setup-chromedriver@master
1918
- uses: actions/setup-node@v2
2019
with:
2120
node-version: "14.x"
@@ -29,7 +28,7 @@ jobs:
2928
run: pip install -r requirements/nox-deps.txt
3029
- name: Run Tests
3130
env: { "CI": "true" }
32-
run: nox -s test_python_suite -- --headless --maxfail=3
31+
run: nox -s test_python_suite -- --maxfail=3
3332
test-python-environments:
3433
runs-on: ${{ matrix.os }}
3534
strategy:
@@ -38,7 +37,6 @@ jobs:
3837
os: [ubuntu-latest, macos-latest, windows-latest]
3938
steps:
4039
- uses: actions/checkout@v2
41-
- uses: nanasess/setup-chromedriver@master
4240
- uses: actions/setup-node@v2
4341
with:
4442
node-version: "14.x"
@@ -52,7 +50,7 @@ jobs:
5250
run: pip install -r requirements/nox-deps.txt
5351
- name: Run Tests
5452
env: { "CI": "true" }
55-
run: nox -s test_python --stop-on-first-error -- --headless --maxfail=3 --no-cov
53+
run: nox -s test_python --stop-on-first-error -- --maxfail=3 --no-cov
5654
test-docs:
5755
runs-on: ubuntu-latest
5856
steps:

docs/app.py

+30-18
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
from sanic import Sanic, response
66

7-
from idom.server.sanic import PerClientStateServer
8-
from idom.widgets import multiview
7+
from idom import component
8+
from idom.core.types import ComponentConstructor
9+
from idom.server.sanic import Options, configure, use_request
910

1011
from .examples import load_examples
1112

@@ -22,13 +23,13 @@
2223
def run():
2324
app = make_app()
2425

25-
PerClientStateServer(
26-
make_examples_component(),
27-
{
28-
"redirect_root_to_index": False,
29-
"url_prefix": IDOM_MODEL_SERVER_URL_PREFIX,
30-
},
26+
configure(
3127
app,
28+
Example(),
29+
Options(
30+
redirect_root=False,
31+
url_prefix=IDOM_MODEL_SERVER_URL_PREFIX,
32+
),
3233
)
3334

3435
app.run(
@@ -39,8 +40,28 @@ def run():
3940
)
4041

4142

43+
@component
44+
def Example():
45+
view_id = use_request().get_args().get("view_id")
46+
return _get_examples()[view_id]()
47+
48+
49+
def _get_examples():
50+
if not _EXAMPLES:
51+
_EXAMPLES.update(load_examples())
52+
return _EXAMPLES
53+
54+
55+
def reload_examples():
56+
_EXAMPLES.clear()
57+
_EXAMPLES.update(load_examples())
58+
59+
60+
_EXAMPLES: dict[str, ComponentConstructor] = {}
61+
62+
4263
def make_app():
43-
app = Sanic(__name__)
64+
app = Sanic("docs_app")
4465

4566
app.static("/docs", str(HERE / "build"))
4667

@@ -49,12 +70,3 @@ async def forward_to_index(request):
4970
return response.redirect("/docs/index.html")
5071

5172
return app
52-
53-
54-
def make_examples_component():
55-
mount, component = multiview()
56-
57-
for example_name, example_component in load_examples():
58-
mount.add(example_name, example_component)
59-
60-
return component

docs/examples.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def load_examples() -> Iterator[tuple[str, Callable[[], ComponentType]]]:
2323
def all_example_names() -> set[str]:
2424
names = set()
2525
for file in _iter_example_files(SOURCE_DIR):
26-
path = file.parent if file.name == "app.py" else file
26+
path = file.parent if file.name == "main.py" else file
2727
names.add("/".join(path.relative_to(SOURCE_DIR).with_suffix("").parts))
2828
return names
2929

@@ -48,7 +48,7 @@ def get_main_example_file_by_name(
4848
) -> Path:
4949
path = _get_root_example_path_by_name(name, relative_to)
5050
if path.is_dir():
51-
return path / "app.py"
51+
return path / "main.py"
5252
else:
5353
return path.with_suffix(".py")
5454

docs/source/_exts/idom_example.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def run(self):
5151
if len(ex_files) == 1:
5252
labeled_tab_items.append(
5353
(
54-
"app.py",
54+
"main.py",
5555
_literal_include(
5656
path=ex_files[0],
5757
linenos=show_linenos,

docs/source/about/changelog.rst

+32-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,41 @@ Changelog
1111
All notable changes to this project will be recorded in this document. The style of
1212
which is based on `Keep a Changelog <https://keepachangelog.com/>`__. The versioning
1313
scheme for the project adheres to `Semantic Versioning <https://semver.org/>`__. For
14-
more info, see the :ref:`Contributor Guide <Create a Changelog Entry>`.
14+
more info, see the :ref:`Contributor Guide <Creating a Changelog Entry>`.
1515

1616

17+
.. INSTRUCTIONS FOR CHANGELOG CONTRIBUTORS
18+
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
19+
.. If you're adding a changelog entry, be sure to read the "Creating a Changelog Entry"
20+
.. section of the documentation before doing so for instructions on how to adhere to the
21+
.. "Keep a Changelog" style guide (https://keepachangelog.com).
22+
1723
Unreleased
1824
----------
1925

20-
Nothing yet...
26+
Changed:
27+
28+
- How IDOM integrates with servers - :pull:`703`
29+
30+
- ``idom.run`` no longer accepts an app instance to discourage use outside of testing
31+
- IDOM's server implementations now provide ``configure()`` functions instead
32+
- ``idom.testing`` has been completely reworked in order to support async web drivers
33+
34+
Added:
35+
36+
- Access to underlying server requests via contexts - :issue:`669`
37+
38+
Removed:
39+
40+
- ``idom.widgets.multiview`` since basic routing view ``use_scope`` is now possible
41+
- All ``SharedClientStateServer`` implementations.
42+
- All ``PerClientStateServer`` implementations have been replaced with ``configure()``
43+
44+
Fixed:
45+
46+
- IDOM's test suite no longer uses sync web drivers - :issue:`591`
47+
- Updated Sanic requirement to ``>=21`` - :issue:`678`
48+
- How we advertise ``idom.run`` - :issue:`657`
2149

2250

2351
0.37.2
@@ -30,7 +58,8 @@ Changed:
3058

3159
Fixed:
3260

33-
- A typo caused IDOM to use the insecure `ws` web-socket protocol on pages loaded with `https` instead of the secure `wss` protocol - :pull:`716`
61+
- A typo caused IDOM to use the insecure ``ws`` web-socket protocol on pages loaded with
62+
``https`` instead of the secure ``wss`` protocol - :pull:`716`
3463

3564

3665
0.37.1

docs/source/about/contributor-guide.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ about how to get started. To make a change to IDOM you'll do the following:
6666
:ref:`equality checks <Code Quality Checks>` and, with any luck, accept your request.
6767
At that point your contribution will be merged into the main codebase!
6868

69-
Create a Changelog Entry
70-
........................
69+
Creating a Changelog Entry
70+
..........................
7171

7272
As part of your pull request, you'll want to edit the `Changelog
7373
<https://github.com/idom-team/idom/blob/main/docs/source/about/changelog.rst>`__ by

docs/source/guides/adding-interactivity/components-with-state/index.rst

+9-9
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ below highlights a line of code where something of interest occurs:
151151

152152
<h2>Initial render</h2>
153153

154-
.. literalinclude:: _examples/adding_state_variable/app.py
154+
.. literalinclude:: _examples/adding_state_variable/main.py
155155
:lines: 12-33
156156
:emphasize-lines: 2
157157

@@ -165,7 +165,7 @@ below highlights a line of code where something of interest occurs:
165165

166166
<h2>Initial state declaration</h2>
167167

168-
.. literalinclude:: _examples/adding_state_variable/app.py
168+
.. literalinclude:: _examples/adding_state_variable/main.py
169169
:lines: 12-33
170170
:emphasize-lines: 3
171171

@@ -181,7 +181,7 @@ below highlights a line of code where something of interest occurs:
181181

182182
<h2>Define event handler</h2>
183183

184-
.. literalinclude:: _examples/adding_state_variable/app.py
184+
.. literalinclude:: _examples/adding_state_variable/main.py
185185
:lines: 12-33
186186
:emphasize-lines: 5
187187

@@ -196,7 +196,7 @@ below highlights a line of code where something of interest occurs:
196196

197197
<h2>Return the view</h2>
198198

199-
.. literalinclude:: _examples/adding_state_variable/app.py
199+
.. literalinclude:: _examples/adding_state_variable/main.py
200200
:lines: 12-33
201201
:emphasize-lines: 16
202202

@@ -212,7 +212,7 @@ below highlights a line of code where something of interest occurs:
212212

213213
<h2>User interaction</h2>
214214

215-
.. literalinclude:: _examples/adding_state_variable/app.py
215+
.. literalinclude:: _examples/adding_state_variable/main.py
216216
:lines: 12-33
217217
:emphasize-lines: 5
218218

@@ -226,7 +226,7 @@ below highlights a line of code where something of interest occurs:
226226

227227
<h2>New state is set</h2>
228228

229-
.. literalinclude:: _examples/adding_state_variable/app.py
229+
.. literalinclude:: _examples/adding_state_variable/main.py
230230
:lines: 12-33
231231
:emphasize-lines: 6
232232

@@ -242,7 +242,7 @@ below highlights a line of code where something of interest occurs:
242242

243243
<h2>Next render begins</h2>
244244

245-
.. literalinclude:: _examples/adding_state_variable/app.py
245+
.. literalinclude:: _examples/adding_state_variable/main.py
246246
:lines: 12-33
247247
:emphasize-lines: 2
248248

@@ -256,7 +256,7 @@ below highlights a line of code where something of interest occurs:
256256

257257
<h2>Next state is acquired</h2>
258258

259-
.. literalinclude:: _examples/adding_state_variable/app.py
259+
.. literalinclude:: _examples/adding_state_variable/main.py
260260
:lines: 12-33
261261
:emphasize-lines: 3
262262

@@ -272,7 +272,7 @@ below highlights a line of code where something of interest occurs:
272272

273273
<h2>Repeat...</h2>
274274

275-
.. literalinclude:: _examples/adding_state_variable/app.py
275+
.. literalinclude:: _examples/adding_state_variable/main.py
276276
:lines: 12-33
277277

278278
From this point on, the steps remain the same. The only difference being the

docs/source/guides/getting-started/_examples/hello_world.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
@component
55
def App():
6-
return html.h1("Hello, World!")
6+
return html.h1("Hello, world!")
77

88

99
run(App)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# :lines: 11-
2+
3+
from idom import run
4+
from idom.server import fastapi as fastapi_server
5+
6+
7+
# the run() function is the entry point for examples
8+
fastapi_server.configure = lambda _, cmpt: run(cmpt)
9+
10+
11+
from fastapi import FastAPI
12+
13+
from idom import component, html
14+
from idom.server.fastapi import configure
15+
16+
17+
@component
18+
def HelloWorld():
19+
return html.h1("Hello, world!")
20+
21+
22+
app = FastAPI()
23+
configure(app, HelloWorld)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# :lines: 11-
2+
3+
from idom import run
4+
from idom.server import flask as flask_server
5+
6+
7+
# the run() function is the entry point for examples
8+
flask_server.configure = lambda _, cmpt: run(cmpt)
9+
10+
11+
from flask import Flask
12+
13+
from idom import component, html
14+
from idom.server.flask import configure
15+
16+
17+
@component
18+
def HelloWorld():
19+
return html.h1("Hello, world!")
20+
21+
22+
app = Flask(__name__)
23+
configure(app, HelloWorld)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# :lines: 11-
2+
3+
from idom import run
4+
from idom.server import sanic as sanic_server
5+
6+
7+
# the run() function is the entry point for examples
8+
sanic_server.configure = lambda _, cmpt: run(cmpt)
9+
10+
11+
from sanic import Sanic
12+
13+
from idom import component, html
14+
from idom.server.sanic import configure
15+
16+
17+
@component
18+
def HelloWorld():
19+
return html.h1("Hello, world!")
20+
21+
22+
app = Sanic("MyApp")
23+
configure(app, HelloWorld)
24+
25+
26+
if __name__ == "__main__":
27+
app.run(port=8000)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# :lines: 11-
2+
3+
from idom import run
4+
from idom.server import starlette as starlette_server
5+
6+
7+
# the run() function is the entry point for examples
8+
starlette_server.configure = lambda _, cmpt: run(cmpt)
9+
10+
11+
from starlette.applications import Starlette
12+
13+
from idom import component, html
14+
from idom.server.starlette import configure
15+
16+
17+
@component
18+
def HelloWorld():
19+
return html.h1("Hello, world!")
20+
21+
22+
app = Starlette()
23+
configure(app, HelloWorld)

0 commit comments

Comments
 (0)