Giter Club home page Giter Club logo

ipyautoui's People

Contributors

dependabot[bot] avatar ivanov avatar jgunstone avatar mwcraig avatar ollyhensby avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

ipyautoui's Issues

value setter not working for EditGrid

from ipyautoui.demo_schemas.editable_datagrid import EditableGrid

schema = {k: v for k,v in EditableGrid.schema().items() if k!="default"}
value = [{'string': 'asdf', 'integer': 12, 'floater': 3.33, 'something_else': 1}]

EditGrid(schema, value=value, transposed=True)

image

EditGrid still setting to the default value

docstrings, __init__ *args and **kwargs and traitlets

hwo to deal with: docstrings, __init__ *args and **kwargs and traitlets

generally within the ipywidget universe, arguments are just traitlets that are piped to the Javascript side of the UI where they are observed to trigger events on_change, this means they can also be edited during the lifetime of the object.

For this reason, I guess, the arguments are defined something like:

import traitlets as tr

class MyClass(tr.HasTraits):
    my_arg = tr.Bool()
    def __init__(self, **kwargs):
        super(MyClass).__init__(*args, **kwargs)

^ kwargs then set the traitlets on instantiation.

how do others do it?


ipycanvas

in ipycanvas it looks like something clever is happening as documentation accompanies the traitlets definitions in the source code:

https://github.com/martinRenou/ipycanvas/blob/d9ee0a16cf0011978b5a5eedb165dbca564eb8c4/ipycanvas/canvas.py#L462-L483

i.e. the #: lines in the code above
which then makes it into the API Documentation


ipydatagrid

https://github.com/bloomberg/ipydatagrid/blob/848238356083575c1cef4b150137edfdf5c04b16/ipydatagrid/datagrid.py#L213-L323

the above simply documents all the traitlets attributes in the docstring. this is nice and simple, and would also make it easier to document traitlets from child classes. This isn't being used to produce API documentation though.


One annoying thing about both of these approaches is that intellisense doesn't work as because the args aren't explicitly defined in the function call.

In reacton-ipycanvas there is a generate function that appears to read the ipycanvas package and convert the traitlets definition into function calls, thus supporting intellisense.

enable rendering object from request

currently on the autodisplay from path is tested - extend to auto display data when retrieved from an API request

ipyautoui.autodisplay.DisplayFromRequest

Adding pytests

Create AutoUi test object and other test objects (iterable, etc).

use pdoc for autorendering .py files

import subprocess
from IPython.display import IFrame
subprocess.Popen("pdoc src/ipyautoui/autoipywidget.py --no-browser", shell=True)

IFrame("http://localhost:8080", width=1200, height=1200)

add copy dialogue options to ipyautoui EditGrid

something like this:

class UiCopyDialogue(w.VBox):
    def __init__(self):
        super().__init__()
        self.bn_top = w.Button(icon="sort-up", layout={"width": "40px"})
        self.bn_inplace = w.Button(icon="sort", layout={"width": "40px"})
        self.bn_end = w.Button(icon="sort-down", layout={"width": "40px"})
        self.bn_blank = w.Button(
            icon="", style={"button_color": "white"}, layout={"width": "40px"}
        )
        self.children = [
            w.HBox([self.bn_top, w.HTML("duplicate selection to beginning")]),
            w.HBox([self.bn_inplace, w.HTML("duplicate selection to below current")]),
            w.HBox([self.bn_end, w.HTML("duplicate selection to end")]),
            w.HBox([self.bn_blank, w.HTML("select new row/col to copy to")]),
        ]


UiCopyDialogue()

Image

then the save_buttonbar.ButtonBar needs editing along with EditGrid.
aim to match UiDelete in functionality
look at TODOs in save_buttonbar

docstring shows wrong arguments for `AutoUi`

In jupyter, looking at the hlpe string shows arguments (schema, value, path, show_raw, validate_onchange, update_fdir_to_path_parent), but the Args in the docstring are different:

In [2]: AutoUi?

Init signature:
AutoUi(
    schema: Union[Type[pydantic.main.BaseModel], dict],
    value: dict = None,
    path: pathlib.Path = None,
    show_raw: bool = True,
    validate_onchange=True,
    update_fdir_to_path_parent=True,
    **kwargs,
)
Docstring:     
extends AutoObject and AutoUiCommonMethods to create an
AutoUi capable of interacting with a json file
Init docstring:
creates a widget input form from schema. datatype must be "object"

Args:
    schema (dict): json schema defining widget to generate
    value (dict, optional): value of json. Defaults to None.
    update_map_widgets (frozenmap, optional): frozen dict of widgets to map to schema items. Defaults to None.
    fdir (path, optional): fdir to work from. useful for widgets that link to files. Defaults to None.
    order (list): allows user to re-specify the order for widget rows to appear by key name in self.di_widgets
    insert_rows (dict): e.g. {3:w.Button()}. allows user to insert a widget into the rows. its presence
        is ignored by the widget otherwise.
    nested_widgets (list): e.g. [FileUploadToDir]. allows user to indicate widgets that should be show / hide
        type

