Skip to content

Notify backends of updates to plot render settings #7450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c8f1d9d
Add event for plot render settings
lionel- Mar 28, 2025
cae5152
Draft request UI backend notification
lionel- Apr 15, 2025
925981d
Add subscription types
lionel- Apr 22, 2025
2eca3fd
Notify interested backends
lionel- Apr 22, 2025
275325e
Invert dependencies between services
lionel- Apr 23, 2025
53a728c
Ensure handler is called on already started UI clients
lionel- Apr 24, 2025
940e7b6
Add `register()` method to UI client instances for lifecycle management
lionel- Apr 24, 2025
f797341
Fix import imbroglio
lionel- Apr 24, 2025
b4af4eb
Add justfile for comms
lionel- Apr 25, 2025
8f52097
Homogenize naming
lionel- Apr 25, 2025
dd47371
Second pass at exports conundrum
lionel- Apr 25, 2025
7128299
Add support for external references in OpenRPC contracts
lionel- Apr 25, 2025
4e26f54
Make notification a request for now
lionel- Apr 30, 2025
1fd14da
Fix merge issues
lionel- May 1, 2025
1cd6adf
Import external refs rather than redefine them
lionel- May 1, 2025
6b5398e
Tweak doc
lionel- May 1, 2025
ab8bd19
Fix comparison of settings
lionel- May 5, 2025
d6faccd
Fix dependencies in `useEffect()`
lionel- May 5, 2025
1b22ae8
Be defensive against invalid sizes
lionel- May 5, 2025
e83aa96
Notify of render settings with current policy
lionel- May 6, 2025
b20cdb8
Fix lifecycle issues with plot clients
lionel- May 6, 2025
b870c38
Update current sizing policy when plot policy changes
lionel- May 6, 2025
97a83e6
Add `onDidChangesizingPolicy` event on plot service
lionel- May 6, 2025
1085107
Notify backends of sizing policy changes
lionel- May 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions extensions/positron-python/python_files/posit/positron/plot_comm.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,20 @@


@enum.unique
class RenderFormat(str, enum.Enum):
class PlotUnit(str, enum.Enum):
"""
Possible values for PlotUnit
"""

Pixels = "pixels"

Inches = "inches"


@enum.unique
class PlotRenderFormat(str, enum.Enum):
"""
Possible values for RenderFormat
Possible values for PlotRenderFormat
"""

Png = "png"
Expand All @@ -35,17 +46,6 @@ class RenderFormat(str, enum.Enum):
Tiff = "tiff"


@enum.unique
class PlotUnit(str, enum.Enum):
"""
Possible values for PlotUnit
"""

Pixels = "pixels"

Inches = "inches"


class IntrinsicSize(BaseModel):
"""
The intrinsic size of a plot, if known
Expand Down Expand Up @@ -81,9 +81,9 @@ class PlotResult(BaseModel):
description="The MIME type of the plot data",
)

policy: Optional[RenderPolicy] = Field(
settings: Optional[PlotRenderSettings] = Field(
default=None,
description="The policy used to render the plot",
description="The settings used to render the plot",
)


Expand All @@ -101,21 +101,21 @@ class PlotSize(BaseModel):
)


class RenderPolicy(BaseModel):
class PlotRenderSettings(BaseModel):
"""
The policy used to render the plot
The settings used to render the plot
"""

size: PlotSize = Field(
description="Plot size of the render policy",
description="Plot size to render the plot to",
)

pixel_ratio: Union[StrictInt, StrictFloat] = Field(
description="The pixel ratio of the display device",
)

format: RenderFormat = Field(
description="Format of the render policy",
format: PlotRenderFormat = Field(
description="Format in which to render the plot",
)


Expand Down Expand Up @@ -163,7 +163,7 @@ class RenderParams(BaseModel):
description="The pixel ratio of the display device",
)

format: RenderFormat = Field(
format: PlotRenderFormat = Field(
description="The requested plot format",
)

Expand Down Expand Up @@ -215,7 +215,7 @@ class PlotFrontendEvent(str, enum.Enum):

PlotSize.update_forward_refs()

RenderPolicy.update_forward_refs()
PlotRenderSettings.update_forward_refs()

GetIntrinsicSizeRequest.update_forward_refs()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def verify_response(response, filename: str, expected_size: Tuple[float, float],
assert percent_difference(image.size[1], expected_size[1] * pixel_ratio) <= threshold

# Check the rest of the response.
assert response == json_rpc_response({"mime_type": f"image/{format_}", "policy": None})
assert response == json_rpc_response({"mime_type": f"image/{format_}", "settings": None})

verify_response(response, "test-mpl-render-0-explicit-size", (size.width, size.height))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

from ._vendor.pydantic import BaseModel, Field, StrictBool, StrictFloat, StrictInt, StrictStr

from .plot_comm import PlotRenderSettings

Param = Any
CallMethodResult = Any

Expand Down Expand Up @@ -137,10 +139,47 @@ class UiBackendRequest(str, enum.Enum):
An enumeration of all the possible requests that can be sent to the backend ui comm.
"""

