Skip to content

Commit

Permalink
feat: prevent workflows tree to be sent during run mode
Browse files Browse the repository at this point in the history
* refact: use core_ui.export_component_tree before sending the component tree to user interface
* refact: use ServeMode as typing for all argument that requires run or edit
* fix: warning on continuous integration
  • Loading branch information
FabienArcellier committed Oct 8, 2024
1 parent 89ea122 commit afbaf73
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 11 deletions.
19 changes: 13 additions & 6 deletions src/writer/app_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
from pydantic import ValidationError
from watchdog.observers.polling import PollingObserver

from writer import VERSION, audit_and_fix, wf_project
from writer.core import EventHandlerRegistry, MiddlewareRegistry, WriterSession, use_request_context
from writer import VERSION, audit_and_fix, core_ui, wf_project
from writer.core import Config, EventHandlerRegistry, MiddlewareRegistry, WriterSession, use_request_context
from writer.core_ui import ingest_bmc_component_tree
from writer.ss_types import (
AppProcessServerRequest,
Expand All @@ -34,6 +34,7 @@
InitSessionRequest,
InitSessionRequestPayload,
InitSessionResponsePayload,
ServeMode,
StateContentRequest,
StateContentResponsePayload,
StateEnquiryRequest,
Expand Down Expand Up @@ -83,7 +84,7 @@ def __init__(self,
client_conn: multiprocessing.connection.Connection,
server_conn: multiprocessing.connection.Connection,
app_path: str,
mode: str,
mode: ServeMode,
run_code: str,
bmc_components: Dict,
is_app_process_server_ready: multiprocessing.synchronize.Event,
Expand Down Expand Up @@ -147,11 +148,14 @@ def _handle_session_init(self, payload: InitSessionRequestPayload) -> InitSessio
session.session_state.add_log_entry(
"error", "Serialisation error", tb.format_exc())

ui_component_tree = core_ui.export_component_tree(
session.session_component_tree, mode=writer.Config.mode)

res_payload = InitSessionResponsePayload(
userState=user_state,
sessionId=session.session_id,
mail=session.session_state.mail,
components=session.session_component_tree.to_dict(),
components=ui_component_tree,
userFunctions=self._get_user_functions(),
featureFlags=writer.Config.feature_flags
)
Expand All @@ -177,10 +181,13 @@ def _handle_event(self, session: WriterSession, event: WriterEvent) -> EventResp

mail = session.session_state.mail

ui_component_tree = core_ui.export_component_tree(
session.session_component_tree, mode=Config.mode, only_update=True)

res_payload = EventResponsePayload(
result=result,
mutations=mutations,
components=session.session_component_tree.fetch_updates(),
components=ui_component_tree,
mail=mail
)
session.session_state.clear_mail()
Expand Down Expand Up @@ -591,7 +598,7 @@ def __init__(self, app_path: str, mode: str):
if mode not in ("edit", "run"):
raise ValueError("Invalid mode.")

self.mode = mode
self.mode = cast(ServeMode, mode)
self._set_logger()

def hook_to_running_event_loop(self):
Expand Down
3 changes: 2 additions & 1 deletion src/writer/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
InstancePath,
InstancePathItem,
Readable,
ServeMode,
WriterEvent,
WriterEventResult,
WriterFileItem,
Expand Down Expand Up @@ -129,7 +130,7 @@ def wrapper(*args, **kwargs):
class Config:

is_mail_enabled_for_log: bool = False
mode: str = "run"
mode: ServeMode = "run"
logger: Optional[logging.Logger] = None
feature_flags: list[str] = []

Expand Down
19 changes: 18 additions & 1 deletion src/writer/core_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pydantic import BaseModel, Field
from typing_extensions import TypedDict

from writer.ss_types import ComponentDefinition
from writer.ss_types import ComponentDefinition, ServeMode

current_parent_container: ContextVar[Union["Component", None]] = \
ContextVar("current_parent_container")
Expand Down Expand Up @@ -432,6 +432,23 @@ def session_components_list(component_tree: ComponentTree) -> list:
"""
return list(component_tree.branch(Branch.session_cmc).components.values())

def export_component_tree(component_tree: ComponentTree, mode: ServeMode, only_update=False) -> Optional[Dict]:
"""
Exports the component tree to the ui.
>>> filtered_component_tree = core_ui.export_component_tree(session.session_component_tree, mode=writer.Config.mode)
This function filters artifacts that should be hidden from the user, for example workflows in run mode.
:param component_tree: the full component tree
:param mode: the mode of the application (edit, run)
:param updated: return something only if component tree has been updated
:return: a dictionary representing the component tree
"""
if only_update is True and component_tree.updated is False:
return None

return component_tree.to_dict()

class UIError(Exception):
...
Expand Down
6 changes: 3 additions & 3 deletions tests/backend/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ def cumulative_sum(state):
"total": 0
})

initial_state.subscribe_mutation('a\.b', cumulative_sum)
initial_state.subscribe_mutation(r'a\.b', cumulative_sum)

# Acts
initial_state['a.b'] = 1
Expand Down Expand Up @@ -1708,6 +1708,6 @@ def test_parse_state_variable_expression_should_process_expression():
# When
assert parse_state_variable_expression('features') == ['features']
assert parse_state_variable_expression('features.eyes') == ['features', 'eyes']
assert parse_state_variable_expression('features\.eyes') == ['features.eyes']
assert parse_state_variable_expression('features\.eyes.color') == ['features.eyes', 'color']
assert parse_state_variable_expression(r'features\.eyes') == ['features.eyes']
assert parse_state_variable_expression(r'features\.eyes.color') == ['features.eyes', 'color']

0 comments on commit afbaf73

Please sign in to comment.