Skip to content

data explorer: "Copy as Code" comms #8536

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

Merged
merged 29 commits into from
Jul 21, 2025
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
02a2c28
make action and button
isabelizimm Jul 2, 2025
dc9ef57
Merge branch 'main' into export-to-code
isabelizimm Jul 8, 2025
6f502e0
plumb through comms
isabelizimm Jul 9, 2025
dcf380b
export -> copy
isabelizimm Jul 10, 2025
32eb2c0
add modal on filter bar
isabelizimm Jul 11, 2025
f9a2c01
ui updates
isabelizimm Jul 14, 2025
2b9f962
make calls from modal
isabelizimm Jul 15, 2025
5083889
clean up comms
isabelizimm Jul 15, 2025
5be588b
clean up modal
isabelizimm Jul 15, 2025
d59fd66
linting for python
isabelizimm Jul 15, 2025
cc2d069
nit to modal
isabelizimm Jul 15, 2025
bae6ced
Merge branch 'export-as-code-comms' into copy-as-code-comms
isabelizimm Jul 15, 2025
4d624bc
updates from copilot
isabelizimm Jul 15, 2025
ac12c66
nit
isabelizimm Jul 15, 2025
0d6e7d9
cleanup
isabelizimm Jul 15, 2025
c33df7c
updates from review
isabelizimm Jul 16, 2025
45cd402
guess syntax immediately
isabelizimm Jul 16, 2025
1adfc02
reorder guessing
isabelizimm Jul 16, 2025
7a0d40b
no undefined for guessing
isabelizimm Jul 16, 2025
9cbe02a
python lint
isabelizimm Jul 17, 2025
51893f0
Update positron/comms/data_explorer-backend-openrpc.json
isabelizimm Jul 17, 2025
9517202
rename, early exits
isabelizimm Jul 17, 2025
36bf5f5
use supported feature flag for syntaxes
isabelizimm Jul 17, 2025
da70e52
refactor
isabelizimm Jul 17, 2025
b6bbe5c
clean up comm names
isabelizimm Jul 17, 2025
ccd15c4
updates from review
isabelizimm Jul 18, 2025
0cc6f14
tweaks to runtime
isabelizimm Jul 18, 2025
0c0ffac
Merge branch 'main' into copy-as-code-comms
isabelizimm Jul 18, 2025
a85ef9f
lint post merge from main
isabelizimm Jul 18, 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
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from .data_explorer_comm import (
ArraySelection,
BackendState,
CodeSyntax,
ColumnDisplayType,
ColumnFilter,
ColumnFilterType,
Expand Down Expand Up @@ -69,6 +70,7 @@
GetRowLabelsRequest,
GetSchemaRequest,
GetStateRequest,
GuessCodeSyntaxRequest,
RowFilter,
RowFilterCondition,
RowFilterType,
Expand All @@ -94,6 +96,8 @@
TableSelectionKind,
TableShape,
TextSearchType,
TranslatedCode,
TranslateToCodeRequest,
)
from .positron_comm import CommMessage, PositronComm
from .utils import BackgroundJobQueue, guid
Expand Down Expand Up @@ -282,6 +286,12 @@
def _get_single_column_schema(self, column_index: int) -> ColumnSchema:
raise NotImplementedError

def get_code_syntaxes(self, request: GetCodeSyntaxesRequest):

Check failure on line 289 in extensions/positron-python/python_files/posit/positron/data_explorer.py

View workflow job for this annotation

GitHub Actions / Check Python types

"GetCodeSyntaxesRequest" is not defined (reportUndefinedVariable)
raise NotImplementedError

def translate_to_code(self, request: TranslateToCodeRequest):
raise NotImplementedError

def search_schema(self, request: SearchSchemaRequest):
filters = request.params.filters
start_index = request.params.start_index
Expand Down Expand Up @@ -805,6 +815,7 @@
support_status=SupportStatus.Unsupported,
supported_formats=[],
),
code_syntaxes=["pandas", "polars"],
)


Expand Down Expand Up @@ -1351,6 +1362,16 @@

return schema_updated, new_state

def guess_code_syntax(self, request: GuessCodeSyntaxRequest): # noqa: ARG002
"""Returns the supported code types for exporting data."""
return CodeSyntax(code_syntax="pandas").dict()

def translate_to_code(self, request: TranslateToCodeRequest): # noqa: ARG002
"""Translates the current data view, including filters and sorts, into a code snippet."""
return TranslatedCode(
translated_code=["import pandas as pd", "# TODO: Implement export to code"]
).dict()