Returns:
    AutoObject(w.VBox)
File:           ~/miniconda3/envs/mapping/lib/python3.10/site-packages/ipyautoui/autoui.py
Type:           MetaHasTraits
Subclasses:     

Updates to editgrid functionality

  • BaseForm should update as different rows are selected.
  • Copy button should instantly copy and paste the selected row/s into the datagrid.
    • Can selected duplicate rows and copy them all.

selected_keys needs to be generic

Currently it uses a specific column to work which is fine in the its use case within aectemplater-ui. However, this is issue generally.

@property
def selected_keys(self):
self._selected_keys = set()
no_rows_selected = 0
for di in self.selected_rows:
no_rows_selected += di["r2"] - di["r1"] + 1
col_posx = list(self.data.columns).index("Name")
arr_property_name_posx = (np.arange(no_rows_selected) * 3) + col_posx
li_property_names_selected = [
self.selected_cell_values[i] for i in arr_property_name_posx
]
self._selected_keys = {
i
for i, v in enumerate(self.value)
if v["Name"] in li_property_names_selected
}
return self._selected_keys

add `close_edit_on_save` boolean to EditGrid

currently -

image

on save the edit dialogue above is automatically closed.
if you want to scroll through rows this may not be favourable.
add a close_edit_on_save config var that allows the user to choose

Release plans

