Synchronize Event Namespace (#1370)
This commit is contained in:
parent
370e1fd04c
commit
4505279d5d
@ -97,6 +97,9 @@ class App(Base):
|
|||||||
Args:
|
Args:
|
||||||
*args: Args to initialize the app with.
|
*args: Args to initialize the app with.
|
||||||
**kwargs: Kwargs to initialize the app with.
|
**kwargs: Kwargs to initialize the app with.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the event namespace is not provided in the config.
|
||||||
"""
|
"""
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@ -128,9 +131,13 @@ class App(Base):
|
|||||||
|
|
||||||
# Create the socket app. Note event endpoint constant replaces the default 'socket.io' path.
|
# Create the socket app. Note event endpoint constant replaces the default 'socket.io' path.
|
||||||
self.socket_app = ASGIApp(self.sio, socketio_path="")
|
self.socket_app = ASGIApp(self.sio, socketio_path="")
|
||||||
|
namespace = config.get_event_namespace()
|
||||||
|
|
||||||
|
if not namespace:
|
||||||
|
raise ValueError("event namespace must be provided in the config.")
|
||||||
|
|
||||||
# Create the event namespace and attach the main app. Not related to any paths.
|
# Create the event namespace and attach the main app. Not related to any paths.
|
||||||
self.event_namespace = EventNamespace("/event", self)
|
self.event_namespace = EventNamespace(namespace, self)
|
||||||
|
|
||||||
# Register the event namespace with the socket.
|
# Register the event namespace with the socket.
|
||||||
self.sio.register_namespace(self.event_namespace)
|
self.sio.register_namespace(self.event_namespace)
|
||||||
|
@ -206,6 +206,9 @@ class Config(Base):
|
|||||||
# Whether to enable or disable nextJS gzip compression.
|
# Whether to enable or disable nextJS gzip compression.
|
||||||
next_compression: bool = True
|
next_compression: bool = True
|
||||||
|
|
||||||
|
# The event namespace for ws connection
|
||||||
|
event_namespace: Optional[str] = constants.EVENT_NAMESPACE
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize the config values.
|
"""Initialize the config values.
|
||||||
|
|
||||||
@ -251,6 +254,18 @@ class Config(Base):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_event_namespace(self) -> Optional[str]:
|
||||||
|
"""Get the websocket event namespace.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The namespace for websocket.
|
||||||
|
"""
|
||||||
|
if self.event_namespace:
|
||||||
|
return f'/{self.event_namespace.strip("/")}'
|
||||||
|
|
||||||
|
event_url = constants.Endpoint.EVENT.get_url()
|
||||||
|
return urllib.parse.urlsplit(event_url).path
|
||||||
|
|
||||||
|
|
||||||
def get_config() -> Config:
|
def get_config() -> Config:
|
||||||
"""Get the app config.
|
"""Get the app config.
|
||||||
|
@ -197,7 +197,8 @@ OLD_CONFIG_FILE = f"pcconfig{PY_EXT}"
|
|||||||
PRODUCTION_BACKEND_URL = "https://{username}-{app_name}.api.pynecone.app"
|
PRODUCTION_BACKEND_URL = "https://{username}-{app_name}.api.pynecone.app"
|
||||||
# Token expiration time in seconds.
|
# Token expiration time in seconds.
|
||||||
TOKEN_EXPIRATION = 60 * 60
|
TOKEN_EXPIRATION = 60 * 60
|
||||||
|
# The event namespace for websocket
|
||||||
|
EVENT_NAMESPACE = get_value("EVENT_NAMESPACE")
|
||||||
|
|
||||||
# Env modes
|
# Env modes
|
||||||
class Env(str, Enum):
|
class Env(str, Enum):
|
||||||
|
@ -5,7 +5,7 @@ import pytest
|
|||||||
|
|
||||||
import reflex as rx
|
import reflex as rx
|
||||||
from reflex import constants
|
from reflex import constants
|
||||||
from reflex.config import DBConfig
|
from reflex.config import DBConfig, get_config
|
||||||
from reflex.constants import get_value
|
from reflex.constants import get_value
|
||||||
|
|
||||||
|
|
||||||
@ -133,3 +133,28 @@ def test_get_value(monkeypatch, key, value, expected_value_type_in_config):
|
|||||||
casted_value = get_value(key, type_=expected_value_type_in_config)
|
casted_value = get_value(key, type_=expected_value_type_in_config)
|
||||||
|
|
||||||
assert isinstance(casted_value, expected_value_type_in_config)
|
assert isinstance(casted_value, expected_value_type_in_config)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"kwargs, expected",
|
||||||
|
[
|
||||||
|
({"app_name": "test_app", "api_url": "http://example.com"}, "/event"),
|
||||||
|
({"app_name": "test_app", "api_url": "http://example.com/api"}, "/api/event"),
|
||||||
|
({"app_name": "test_app", "event_namespace": "/event"}, "/event"),
|
||||||
|
({"app_name": "test_app", "event_namespace": "event"}, "/event"),
|
||||||
|
({"app_name": "test_app", "event_namespace": "event/"}, "/event"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_event_namespace(mocker, kwargs, expected):
|
||||||
|
"""Test the event namespace.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
mocker: The pytest mock object.
|
||||||
|
kwargs: The Config kwargs.
|
||||||
|
expected: Expected namespace
|
||||||
|
"""
|
||||||
|
conf = rx.Config(**kwargs)
|
||||||
|
mocker.patch("reflex.config.get_config", return_value=conf)
|
||||||
|
|
||||||
|
config = get_config()
|
||||||
|
assert config.get_event_namespace() == expected
|
||||||
|
Loading…
Reference in New Issue
Block a user