# Notification that the settings to render a plot (i.e. the plot size)
# have changed.
DidChangePlotsRenderSettings = "did_change_plots_render_settings"

# Run a method in the interpreter and return the result to the frontend
CallMethod = "call_method"


class DidChangePlotsRenderSettingsParams(BaseModel):
"""
Typically fired when the plot component has been resized by the user.
This notification is useful to produce accurate pre-renderings of
plots.
"""

settings: PlotRenderSettings = Field(
description="Plot rendering settings.",
)


class DidChangePlotsRenderSettingsRequest(BaseModel):
"""
Typically fired when the plot component has been resized by the user.
This notification is useful to produce accurate pre-renderings of
plots.
"""

params: DidChangePlotsRenderSettingsParams = Field(
description="Parameters to the DidChangePlotsRenderSettings method",
)

method: Literal[UiBackendRequest.DidChangePlotsRenderSettings] = Field(
description="The JSON-RPC method name (did_change_plots_render_settings)",
)

jsonrpc: str = Field(
default="2.0",
description="The JSON-RPC version specifier",
)


class CallMethodParams(BaseModel):
"""
Unlike other RPC methods, `call_method` calls into methods implemented
Expand Down Expand Up @@ -180,7 +219,10 @@ class CallMethodRequest(BaseModel):

class UiBackendMessageContent(BaseModel):
comm_id: str
data: CallMethodRequest
data: Union[
DidChangePlotsRenderSettingsRequest,
CallMethodRequest,
] = Field(..., discriminator="method")


@enum.unique
Expand Down Expand Up @@ -477,6 +519,10 @@ class ShowHtmlFileParams(BaseModel):

Range.update_forward_refs()

DidChangePlotsRenderSettingsParams.update_forward_refs()

DidChangePlotsRenderSettingsRequest.update_forward_refs()

CallMethodParams.update_forward_refs()

CallMethodRequest.update_forward_refs()
Expand Down
4 changes: 4 additions & 0 deletions extensions/positron-r/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ export async function makeMetadata(
config.get<string>('shutdownTimeout', 'immediately') !== 'immediately' ?
positron.LanguageRuntimeSessionLocation.Machine : positron.LanguageRuntimeSessionLocation.Workspace;

// Subscribe to UI notifications of interest
const uiSubscriptions = [positron.UiRuntimeNotifications.DidChangePlotsRenderSettings];

const metadata: positron.LanguageRuntimeMetadata = {
runtimeId,
runtimeName,
Expand All @@ -295,6 +298,7 @@ export async function makeMetadata(
).toString('base64'),
sessionLocation,
startupBehavior,
uiSubscriptions,
extraRuntimeData
};

Expand Down
14 changes: 13 additions & 1 deletion positron/comms/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,16 @@ npm install
If you've already installed dependencies, just run the code generator.
This will (re-)generate code for all comms.

```
```sh
npx ts-node generate-comms.ts
```

If you have `just` installed, then just run `just`:

```sh
just
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just easier to remember :-)

```

For each contract, this writes Rust, Python, and Typescript modules using the current contract.
It also prints each affected filepath.

Expand All @@ -82,6 +88,12 @@ This will (re-)generate code only for the ui and variables comms.
npx ts-node generate-comms.ts ui variables
```

You can pass arguments via `just` as well but you'll need to explicitly name the `gen` recipe instead of relying on it being the default:

```
just gen ui variables
```

Above we've targetted two comms by name, "ui" and "variables".
It's also acceptable to specify a comm by mentioning any member of its trio of files, i.e. "ui.json", "ui-frontend-openrpc.json", and "ui-backend-openrpc.json" are the same as specifying "ui".

Expand Down
Loading
Loading