๐Ÿ‘‹ @jgunstone we met at the Future of Jupyter Widgets workshop a few weeks ago. I'd really like to try out ipyautoui in a project I'm working on (the notebook pieces of https://github.com/feder-observatory/stellarphot) but to do that I'd need there to be a release that can be pip installed. In addition to the auto UI functionality, I'm potentially also interested in the auto run piece. The last piece I'm eager to use is your FileChooser wrapper.

I'm happy to help with getting a release ready if you need help, though I won't have a ton of availability until classes end on Dec 6.

I've got a lot of experience with conda-forge, so I'm happy to help with that piece of the packaging puzzle.

EditGrid datahandler review and copy dialogue

currenlty we have a datahandler that mirrors the changes that are happening in EditGrid... could it be more like a watcher that pushes changes?

for implementing a copy dialogue with multiple different copy types, this would require each of those types to also be represented in the datahandler...

review.

this outlines what the copy dialogue would look like but it is currently not implemented for use... (probs shouldn't have put it in the main!)
#96

create a FileUploadHandler widget

create a widget that uses the widgets.FileUpload to upload files, but then automatically saves uploaded files in a specified location.

it should also allow the user to remove uploaded files.

Add and Edit Open Simultaneously

image

The snapshot above shows both Add and Edit options open at the same time.

Add should close when Edit is clicked and vice-versa.

It may be worth updating the button bar UI object to ipywidgets.ToggleButtons.

create a `config_autoui.json` file user specific config data

ipyautoui aims to map provide mapping the root file directory out-the-box.
This is useful when you are running Apps on a remote server, but want to configure a way to open files and folders on the users machine.

This is unlikely to be a common use-case and for most users will be an unused feature, but for those who have access to file both through there computer and through the server, it can be quite a powerful additional feature.

moving this config into a set-up file removes hard-coding any unusual behaviour into the code.

use pydantic config settings to set up.

e.g. https://github.com/maxfordham/aectemplater/blob/main/src/aectemplater/app/env.py

save config_autoui.json in jupyter --config-dir

EditGrid Filtered View

When EditGrid is in transposed view - it is possible to filter on index to show / hide params.
it would be good if these filter settings got passed to the ui_add and ui_edit objects.
this should be fairly straightforward by linking the filter settings to the AutoUi order param, which can also be used for filtering.
the order param should change on change in filter using observe.

Duplicate selected_cols

Which one to keep?

@property
def selected_cols(self):
"""Get the data selected in the table which is returned as a dataframe."""
s = self.selected_visible_cell_iterator
cols = set([l["c"] for l in s])
cols = [self.get_col_name_from_index(col_index) for col_index in cols]
index = self.get_dataframe_index(self.data)
if isinstance(index, pd.core.indexes.frozen.FrozenList):
index = tuple(index)
return [
self.apply_map_name_title({l[index]: l[col_name] for l in s._data["data"]})
for col_name in cols
]
@property
def selected_cols(self):
"""Get the data selected in the table which is returned as a dataframe."""
di = self.selected_dict
index = self.get_dataframe_index(self.data)
if isinstance(index, pd.core.indexes.frozen.FrozenList):
index = tuple(index)
return [self.apply_map_name_title(v) for v in di.values()]

AutoUi allow non object root

AutoUi makes the incorrect assumption that the root must be an "object"
as an example, the pydantic model works fine

from typing import List, Optional
from pydantic import AnyUrl, BaseModel, Field

class Pet(BaseModel):
    id: int
    name: str
    tag: Optional[str] = None

Pet.schema()
{'title': 'Pet',
 'type': 'object',
 'properties': {'id': {'title': 'Id', 'type': 'integer'},
  'name': {'title': 'Name', 'type': 'string'},
  'tag': {'title': 'Tag', 'type': 'string'}},
 'required': ['id', 'name']}

the root is an object and it has properties.

this does not work:

class Pets(BaseModel):
    __root__: List[Pet]

Pets.schema()
{'title': 'Pets',
 'type': 'array',
 'items': {'$ref': '#/definitions/Pet'},
 'definitions': {'Pet': {'title': 'Pet',
   'type': 'object',
   'properties': {'id': {'title': 'Id', 'type': 'integer'},
    'name': {'title': 'Name', 'type': 'string'},
    'tag': {'title': 'Tag', 'type': 'string'}},
   'required': ['id', 'name']}}}

as the root is an array. it should work.

todo before v1 release

we'd like to use ipyautoui as a best-practice example for other maxfordham opensource repos

  • #207
  • #206
  • #208
  • #183
  • #180
  • #17
  • update the setup.py file and replace setup.cfg with pyproject.toml
  • #195 run tests on push / merge to main.
  • #181
  • #200
  • incorporate building the docs into the tests (currently this is easy to do locally but fails at build time). does all the test data need to be in the tests folder?
  • remove versioneer.py and any other un-needed files
  • consider removing some widget libraries from the requirements.txt file and having them as user-installed or optional dependencies for things like: ipydatagrid, ipyfilechooser, ... (potentially making the core it JupyterLite compatible)
  • ... anything else...

attach_schema_refs recursion bug for enums

image

Code circled in red should fix this issue:

image

It basically checks whether the top-level schema (of that recursion level) has '$ref' in it as before it was skipping this and going straight to iterating through the items.

default value from schema being ignored for: Arrays, Objects and DataFrames

see this example:

if __name__ == "__main__":
AUTO_GRID_DEFAULT_VALUE = {
"description": "another description",
"dataframe": [
{"string": "important string", "integer": 1, "floater": 3.14,},
{"string": "update", "integer": 4, "floater": 3.12344,},
{"string": "evening", "integer": 5, "floater": 3.14},
{"string": "morning", "integer": 5, "floater": 3.14},
{"string": "number", "integer": 3, "floater": 3.14},
],
"alist": ["a", "b", "c"],
"anobject": DataFrameCols().dict(),
}
class DataFrameCols(BaseModel):
string: str = Field("string", aui_column_width=100)
integer: int = Field(1, aui_column_width=80)
floater: float = Field(3.1415, aui_column_width=70, aui_sig_fig=3)
something_else: float = Field(324, aui_column_width=100)
class TestDataFrame(BaseModel):
"""a description of TestDataFrame"""
description: str = "a description of my dataframe"
dataframe: typing.List[DataFrameCols] = Field(
default=AUTO_GRID_DEFAULT_VALUE, format="dataframe"
)
alist: typing.List[str] = ["a", "b", "c"]
anobject: DataFrameCols
# TODO: note that default values aren't being set from the schema for the Array or DataGrid
auto_grid = AutoUi(schema=TestDataFrame)
display(auto_grid)
if __name__ == "__main__":
auto_grid.value = AUTO_GRID_DEFAULT_VALUE

traitlets_paths not on conda

traitlets_paths only has a pip install

create a conda-feedstock

it could be removed but is useful for defining pathlib.Path types

Adding Examples

Create more examples to display the functionality of the package

change name from `nullable` to `allow_none` to be consistent with traitlets

we add a nullable flag to the schema indicating to the AutoUi this field can be nulled -
suggest using the terminology allow_none instead of nullable

def add_nullable_to_object(schema_obj):
if "required" in schema_obj.keys():
req = schema_obj["required"]
else:
req = []
if "properties" not in schema_obj.keys():
if "autoui" in schema_obj.keys():
return schema_obj
else:
raise ValueError(
"AutoUi does not support rendering generic dictionaries."
" This can be overridden by specifying a `autoui` pyobject renderer."
)
for k, v in schema_obj["properties"].items():
if k not in req and "default" not in v.keys():
v["nullable"] = True
else:
pass
v = attach_nullable_field(v)
return schema_obj

AutoObject - None Setting Bug

If there is a value and we set it to None:

image

Then this is set successfully:

image

Now setting it back by clicking the toggle button:

image

The default value appears but then pressing save does not set that default value:

image

Potential Reason
I think the issue may be that the _value traitlet hasn't updated upon clicking the toggle button and therefore is still set to None.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.