Skip to content

Commit

Permalink
fix flask server
Browse files Browse the repository at this point in the history
Also adds tests for multiview (i.e. query params in socket handler)
for all implementations
  • Loading branch information
rmorshea committed Jan 27, 2021
1 parent 55a073f commit 0c78acf
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
27 changes: 22 additions & 5 deletions idom/server/flask.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import json
import asyncio
import logging
from urllib.parse import urljoin
from asyncio import Queue as AsyncQueue
from threading import Event as ThreadEvent, Thread
from queue import Queue as ThreadQueue
from urllib.parse import parse_qs as parse_query_string
from typing import Union, Tuple, Dict, Any, Optional, Callable, NamedTuple, Type, cast

from typing_extensions import TypedDict
from flask import Flask, Blueprint, send_from_directory, redirect, url_for
from flask import Flask, Blueprint, send_from_directory, redirect, url_for, request
from flask_cors import CORS
from flask_sockets import Sockets
from geventwebsocket.websocket import WebSocket
Expand Down Expand Up @@ -77,7 +77,7 @@ def _setup_application(self, config: Config, app: Flask) -> None:

sockets = Sockets(app)

@sockets.route(urljoin(config["url_prefix"], "/stream")) # type: ignore
@sockets.route(_join_url_paths(config["url_prefix"], "/stream")) # type: ignore
def model_stream(ws: WebSocket) -> None:
def send(value: Any) -> None:
ws.send(json.dumps(value))
Expand All @@ -89,9 +89,14 @@ def recv() -> Optional[LayoutEvent]:
else:
return None

query_params = {
k: v if len(v) > 1 else v[0]
for k, v in parse_query_string(ws.environ["QUERY_STRING"]).items()
}

run_dispatcher_in_thread(
lambda: self._dispatcher_type(
Layout(self._root_component_constructor())
Layout(self._root_component_constructor(**query_params))
),
send,
recv,
Expand All @@ -109,7 +114,13 @@ def send_build_dir(path: str) -> Any:

@blueprint.route("/")
def redirect_to_index() -> Any:
return redirect(url_for("idom.send_build_dir", path="index.html"))
return redirect(
url_for(
"idom.send_build_dir",
path="index.html",
**request.args,
)
)

def _setup_application_did_start_event(
self, config: Config, app: Flask, event: ThreadEvent
Expand Down Expand Up @@ -261,3 +272,9 @@ def update_environ(self) -> None:
super().update_environ()
# BUG: for some reason coverage doesn't seem to think this line is covered
self._before_first_request_callback() # pragma: no cover


def _join_url_paths(*args: str) -> str:
# urllib.parse.urljoin performs more logic than is needed. Thus we need a util func
# to join paths as if they were POSIX paths.
return "/".join(map(lambda x: str(x).rstrip("/"), filter(None, args)))
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import pytest

import idom
from idom.server.utils import find_builtin_server_type
from idom.server.prefab import multiview_server
from idom.testing import ServerMountPoint
from idom.server import (
flask as idom_flask,
sanic as idom_sanic,
tornado as idom_tornado,
)


from tests.driver_utils import no_such_element


@pytest.fixture
def server_mount_point():
@pytest.fixture(
params=[
# add new PerClientStateServer implementations here to
# run a suite of tests which check basic functionality
idom_sanic.PerClientStateServer,
idom_flask.PerClientStateServer,
idom_tornado.PerClientStateServer,
],
ids=lambda cls: f"{cls.__module__}.{cls.__name__}",
)
def server_mount_point(request):
with ServerMountPoint(
find_builtin_server_type("PerClientStateServer"),
request.param,
mount_and_server_constructor=multiview_server,
) as mount_point:
yield mount_point
Expand Down

0 comments on commit 0c78acf

Please sign in to comment.