diff --git a/CHANGES.md b/CHANGES.md index d81075c4..5022d409 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,3 +21,8 @@ Changelog * calling `show()` now returns an object which can alter the state of a process * accessing/altering state through the `data` property * shutting down a process using the `kill()` function + +### 1.3.0 (2019-10-29) + * `webbrowser` integration (the ability to automatically open a webbrowser upon calling `dtale.show()`) + * flag for hiding the "Shutdown" button for long-running demos + * "Instances" navigator popup for viewing all activate D-Tale instances for the current python process diff --git a/README.md b/README.md index 08e43588..482ab0c3 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,16 @@ $ pip install --upgrade dtale Now you will have to ability to use D-Tale from the command-line or within a python-enabled terminal ### Command-line +Base CLI options (run `dtale --help` to see all options available) + +|Prop|Description| +|:--------:|------| +|`--host`|the name of the host you would like to use (most likely not needed since `socket.gethostname()` should figure this out)| +|`--port`|the port you would like to assign to your D-Tale instance| +|`--debug`|turn on Flask's "debug" mode for your D-Tale instance| +|`--no-reaper`|flag to turn off auto-reaping subprocess (kill D-Tale instances after an hour of inactivity), good for long-running displays | +|`--open-browser`|flag to automatically open up your server's default browser to your D-Tale instance| + Loading data from **arctic** ```bash dtale --arctic-host mongodb://localhost:27027 --arctic-library jdoe.my_lib --arctic-node my_node --arctic-start 20130101 --arctic-end 20161231 @@ -135,6 +145,14 @@ d.data = tmp # Shutting down D-Tale process d.kill() + +# using Python's `webbrowser` package it will try and open your server's default browser to this process +d.open_browser() + +# There is also some helpful metadata about the process +d._port # the process's port +d._url # the url to access the process + ``` ## UI @@ -198,6 +216,37 @@ Selecting/Deselecting Columns |--------|:------:| |![About-up-to-date](https://raw.githubusercontent.com/manahl/dtale/master/docs/images/About-up-to-date.png "About - Out of Date")|![About-out-of-date](https://raw.githubusercontent.com/manahl/dtale/master/docs/images/About-out-of-date.png "About - Up to Date")| +- **Instances**: This will give you information about other D-Tale instances are running under your current Python process. + +For example, if you ran the following script: +```python +import pandas as pd +import dtale + +dtale.show(pd.DataFrame([dict(foo=1, bar=2, biz=3, baz=4, snoopy_D_O_double_gizzle=5)])) +dtale.show(pd.DataFrame([ + dict(a=1, b=2, c=3, d=4), + dict(a=2, b=3, c=4, d=5), + dict(a=3, b=4, c=5, d=6), + dict(a=4, b=5, c=6, d=7) +])) +dtale.show(pd.DataFrame([range(6), range(6), range(6), range(6), range(6), range(6)]), name="foo") +``` +This will make the **Instances** button available in all 3 of these D-Tale instances. Clicking that button while in the first instance invoked above will give you this popup: + +![Instances](https://raw.githubusercontent.com/manahl/dtale/master/docs/images/Instances.png "Instances") +* Grid with the following information + * Process: timestamp when the process was started along with the name (if specified in `dtale.show()`) + * Rows: number of rows + * Columns: number of columns + * Column Names: comma-separated string of column names (only first 30 characters, hover for full listing) + * Preview: this button is available any of the non-current instances. Clicking this will bring up left-most 5X5 grid information for that instance +* The row highlighted in green signifys the current D-Tale instance +* Any other row can be clicked to switch to that D-Tale instance + +Here is an example of clicking the "Preview" button: + +![Instances_w_preview](https://raw.githubusercontent.com/manahl/dtale/master/docs/images/Instances_preview.png "Instances Preview") - Resize: mostly a fail-safe in the event that your columns are no longer lining up. Click this and should fix that - Shutdown: pretty self-explanatory, kills your D-Tale session (there is also an auto-kill process that will kill your D-Tale after an hour of inactivity) diff --git a/docs/images/Browser1.png b/docs/images/Browser1.png index abefc93e..a966fc69 100644 Binary files a/docs/images/Browser1.png and b/docs/images/Browser1.png differ diff --git a/docs/images/Col_select.png b/docs/images/Col_select.png index 6f693c55..cca6df42 100644 Binary files a/docs/images/Col_select.png and b/docs/images/Col_select.png differ diff --git a/docs/images/Info_menu.png b/docs/images/Info_menu.png index 627cad37..bd83d92d 100644 Binary files a/docs/images/Info_menu.png and b/docs/images/Info_menu.png differ diff --git a/docs/images/Info_menu_small.png b/docs/images/Info_menu_small.png index 98b66134..4710f263 100644 Binary files a/docs/images/Info_menu_small.png and b/docs/images/Info_menu_small.png differ diff --git a/docs/images/Instances.png b/docs/images/Instances.png new file mode 100644 index 00000000..045ed434 Binary files /dev/null and b/docs/images/Instances.png differ diff --git a/docs/images/Instances_preview.png b/docs/images/Instances_preview.png new file mode 100644 index 00000000..7fe04489 Binary files /dev/null and b/docs/images/Instances_preview.png differ diff --git a/docs/images/Menu_one_col.png b/docs/images/Menu_one_col.png index 64b7796c..f7707a4d 100644 Binary files a/docs/images/Menu_one_col.png and b/docs/images/Menu_one_col.png differ diff --git a/docs/source/conf.py b/docs/source/conf.py index cfa12a1d..96ab1202 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -63,9 +63,9 @@ # built documents. # # The short X.Y version. -version = u'1.2.0' +version = u'1.3.0' # The full version, including alpha/beta/rc tags. -release = u'1.2.0' +release = u'1.3.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/package.json b/package.json index cb4e0d97..ef811684 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dtale", - "version": "1.2.0", + "version": "1.3.0", "description": "Numeric Data Viewer", "main": "main.js", "directories": { diff --git a/setup.py b/setup.py index 4c385ab1..cb99a384 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,7 @@ def run_tests(self): setup( name="dtale", - version="1.2.0", + version="1.3.0", author="MAN Alpha Technology", author_email="ManAlphaTech@man.com", description="Web Client for Visualizing Pandas Objects", diff --git a/tests/dtale/test_app.py b/tests/dtale/test_app.py index 476409fd..ee40e9d1 100644 --- a/tests/dtale/test_app.py +++ b/tests/dtale/test_app.py @@ -1,4 +1,5 @@ import mock +import numpy as np import pandas as pd import pandas.util.testing as pdt import pytest @@ -66,6 +67,16 @@ def test_show(unittest): data_hook.open_browser() assert 'http://localhost:9999' == webbrowser_instance.open.mock_calls[1][1][0] + # RangeIndex test + test_data = pd.DataFrame([1, 2, 3]) + with ExitStack() as stack: + mock_run = stack.enter_context(mock.patch('dtale.app.DtaleFlask.run', mock.Mock())) + mock_find_free_port = stack.enter_context(mock.patch('dtale.app.find_free_port', mock.Mock(return_value=9999))) + stack.enter_context(mock.patch('socket.gethostname', mock.Mock(return_value='localhost'))) + mock_logger = stack.enter_context(mock.patch('dtale.app.logger', mock.Mock())) + data_hook = show(data=test_data, subprocess=False, name='foo') + assert np.array_equal(data_hook.data['0'].values, test_data[0].values) + def mock_run(self, *args, **kwargs): assert self.jinja_env.auto_reload assert self.config['TEMPLATES_AUTO_RELOAD']