Skip to content

Commit

Permalink
Merge pull request #701 from FabienArcellier/fix/dataframe-name
Browse files Browse the repository at this point in the history
refact: rename EditableDataframe into EditableDataFrame
  • Loading branch information
ramedina86 authored Dec 18, 2024
2 parents 00b964f + 3093c36 commit d877ba2
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 80 deletions.
2 changes: 1 addition & 1 deletion apps/hello/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def _get_editable_df():
'object': [{"updatedAt": None}, {"updatedAt": None}, {"updatedAt": None}],
'text': ['one', 'two', 'three'],
})
return wf.EditableDataframe(df)
return wf.EditableDataFrame(df)

def _get_highlighted_members():
sample_df = _get_main_df().sample(3).set_index("name", drop=False)
Expand Down
18 changes: 9 additions & 9 deletions docs/framework/dataframe.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ it offers components as `dataframe` to manipulate dataframes. These components a
|--------------------|---------------------------------------|
| `pandas.DataFrame` | x |
| `polar.DataFrame` | x |
| `list of records` | x (with `EditableDataframe`) |
| `list of records` | x (with `EditableDataFrame`) |

## Use a dataframe

Expand All @@ -26,7 +26,7 @@ wf.init_state({

## Prepare a dataframe for editing

**writer provides `EditableDataframe` as a helper to facilitate manipulation**. it makes it easier to write event handlers such as adding a line,
**writer provides `EditableDataFrame` as a helper to facilitate manipulation**. it makes it easier to write event handlers such as adding a line,
deleting it or modifying a value, etc...

```python
Expand All @@ -36,7 +36,7 @@ import writer as wf
df = pandas.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})

wf.init_state({
'mydf': wf.EditableDataframe(df)
'mydf': wf.EditableDataFrame(df)
})
```

Expand All @@ -50,7 +50,7 @@ import writer as wf

df = pandas.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
wf.init_state({
'mydf': wf.EditableDataframe(df)
'mydf': wf.EditableDataFrame(df)
})

# Subscribe this event handler to the `wf-dataframe-add` event
Expand All @@ -76,9 +76,9 @@ def on_record_action(state, payload):
state['record'] = state['df'].record(record_index) # dict representation of record
```

### Datastructures supported by `EditableDataframe`
### Datastructures supported by `EditableDataFrame`

`EditableDataframe` can be used with a panda dataframe, a polar dataframe and list of records.
`EditableDataFrame` can be used with a panda dataframe, a polar dataframe and list of records.

```python
import pandas
Expand All @@ -91,8 +91,8 @@ polars_df = polars.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
list_of_records = [{'a': 1, 'b': 4}, {'a': 2, 'b': 5}, {'a': 3, 'b': 6}]

wf.init_state({
'mypandas': wf.EditableDataframe(panda_df),
'mypolars': wf.EditableDataframe(polars_df),
'mylistofrecords': wf.EditableDataframe(list_of_records)
'mypandas': wf.EditableDataFrame(panda_df),
'mypolars': wf.EditableDataFrame(polars_df),
'mylistofrecords': wf.EditableDataFrame(list_of_records)
})
```
15 changes: 11 additions & 4 deletions src/ui/src/components/core/content/CoreDataframe.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,23 +139,30 @@ const description = "A component to display Pandas DataFrames.";
const dataFrameUpdateHandlerStub = `
# Subscribe this event handler to the \`wf-dataframe-update\` event
#
# more on : https://dev.writer.com/framework/dataframe
def on_record_change(state, payload):
state['mydf'].record_update(payload)`;
state['mydf'].record_update(payload) # should contain an EditableDataFrame instance`;
const dataFrameAddHandlerStub = `
# Subscribe this event handler to the \`wf-dataframe-add\` event
#
# more on : https://dev.writer.com/framework/dataframe
def on_record_add(state, payload):
payload['record']['sales'] = 0 # default value inside the dataframe
state['mydf'].record_add(payload)`;
state['mydf'].record_add(payload) # should contain an EditableDataFrame instance`;
const dataFrameActionHandlerStub = `
# Subscribe this event handler to the \`wf-dataframe-action\` event
#
# more on : https://dev.writer.com/framework/dataframe
def on_record_action(state, payload):
# state['mydf'] should contains an EditableDataFrame instance
record_index = payload['record_index']
if payload['action'] == 'remove':
state['mydf'].record_remove(payload)
state['mydf'].record_remove(payload) # should contain an EditableDataFrame instance
if payload['action'] == 'open':
state['record'] = state['df'].record(record_index) # dict representation of record`;
state['record'] = state['mydf'].record(record_index) # dict representation of record`;
export default {
writer: {
Expand Down
2 changes: 1 addition & 1 deletion src/writer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from writer.core import (
writerproperty as property,
)
from writer.core_df import EditableDataframe
from writer.core_df import EditableDataFrame

try:
from writer.ui import WriterUIManager
Expand Down
4 changes: 2 additions & 2 deletions src/writer/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ class StateSerialiser:
"""
def serialise(self, v: Any) -> Union[Dict, List, str, bool, int, float, None]:
from writer.ai import Conversation
from writer.core_df import EditableDataframe
from writer.core_df import EditableDataFrame

if isinstance(v, State):
return self._serialise_dict_recursively(v.to_dict())
Expand All @@ -299,7 +299,7 @@ def serialise(self, v: Any) -> Union[Dict, List, str, bool, int, float, None]:
return self._serialise_list_recursively(v)
if isinstance(v, (str, bool)):
return v
if isinstance(v, EditableDataframe):
if isinstance(v, EditableDataFrame):
table = v.pyarrow_table()
return self._serialise_pyarrow_table(table)
if v is None:
Expand Down
70 changes: 35 additions & 35 deletions src/writer/core_df.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import pyarrow # type: ignore

from .core import MutableValue, import_failure
from .ss_types import DataframeRecordAdded, DataframeRecordRemoved, DataframeRecordUpdated
from .ss_types import DataFrameRecordAdded, DataFrameRecordRemoved, DataFrameRecordUpdated

if TYPE_CHECKING:
import pandas
Expand Down Expand Up @@ -38,37 +38,37 @@ def record(df: Any, record_index: int) -> dict:
"""
This method read a record at the given line and get it back as dictionary
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> r = edf.record(1)
"""
raise NotImplementedError

@staticmethod
def record_add(df: Any, payload: DataframeRecordAdded) -> Any:
def record_add(df: Any, payload: DataFrameRecordAdded) -> Any:
"""
signature of the methods to be implemented to process wf-dataframe-add event
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_add({"record": {"a": 1, "b": 2}})
"""
raise NotImplementedError

@staticmethod
def record_update(df: Any, payload: DataframeRecordUpdated) -> Any:
def record_update(df: Any, payload: DataFrameRecordUpdated) -> Any:
"""
signature of the methods to be implemented to process wf-dataframe-update event
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_update({"record_index": 12, "record": {"a": 1, "b": 2}})
"""
raise NotImplementedError

@staticmethod
def record_remove(df: Any, payload: DataframeRecordRemoved) -> Any:
def record_remove(df: Any, payload: DataFrameRecordRemoved) -> Any:
"""
signature of the methods to be implemented to process wf-dataframe-action event
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_remove({"record_index": 12})
"""
raise NotImplementedError
Expand All @@ -86,7 +86,7 @@ class PandasRecordProcessor(DataframeRecordProcessor):
PandasRecordProcessor processes records from a pandas dataframe saved into an EditableDataframe
>>> df = pandas.DataFrame({"a": [1, 2], "b": [3, 4]})
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_add({"a": 1, "b": 2})
"""

Expand All @@ -100,7 +100,7 @@ def match(df: Any) -> bool:
def record(df: 'pandas.DataFrame', record_index: int) -> dict:
"""
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> r = edf.record(1)
"""
import pandas
Expand All @@ -118,9 +118,9 @@ def record(df: 'pandas.DataFrame', record_index: int) -> dict:
return dict(record)

@staticmethod
def record_add(df: 'pandas.DataFrame', payload: DataframeRecordAdded) -> 'pandas.DataFrame':
def record_add(df: 'pandas.DataFrame', payload: DataFrameRecordAdded) -> 'pandas.DataFrame':
"""
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_add({"record": {"a": 1, "b": 2}})
"""
import pandas
Expand All @@ -137,9 +137,9 @@ def record_add(df: 'pandas.DataFrame', payload: DataframeRecordAdded) -> 'pandas
return pandas.concat([df, new_df])

@staticmethod
def record_update(df: 'pandas.DataFrame', payload: DataframeRecordUpdated) -> 'pandas.DataFrame':
def record_update(df: 'pandas.DataFrame', payload: DataFrameRecordUpdated) -> 'pandas.DataFrame':
"""
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_update({"record_index": 12, "record": {"a": 1, "b": 2}})
"""
import pandas
Expand All @@ -162,9 +162,9 @@ def record_update(df: 'pandas.DataFrame', payload: DataframeRecordUpdated) -> 'p
return df

@staticmethod
def record_remove(df: 'pandas.DataFrame', payload: DataframeRecordRemoved) -> 'pandas.DataFrame':
def record_remove(df: 'pandas.DataFrame', payload: DataFrameRecordRemoved) -> 'pandas.DataFrame':
"""
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_remove({"record_index": 12})
"""
record_index: int = payload['record_index']
Expand All @@ -187,7 +187,7 @@ class PolarRecordProcessor(DataframeRecordProcessor):
PolarRecordProcessor processes records from a polar dataframe saved into an EditableDataframe
>>> df = polars.DataFrame({"a": [1, 2], "b": [3, 4]})
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_add({"record": {"a": 1, "b": 2}})
"""

Expand All @@ -201,7 +201,7 @@ def match(df: Any) -> bool:
def record(df: 'polars.DataFrame', record_index: int) -> dict:
"""
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> r = edf.record(1)
"""
record = {}
Expand All @@ -213,15 +213,15 @@ def record(df: 'polars.DataFrame', record_index: int) -> dict:


@staticmethod
def record_add(df: 'polars.DataFrame', payload: DataframeRecordAdded) -> 'polars.DataFrame':
def record_add(df: 'polars.DataFrame', payload: DataFrameRecordAdded) -> 'polars.DataFrame':
_assert_record_match_polar_df(df, payload['record'])

import polars
new_df = polars.DataFrame([payload['record']])
return polars.concat([df, new_df])

@staticmethod
def record_update(df: 'polars.DataFrame', payload: DataframeRecordUpdated) -> 'polars.DataFrame':
def record_update(df: 'polars.DataFrame', payload: DataFrameRecordUpdated) -> 'polars.DataFrame':
# This implementation works but is not optimal.
# I didn't find a better way to update a record in polars
#
Expand All @@ -236,7 +236,7 @@ def record_update(df: 'polars.DataFrame', payload: DataframeRecordUpdated) -> 'p
return df

@staticmethod
def record_remove(df: 'polars.DataFrame', payload: DataframeRecordRemoved) -> 'polars.DataFrame':
def record_remove(df: 'polars.DataFrame', payload: DataFrameRecordRemoved) -> 'polars.DataFrame':
import polars

record_index: int = payload['record_index']
Expand All @@ -257,7 +257,7 @@ class RecordListRecordProcessor(DataframeRecordProcessor):
RecordListRecordProcessor processes records from a list of record saved into an EditableDataframe
>>> df = [{"a": 1, "b": 2}, {"a": 3, "b": 4}]
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_add({"record": {"a": 1, "b": 2}})
"""

Expand All @@ -270,20 +270,20 @@ def match(df: Any) -> bool:
def record(df: List[Dict[str, Any]], record_index: int) -> dict:
"""
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> r = edf.record(1)
"""
r = df[record_index]
return copy.copy(r)

@staticmethod
def record_add(df: List[Dict[str, Any]], payload: DataframeRecordAdded) -> List[Dict[str, Any]]:
def record_add(df: List[Dict[str, Any]], payload: DataFrameRecordAdded) -> List[Dict[str, Any]]:
_assert_record_match_list_of_records(df, payload['record'])
df.append(payload['record'])
return df

@staticmethod
def record_update(df: List[Dict[str, Any]], payload: DataframeRecordUpdated) -> List[Dict[str, Any]]:
def record_update(df: List[Dict[str, Any]], payload: DataFrameRecordUpdated) -> List[Dict[str, Any]]:
_assert_record_match_list_of_records(df, payload['record'])

record_index = payload['record_index']
Expand All @@ -293,7 +293,7 @@ def record_update(df: List[Dict[str, Any]], payload: DataframeRecordUpdated) ->
return df

@staticmethod
def record_remove(df: List[Dict[str, Any]], payload: DataframeRecordRemoved) -> List[Dict[str, Any]]:
def record_remove(df: List[Dict[str, Any]], payload: DataFrameRecordRemoved) -> List[Dict[str, Any]]:
del(df[payload['record_index']])
return df

Expand All @@ -314,13 +314,13 @@ def pyarrow_table(df: List[Dict[str, Any]]) -> pyarrow.Table:

return table

class EditableDataframe(MutableValue):
class EditableDataFrame(MutableValue):
"""
Editable Dataframe makes it easier to process events from components
that modify a dataframe like the dataframe editor.
>>> initial_state = wf.init_state({
>>> "df": wf.EditableDataframe(df)
>>> "df": wf.EditableDataFrame(df)
>>> })
Editable Dataframe is compatible with a pandas, thrillers or record list dataframe
Expand Down Expand Up @@ -348,41 +348,41 @@ def df(self, value: Union['pandas.DataFrame', 'polars.DataFrame', List[dict]]) -
self._df = value
self.mutate()

def record_add(self, payload: DataframeRecordAdded) -> None:
def record_add(self, payload: DataFrameRecordAdded) -> None:
"""
Adds a record to the dataframe
>>> df = pandas.DataFrame({"a": [1, 2], "b": [3, 4]})
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_add({"record": {"a": 1, "b": 2}})
"""
assert self.processor is not None

self._df = self.processor.record_add(self.df, payload)
self.mutate()

def record_update(self, payload: DataframeRecordUpdated) -> None:
def record_update(self, payload: DataFrameRecordUpdated) -> None:
"""
Updates a record in the dataframe
The record must be complete otherwise an error is raised (ValueError).
It must a value for each index / column.
>>> df = pandas.DataFrame({"a": [1, 2], "b": [3, 4]})
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_update({"record_index": 0, "record": {"a": 2, "b": 2}})
"""
assert self.processor is not None

self._df = self.processor.record_update(self.df, payload)
self.mutate()

def record_remove(self, payload: DataframeRecordRemoved) -> None:
def record_remove(self, payload: DataFrameRecordRemoved) -> None:
"""
Removes a record from the dataframe
>>> df = pandas.DataFrame({"a": [1, 2], "b": [3, 4]})
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> edf.record_remove({"record_index": 0})
"""
assert self.processor is not None
Expand All @@ -397,7 +397,7 @@ def pyarrow_table(self) -> pyarrow.Table:
This mechanism is used for serializing data for transmission to the frontend.
>>> df = pandas.DataFrame({"a": [1, 2], "b": [3, 4]})
>>> edf = EditableDataframe(df)
>>> edf = EditableDataFrame(df)
>>> pa_table = edf.pyarrow_table()
"""
assert self.processor is not None
Expand Down
Loading

0 comments on commit d877ba2

Please sign in to comment.