Synchronize Event Namespace (#1370)
This commit is contained in:
parent
370e1fd04c
commit
4505279d5d
@ -97,6 +97,9 @@ class App(Base):
|
||||
Args:
|
||||
*args: Args 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)
|
||||
|
||||
@ -128,9 +131,13 @@ class App(Base):
|
||||
|
||||
# Create the socket app. Note event endpoint constant replaces the default 'socket.io' 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.
|
||||
self.event_namespace = EventNamespace("/event", self)
|
||||
self.event_namespace = EventNamespace(namespace, self)
|
||||
|
||||
# Register the event namespace with the socket.
|
||||
self.sio.register_namespace(self.event_namespace)
|
||||
|
@ -206,6 +206,9 @@ class Config(Base):
|
||||
# Whether to enable or disable nextJS gzip compression.
|
||||
next_compression: bool = True
|
||||
|
||||
# The event namespace for ws connection
|
||||
event_namespace: Optional[str] = constants.EVENT_NAMESPACE
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the config values.
|
||||
|
||||
@ -251,6 +254,18 @@ class Config(Base):
|
||||
except AttributeError:
|
||||
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:
|
||||
"""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"
|
||||
# Token expiration time in seconds.
|
||||
TOKEN_EXPIRATION = 60 * 60
|
||||
|
||||
# The event namespace for websocket
|
||||
EVENT_NAMESPACE = get_value("EVENT_NAMESPACE")
|
||||
|
||||
# Env modes
|
||||
class Env(str, Enum):
|
||||
|
@ -5,7 +5,7 @@ import pytest
|
||||
|
||||
import reflex as rx
|
||||
from reflex import constants
|
||||
from reflex.config import DBConfig
|
||||
from reflex.config import DBConfig, get_config
|
||||
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)
|
||||
|
||||
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