Skip to content

WIP: copy as code comms #8492

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

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -26,6 +26,7 @@
from .data_explorer_comm import (
ArraySelection,
BackendState,
CodeSyntaxOptions,
ColumnDisplayType,
ColumnFilter,
ColumnFilterType,
Expand All @@ -52,6 +53,7 @@
DataSelectionSingleCell,
ExportDataSelectionFeatures,
ExportDataSelectionRequest,
ExportedCode,
ExportedData,
ExportFormat,
FilterBetween,
Expand All @@ -62,6 +64,7 @@
FilterSetMembership,
FilterTextSearch,
FormatOptions,
GetCodeSyntaxesRequest,
GetColumnProfilesFeatures,
GetColumnProfilesRequest,
GetDataValuesRequest,
Expand Down Expand Up @@ -93,6 +96,7 @@
TableSelectionKind,
TableShape,
TextSearchType,
TranslateToCodeRequest,
)
from .positron_comm import CommMessage, PositronComm
from .utils import BackgroundJobQueue, guid
Expand Down Expand Up @@ -273,6 +277,12 @@ def get_schema(self, request: GetSchemaRequest):
def _get_single_column_schema(self, column_index: int) -> ColumnSchema:
raise NotImplementedError

def get_code_syntaxes(self, request: GetCodeSyntaxesRequest):
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 @@ -1342,6 +1352,14 @@ def schema_getter(column_name, column_index):

return schema_updated, new_state

def get_code_syntaxes(self, request: GetCodeSyntaxesRequest): # noqa: ARG002
"""Returns the supported code types for exporting data."""
return CodeSyntaxOptions(code_syntaxes=["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 ExportedCode(data="import pandas as pd\n\n# TODO: Implement export to code").dict()

@classmethod
def _construct_schema(
cls, column, column_name, column_index: int, state: DataExplorerState
Expand Down Expand Up @@ -2258,6 +2276,14 @@ def schema_getter(column_name, column_index):

return schema_updated, new_state

def get_code_syntaxes(self, request: GetCodeSyntaxesRequest): # noqa: ARG002
"""Returns the supported code types for exporting data."""
return CodeSyntaxOptions(code_syntaxes=["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 ExportedCode(data="import polars as pl\n\n# 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
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,27 @@ class ExportedData(BaseModel):
)


class ExportedCode(BaseModel):
"""
Resulting code
"""

data: Optional[StrictStr] = Field(
default=None,
description="Exported code as a string suitable for copy and paste",
)


class CodeSyntaxOptions(BaseModel):
"""
Code syntaxes available for export
"""

code_syntaxes: List[StrictStr] = Field(
description="Available code syntaxes supported for export",
)


class FilterResult(BaseModel):
"""
The result of applying filters to a table
Expand Down Expand Up @@ -1208,6 +1229,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"

# Get code syntaxes supported for code translation
GetCodeSyntaxes = "get_code_syntaxes"

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

Expand Down Expand Up @@ -1422,6 +1449,65 @@ 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 GetCodeSyntaxesRequest(BaseModel):
"""
Get all available code syntaxes supported for translation for a data
view
"""

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

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 +1661,8 @@ class DataExplorerBackendMessageContent(BaseModel):
GetDataValuesRequest,
GetRowLabelsRequest,
ExportDataSelectionRequest,
TranslateToCodeRequest,
GetCodeSyntaxesRequest,
SetColumnFiltersRequest,
SetRowFiltersRequest,
SetSortColumnsRequest,
Expand Down Expand Up @@ -1623,6 +1711,10 @@ class ReturnColumnProfilesParams(BaseModel):

ExportedData.update_forward_refs()

ExportedCode.update_forward_refs()

CodeSyntaxOptions.update_forward_refs()

FilterResult.update_forward_refs()

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

ExportDataSelectionRequest.update_forward_refs()

TranslateToCodeParams.update_forward_refs()

TranslateToCodeRequest.update_forward_refs()

GetCodeSyntaxesRequest.update_forward_refs()

SetColumnFiltersParams.update_forward_refs()

SetColumnFiltersRequest.update_forward_refs()
Expand Down
99 changes: 98 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",
"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": "exported_code",
"type": "object",
"description": "Resulting code",
"required": [
"code"
],
"properties": {
"data": {
"type": "string",
"description": "Exported code as a string suitable for copy and paste"
}
}
}
}
},
{
"name": "get_code_syntaxes",
"summary": "Get code syntaxes supported for code translation",
"description": "Get all available code syntaxes supported for translation for a data view",
"params": [],
"result": {
"schema": {
"name": "code_syntax_options",
"type": "object",
"description": "Code syntaxes available for export",
"required": [
"code_syntaxes"
],
"properties": {
"code_syntaxes": {
"type": "array",
"description": "Available code syntaxes supported for export",
"items": {
"type": "string"
}
}
}
}
}
},
{
"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,8 @@
"set_row_filters",
"get_column_profiles",
"set_sort_columns",
"export_data_selection"
"export_data_selection",
"export_as_code"
],
"properties": {
"search_schema": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2025 Posit Software, PBC. All rights reserved.
* Licensed under the Elastic License 2.0. See LICENSE.txt for license information.
*--------------------------------------------------------------------------------------------*/

// React.
import React from 'react';

/**
* DropdownEntryProps interface.
*/
interface DropdownEntryProps {
title: string;
subtitle?: string;
group?: string;
}

/**
* DropdownEntry component.
* @param props The dropdown entry props.
* @returns The rendered component
*/
export const DropdownEntry = (props: DropdownEntryProps) => {
// Render.
return (
<div className='dropdown-entry'>
<div className='dropdown-entry-title'>
{props.title}
</div>
{props.group ? <div className='dropdown-entry-group'>{props.group}</div> : null}
</div>
);
};
Loading
Loading