@classmethod
def _construct_schema(
cls, column, column_name, column_index: int, state: DataExplorerState
Expand Down Expand Up @@ -1912,6 +1933,7 @@
ExportFormat.Html,
],
),
code_syntaxes=["pandas"],
)


Expand Down Expand Up @@ -2281,6 +2303,16 @@

return schema_updated, new_state

def guess_code_syntax(self, request: GuessCodeSyntaxRequest): # noqa: ARG002
"""Returns the supported code types for exporting data."""
return CodeSyntax(code_syntax="polars").dict()

def translate_to_code(self, request: TranslateToCodeRequest): # noqa: ARG002
"""Translates the current data view, including filters and sorts, into a code snippet."""
return TranslatedCode(
translated_code=["import polars as pl", "# TODO: Implement export to code"]
).dict()

def _get_single_column_schema(self, column_index: int):
if self.state.schema_cache:
return self.state.schema_cache[column_index]
Expand Down Expand Up @@ -2763,6 +2795,7 @@
supported_formats=[ExportFormat.Csv, ExportFormat.Tsv],
),
set_sort_columns=SetSortColumnsFeatures(support_status=SupportStatus.Supported),
code_syntaxes=["polars"],
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,27 @@ class ExportedData(BaseModel):
)


class TranslatedCode(BaseModel):
"""
Code snippet for the data view
"""

translated_code: List[StrictStr] = Field(
description="Lines of code translating filters and sort keys",
)


class CodeSyntax(BaseModel):
"""
Best guess of syntax to use for code translation
"""

code_syntax: Optional[StrictStr] = Field(
default=None,
description="Best guess of syntax to use for code translation",
)


class FilterResult(BaseModel):
"""
The result of applying filters to a table
Expand Down Expand Up @@ -972,6 +993,10 @@ class SupportedFeatures(BaseModel):
description="Support for 'export_data_selection' RPC and its features",
)

code_syntaxes: List[StrictStr] = Field(
description="List of supported code syntax names",
)


class SearchSchemaFeatures(BaseModel):
"""
Expand Down Expand Up @@ -1208,6 +1233,12 @@ class DataExplorerBackendRequest(str, enum.Enum):
# Export data selection as a string in different formats
ExportDataSelection = "export_data_selection"

# Translates the current data view into a code snippet.
TranslateToCode = "translate_to_code"

# Guess code syntax for code translation
GuessCodeSyntax = "guess_code_syntax"

# Set column filters to select subset of table columns
SetColumnFilters = "set_column_filters"

Expand Down Expand Up @@ -1422,6 +1453,64 @@ class ExportDataSelectionRequest(BaseModel):
)


class TranslateToCodeParams(BaseModel):
"""
Translate filters and sort keys as code in different syntaxes like
pandas, polars, data.table, dplyr
"""

column_filters: List[ColumnFilter] = Field(
description="Zero or more column filters to apply",
)

row_filters: List[RowFilter] = Field(
description="Zero or more row filters to apply",
)

sort_keys: List[ColumnSortKey] = Field(
description="Zero or more sort keys to apply",
)

code_syntax: StrictStr = Field(
description="The code syntax to use for translation",
)


class TranslateToCodeRequest(BaseModel):
"""
Translate filters and sort keys as code in different syntaxes like
pandas, polars, data.table, dplyr
"""

params: TranslateToCodeParams = Field(
description="Parameters to the TranslateToCode method",
)

method: Literal[DataExplorerBackendRequest.TranslateToCode] = Field(
description="The JSON-RPC method name (translate_to_code)",
)

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


class GuessCodeSyntaxRequest(BaseModel):
"""
Guess desired code syntax for translation of a data view based on type
"""

method: Literal[DataExplorerBackendRequest.GuessCodeSyntax] = Field(
description="The JSON-RPC method name (guess_code_syntax)",
)

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


