diff --git a/CHANGELOG.md b/CHANGELOG.md index 2faa74a0..5e697591 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ For pre-1.0 releases, see [0.0.35 Changelog](https://github.com/noteable-io/orig ### Added - CLI for downloading Notebooks and tailing a Notebook to see all RTU messages +- Modeling for RTU messages that were missing + - `variable_explorer_request` on Kernels channel + - `append_output_event` on Files channel + - `v0_create_widget_mdoel_event` on Files channel ### [1.0.0] - 2023-09-08 diff --git a/origami/clients/rtu.py b/origami/clients/rtu.py index bab35706..b7906050 100644 --- a/origami/clients/rtu.py +++ b/origami/clients/rtu.py @@ -685,7 +685,7 @@ async def replay_unapplied_deltas(self): async def on_kernel_status_update(self, msg: KernelStatusUpdateResponse): """Called when we receive a kernel_status_update_event on kernels/ channel""" self.kernel_state = msg.data.kernel.execution_state - logger.info(f"updating Kernel state to: {self.kernel_state}") + logger.debug(f"updating Kernel state to: {self.kernel_state}") async def on_bulk_cell_state_update(self, msg: BulkCellStateUpdateResponse): """Called when we receive a bulk_cell_state_update_event on kernels/ channel""" @@ -695,7 +695,7 @@ async def on_bulk_cell_state_update(self, msg: BulkCellStateUpdateResponse): # When we see that a cell we're monitoring has finished, resolve the Future to # be the cell if item.state in ['finished_with_error', 'finished_with_no_error']: - logger.info( + logger.debug( "Cell execution for monitored cell finished", extra={ 'cell_id': item.cell_id, @@ -722,10 +722,10 @@ async def on_bulk_cell_state_update(self, msg: BulkCellStateUpdateResponse): async def wait_for_kernel_idle(self): """Wait for the kernel to be idle""" - logger.info("Waiting for Kernel to be idle") + logger.debug("Waiting for Kernel to be idle") while self.kernel_state != 'idle': await asyncio.sleep(0.05) - logger.info("Kernel is idle") + logger.debug("Kernel is idle") async def new_delta_request(self, delta=FileDelta) -> FileDelta: """ diff --git a/origami/models/rtu/channels/files.py b/origami/models/rtu/channels/files.py index 904035fd..dbd7ff07 100644 --- a/origami/models/rtu/channels/files.py +++ b/origami/models/rtu/channels/files.py @@ -17,6 +17,7 @@ from pydantic import BaseModel, Field, ValidationError, root_validator +from origami.models.api.outputs import KernelOutput from origami.models.deltas.discriminators import FileDelta from origami.models.kernels import CellState, KernelStatusUpdate from origami.models.rtu.base import BaseRTURequest, BaseRTUResponse, BooleanReplyData @@ -119,6 +120,13 @@ class UpdateOutputCollectionEvent(FilesResponse): data: UpdateOutputCollectionEventData +# If Cells are streaming multiple outputs like a pip install or for loop and print, then we'll get +# append to output events +class AppendOutputEvent(FilesResponse): + event: Literal['append_output_event'] = 'append_output_event' + data: KernelOutput + + # User cell selection is a collaboration feature, shows which cell each user is currently editing # Like Deltas, it follows a request -> reply -> event pattern class UpdateUserCellSelectionRequestData(BaseModel): @@ -190,6 +198,13 @@ class TransformViewToCodeReply(FilesResponse): data: BooleanReplyData +# Widgets, ugh. Not attempting to model the payload, no current plan on doing anything with them +# on the Origami side. +class V0CreateWidgetModelEvent(FilesResponse): + event: Literal['v0_create_widget_model_event'] = 'v0_create_widget_model_event' + data: Any + + # When the API squashes Deltas, it will emit a new file versions changed event class FileVersionsChangedEvent(FilesResponse): event: Literal['v0_file_versions_changed_event'] = 'v0_file_versions_changed_event' @@ -216,9 +231,11 @@ class FileVersionsChangedEvent(FilesResponse): NewDeltaEvent, RemoveUserFileSubscriptionEvent, TransformViewToCodeReply, + V0CreateWidgetModelEvent, UpdateUserCellSelectionReply, UpdateUserFileSubscriptionEvent, UpdateOutputCollectionEvent, + AppendOutputEvent, UsageMetricsEvent, ], Field(discriminator='event'), diff --git a/origami/models/rtu/channels/kernels.py b/origami/models/rtu/channels/kernels.py index bafb6f37..41b49d9a 100644 --- a/origami/models/rtu/channels/kernels.py +++ b/origami/models/rtu/channels/kernels.py @@ -62,6 +62,14 @@ class VariableExplorerUpdateRequest(KernelsRequest): event: Literal['variable_explorer_update_request'] = 'variable_explorer_update_request' +# It is confusing but variable_explorer_update_request can either be an RTU client to Gate server +# (RTURequest) or also be propogated out by Gate from another client, meaning it comes in as a +# server-to-client (RTUResponse) so we need to model it just to avoid warning about unmodeled msgs +class VariableExplorerUpdateRequestPropogated(KernelsResponse): + event: Literal['variable_explorer_update_request'] = 'variable_explorer_update_request' + data: dict = Field(default_factory=dict) + + class VariableExplorerResponse(KernelsResponse): event: Literal['variable_explorer_event'] = 'variable_explorer_event' @@ -131,6 +139,7 @@ class IntegratedAIResultEvent(KernelsResponse): KernelSubscribeReply, KernelStatusUpdateResponse, BulkCellStateUpdateResponse, + VariableExplorerUpdateRequestPropogated, VariableExplorerResponse, IntegratedAIReply, IntegratedAIResultReply, diff --git a/origami/notebook/builder.py b/origami/notebook/builder.py index 1efa308d..34410ddc 100644 --- a/origami/notebook/builder.py +++ b/origami/notebook/builder.py @@ -197,7 +197,7 @@ def update_notebook_metadata(self, delta: NBMetadataUpdate): def update_cell_metadata(self, delta: CellMetadataUpdate): """Update cell metadata using a partial update / nested path technique""" if delta.resource_id in self.deleted_cell_ids: - logger.info( + logger.debug( f"Skipping update_cell_metadata for deleted cell {delta.resource_id}", extra={'delta_properties_path': delta.properties.path}, ) diff --git a/tests/e2e/conftest.py b/tests/e2e/conftest.py index 15801872..1cd32f4f 100644 --- a/tests/e2e/conftest.py +++ b/tests/e2e/conftest.py @@ -107,19 +107,19 @@ def api_base_url(): @pytest.fixture def test_space_id() -> uuid.UUID: # TODO: use env var or otherwise make configurable for CI - return uuid.UUID('edc21f3f-fb30-45fb-a30d-668fac0b0e4a') + return uuid.UUID('1ecc737e-0252-49a1-af9b-a0a400db5888') @pytest.fixture def test_project_id() -> uuid.UUID: # TODO: use env var or otherwise make configurable for CI - return uuid.UUID('c34e6a11-cc60-4ab6-9566-10f81a4a46cd') + return uuid.UUID('a752faf4-bbc7-4fe1-9c5f-be92394e48a2') @pytest.fixture def test_user_id() -> uuid.UUID: # TODO: use env var or otherwise make configurable for CI - return uuid.UUID('f9dfb1b5-7ae4-477c-818f-08d0732018d3') + return uuid.UUID('9eb39719-4fc1-44de-9155-3edaeb32ce2c') class LogWarningTransport(httpx.AsyncHTTPTransport):