Skip to content

Commit e43bcc0

Browse files
authored
Implement use_location (#721)
* experiment with bundling * get starlette and tornado to work * get sanic and flask to work still need to rework how modules are accessed * refine routing + fix bugs * fix cov * add use_request back * remove unused imports * fix test, not sure why it broke * handle unsafe user provided paths * increase default testing timeout * ignore untyped func * rework as location object * fix tornado * upgrade snowpack * always poll async if we poll sync then the server might not ever get a hold of the event loop. this was causing a problem for the sanic server in a test * test traversal_safe_path * add comment about catch * remove unused imports * symlinks are ok in traversal_safe_path * fix docs * refine docstring
1 parent 1d4d942 commit e43bcc0

39 files changed

+5449
-658
lines changed

docs/app.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from idom.core.types import ComponentConstructor
99
from idom.server.sanic import Options, configure, use_request
1010

11-
from .examples import load_examples
11+
from .examples import get_normalized_example_name, load_examples
1212

1313

1414
HERE = Path(__file__).parent
@@ -26,10 +26,7 @@ def run():
2626
configure(
2727
app,
2828
Example(),
29-
Options(
30-
redirect_root=False,
31-
url_prefix=IDOM_MODEL_SERVER_URL_PREFIX,
32-
),
29+
Options(url_prefix=IDOM_MODEL_SERVER_URL_PREFIX),
3330
)
3431

3532
app.run(
@@ -42,7 +39,8 @@ def run():
4239

4340
@component
4441
def Example():
45-
view_id = use_request().get_args().get("view_id")
42+
raw_view_id = use_request().get_args().get("view_id")
43+
view_id = get_normalized_example_name(raw_view_id)
4644
return _get_examples()[view_id]()
4745

4846

docs/examples.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def _get_root_example_path_by_name(name: str, relative_to: str | Path | None) ->
133133
rel_path = rel_path.parent if rel_path.is_file() else rel_path
134134
else:
135135
rel_path = SOURCE_DIR
136-
return rel_path.joinpath(*name.split("/"))
136+
return rel_path.joinpath(*name.split("/")).resolve()
137137

138138

139139
class _PrintBuffer:

docs/source/about/changelog.rst

+28-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,34 @@ more info, see the :ref:`Contributor Guide <Creating a Changelog Entry>`.
2323
Unreleased
2424
----------
2525

26-
Nothing yet...
26+
Added:
27+
28+
- Implement ``use_location()`` hook - :pull:`721`
29+
30+
Navigating to any route below the root of the application will be reflected in the
31+
``location.pathname``. This operates in concert with how IDOM's configured routes have
32+
changed. This will ultimately work towards resolving :issue:`569`.
33+
34+
Changed:
35+
36+
- The routes IDOM configures on apps have changed - :pull:`721`
37+
38+
.. code-block:: text
39+
40+
prefix/_api/modules/* web modules
41+
prefix/_api/stream websocket endpoint
42+
prefix/* client react app
43+
44+
This means that IDOM's client app is available at any route below the configured
45+
``url_prefix`` besides ``prefix/_api``. The ``_api`` route will likely remain a route
46+
which is reserved by IDOM. The route navigated to below the ``prefix`` will be shown
47+
in ``use_location``.
48+
49+
- IDOM's client now uses Preact instead of React - :pull:`721`
50+
51+
Removed:
52+
53+
- ``redirect_root`` server option - :pull:`721`
2754

2855

2956
0.38.0-a1

docs/source/guides/getting-started/_static/embed-idom-view/index.html

+12-23
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,20 @@ <h1>This is an Example App</h1>
99
<p>Just below is an embedded IDOM view...</p>
1010
<div id="idom-app" />
1111
<script type="module">
12-
import { mountLayoutWithWebSocket } from "https://esm.sh/[email protected]";
12+
import {
13+
mountWithLayoutServer,
14+
LayoutServerInfo,
15+
} from "https://esm.sh/[email protected]";
1316

14-
// get the correct web socket protocol
15-
let wsURL;
16-
if (window.location.protocol === "https:") {
17-
wsURL = "wss:";
18-
} else {
19-
wsURL = "ws:";
20-
}
21-
wsURL += "//" + window.location.host;
17+
const serverInfo = new LayoutServerInfo({
18+
host: document.location.hostname,
19+
port: document.location.port,
20+
path: "_idom",
21+
query: queryParams.user.toString(),
22+
secure: document.location.protocol == "https:",
23+
});
2224

23-
// append path to the web socket
24-
wsURL += "/_idom/stream";
25-
26-
// only needed for views that use web modules
27-
const loadImportSource = (source, sourceType) =>
28-
sourceType == "NAME"
29-
? import("_idom/_modules/" + source)
30-
: import(source);
31-
32-
mountLayoutWithWebSocket(
33-
document.getElementById("idom-app"),
34-
wsURL,
35-
loadImportSource
36-
);
25+
mountLayoutWithWebSocket(document.getElementById("idom-app"), serverInfo);
3726
</script>
3827
</body>
3928
</html>

docs/source/guides/getting-started/running-idom.rst

+4-8
Original file line numberDiff line numberDiff line change
@@ -147,19 +147,15 @@ Server Configuration Options
147147
----------------------------
148148

149149
IDOM's various server implementations come with ``Options`` that can be passed to their
150-
respective ``configure()`` functions. Those which are common amongst the options are:
151-
152-
- ``url_prefix`` - prefix all routes configured by IDOM
153-
- ``redirect_root`` - whether to redirect the root of the application to the IDOM view
154-
- ``serve_static_files`` - whether to server IDOM's static files from it's default route
155-
156-
You'd then pass these options to ``configure()`` in the following way:
150+
respective ``configure()`` functions in the following way:
157151

158152
.. code-block::
159153
154+
from idom.server.<implementation> import configure, Options
155+
160156
configure(app, MyComponent, Options(...))
161157
162-
To learn more read the description for your chosen server implementation:
158+
To learn more read about the options for your chosen server ``<implementation>``:
163159

164160
- :class:`idom.server.fastapi.Options`
165161
- :class:`idom.server.flask.Options`

noxfile.py

+3
Original file line numberDiff line numberDiff line change
@@ -390,5 +390,8 @@ def get_idom_script_env() -> dict[str, str]:
390390
return {
391391
"PYTHONPATH": os.getcwd(),
392392
"IDOM_DEBUG_MODE": os.environ.get("IDOM_DEBUG_MODE", "1"),
393+
"IDOM_TESTING_DEFAULT_TIMEOUT": os.environ.get(
394+
"IDOM_TESTING_DEFAULT_TIMEOUT", "6.0"
395+
),
393396
"IDOM_CHECK_VDOM_SPEC": os.environ.get("IDOM_CHECK_VDOM_SPEC", "0"),
394397
}

requirements/pkg-deps.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
typing-extensions >=3.10
22
mypy-extensions >=0.4.3
3-
anyio >=3.0
3+
anyio >=3
44
jsonpatch >=1.32
55
fastjsonschema >=2.14.5
6-
requests >=2.0
6+
requests >=2
77
colorlog >=6

requirements/pkg-extras.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ fastapi >=0.63.0
1111
uvicorn[standard] >=0.13.4
1212

1313
# extra=flask
14-
flask<2.0
14+
flask
1515
markupsafe<2.1
1616
flask-cors
17-
flask-sockets
17+
flask-sock
1818

1919
# extra=tornado
2020
tornado

0 commit comments

Comments
 (0)