class SetColumnFiltersParams(BaseModel):
"""
Set or clear column filters on table, replacing any previous filters
Expand Down Expand Up @@ -1575,6 +1664,8 @@ class DataExplorerBackendMessageContent(BaseModel):
GetDataValuesRequest,
GetRowLabelsRequest,
ExportDataSelectionRequest,
TranslateToCodeRequest,
GuessCodeSyntaxRequest,
SetColumnFiltersRequest,
SetRowFiltersRequest,
SetSortColumnsRequest,
Expand Down Expand Up @@ -1623,6 +1714,10 @@ class ReturnColumnProfilesParams(BaseModel):

ExportedData.update_forward_refs()

TranslatedCode.update_forward_refs()

CodeSyntax.update_forward_refs()

FilterResult.update_forward_refs()

BackendState.update_forward_refs()
Expand Down Expand Up @@ -1741,6 +1836,12 @@ class ReturnColumnProfilesParams(BaseModel):

ExportDataSelectionRequest.update_forward_refs()

TranslateToCodeParams.update_forward_refs()

TranslateToCodeRequest.update_forward_refs()

GuessCodeSyntaxRequest.update_forward_refs()

SetColumnFiltersParams.update_forward_refs()

SetColumnFiltersRequest.update_forward_refs()
Expand Down
107 changes: 106 additions & 1 deletion positron/comms/data_explorer-backend-openrpc.json
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,98 @@
}
}
},
{
"name": "translate_to_code",
"summary": "Translates the current data view into a code snippet.",
"description": "Translate filters and sort keys as code in different syntaxes like pandas, polars, data.table, dplyr",
Copy link
Member

Choose a reason for hiding this comment

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

I think "translate" is not a great verb here, because it could have so many meanings. Translate from English to another language? Translate from R to Python? I realize there's a lot of context to help someone clarify this, but I suspect it would be even better to use a different verb.

For example, I think "convert" or "generate" are better.

This choice obviously affects a lot of locations (every instance of "translate", "translation", "translated", etc.), so I won't repeat the comment elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had started with generate and moved away from it since I felt it was too AI-y, but I'm on board with convert instead 💯

Copy link
Member

Choose a reason for hiding this comment

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

I hear you re: "generate" and "AI-y" in terms of the UI. But internally, I think "generate" is a very viable option. I'm thinking about how nice "generated code" feels versus "converted code".

Copy link
Member

Choose a reason for hiding this comment

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

In any case, both "generate" and "convert" might be handy for actual names and then also for docstrings.

"params": [
{
"name": "column_filters",
"description": "Zero or more column filters to apply",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/column_filter"
}
}
},
{
"name": "row_filters",
"description": "Zero or more row filters to apply",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/row_filter"
}
}
},
{
"name": "sort_keys",
"description": "Zero or more sort keys to apply",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/column_sort_key"
}
}
},
{
"name": "code_syntax",
"description": "The code syntax to use for translation",
"required": true,
"schema": {
"type": "string",
"items": {
"$ref": "#/components/schemas/code_syntax"
}
}
}
],
"result": {
"schema": {
"name": "translated_code",
"type": "object",
"description": "Code snippet for the data view",
"required": [
"translated_code"
],
"properties": {
"translated_code": {
"type": "array",
"description": "Lines of code translating filters and sort keys",
"items": {
"type": "string"
}
}
}
}
}
},
{
"name": "guess_code_syntax",
Copy link
Member

Choose a reason for hiding this comment

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

I think "suggest" fits the intent better. I feel like "guess" implies there is a right answer and we're trying our best to guess it. Whereas "suggest" seems to fit the situation better. When I see "guessing", I think about "type guessing". Whereas we're suggesting a syntax based on the type.

I feel less strongly about this than about "translate".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh! I like this idea. Will change from guess -> suggest

"summary": "Guess code syntax for code translation",
"description": "Guess desired code syntax for translation of a data view based on type",
"params": [],
"result": {
"schema": {
"name": "code_syntax",
"type": "object",
"description": "Best guess of syntax to use for code translation",
"required": [
"code_syntaxes"
],
"properties": {
"code_syntax": {
"type": "string",
"description": "Best guess of syntax to use for code translation"
}
}
}
}
},
{
"name": "set_column_filters",
"summary": "Set column filters to select subset of table columns",
Expand Down Expand Up @@ -1293,6 +1385,10 @@
}
}
},
"code_syntax": {
"type": "string",
"description": "The syntax for translated code"
},
"supported_features": {
"type": "object",
"description": "For each field, returns flags indicating supported features",
Expand All @@ -1302,7 +1398,9 @@
"set_row_filters",
"get_column_profiles",
"set_sort_columns",
"export_data_selection"
"export_data_selection",
"export_as_code",
"code_syntaxes"
],
"properties": {
"search_schema": {
Expand All @@ -1328,6 +1426,13 @@
"export_data_selection": {
"description": "Support for 'export_data_selection' RPC and its features",
"$ref": "#/components/schemas/export_data_selection_features"
},
"code_syntaxes": {
"type": "array",
"description": "List of supported code syntax names",
"items": {
"type": "string"
}
}
}
},
Expand Down
Loading
Loading