Skip to content
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

Request: minified header #105

Closed
yuhan0 opened this issue Oct 17, 2018 · 17 comments
Closed

Request: minified header #105

yuhan0 opened this issue Oct 17, 2018 · 17 comments

Comments

@yuhan0
Copy link

yuhan0 commented Oct 17, 2018

With various nbextensions enabled and saved widget state, the size of a header can easily go up to many hundreds of lines.
This produces huge and mostly irrelevant git diffs and makes it inconvenient to skip past all the "commented-out noise" at the start of a paired .py file in order to get to the actual code.

Would it be possible to have a "minified header" formatting option which strips out unnecessary detail and compresses the entire header onto a single line, or one line for every top-level key? My impression was that the header is not meant to be human-edited anyways, apart from the "jupytext.formats" field. Better still, why not dump it in the original JSON format to prevent any round-trip errors?

Thanks so much for this package!

@mwouts
Copy link
Owner

mwouts commented Oct 17, 2018

Thanks @yuhan0 for sharing. It is interesting how people are using the notebook! I had never seen before such big metadata! Interestingly, at the level of cell metadata we face the same problematic (see also #106 ). Certainly the text representation should focus only the metadata that is relevant.

A few comments, suggestions and questions:

  • Jupytext's use of YAML for the header originates in the R Markdown format. YAML header seems quite standard for Markdown documents. For scripts we could discuss a JSON header, but maybe for now, trying to reduce the size of the header would be a first step in the right direction already.
  • An option would be to have Jupytext reading certain metadata in the text header, and the others in the .ipynb file (we already do that for cell metadata). jupytext section would still be mandatory. We could configure this per notebook, using for instance a notebook_metadata entry, that would contain a coma separated list with desired sections.
  • What should be the default value? Something like jupytext, kernelspecs and language_info? Are you aware of any other notebook metadata that users want to be preserved when the .ipynb file is not provided?

@mwouts
Copy link
Owner

mwouts commented Oct 22, 2018

Hello @yuhan0 , the branch v0.8.4 contains a first implementation of this:

  • Unless configured otherwise, Jupytext will only export the jupytext, kernelspecs and language_info section (and kernel_info for nteract notebooks)
  • You can still save all notebook metadata in the text representation by setting metadata {"jupytext": {"metadata": {"notebook": True}}}
  • Discard all notebook metadata in text representations with {"jupytext": {"metadata": {"notebook": False}}}
  • Obtain the default config by removing the metadata entry
  • Save or discard extra fields, relative to the default config, with {"jupytext": {"metadata": {"notebook": "additional_metadata_one,additional_metadata_two-excluded_metadata_one,excluded_metadata_two"}}}

I would like the following feedback from you:

  • are there notebook metadata not in the default list that you would like to preserve in the text representation?
  • is the reduced size of the header more acceptable?
  • is the configuration easy to use?

@yuhan0
Copy link
Author

yuhan0 commented Oct 24, 2018

Hi, thanks for the quick response and sorry I couldn't get around to replying earlier - the suggestions sound good, except I'm slightly confused about this part:

Save or discard extra fields, relative to the default config, with {"jupytext": {"metadata": {"notebook": "additional_metadata_one,additional_metadata_two-excluded_metadata_one,excluded_metadata_two"}}}

Does it mean literally to append the prefixes "additonal" and "excluded" to the metadata names? E.g. {"metadata": {"notebook" : "additional_toc"}} to include the toc metadata.

Is it a good idea to be able to exclude the default sections? Can they be reliably "inferred" if missing or will it possibly lead to strange behaviour? I imagine the "jupytext" section at the least should not be user-excludable.

How about using a spec like:

{"jupytext": {
    "include_metadata": {
        "notebook": [],
        "cells": []
    },
    "exclude_metadata": {
        "notebook": [],
        "cells": []
    }
}}

where any of the keys can be left out to save space.

@yuhan0
Copy link
Author

yuhan0 commented Oct 24, 2018

Another thought - saved widget state should be treated similarly to cell outputs and always excluded no matter what.
As an example, here is a simple notebook with a few widgets:
image

And the resulting .py file after widget state was saved:
(Note the long lines of base64 encoded images, one of my actual notebooks I tried converting had several MB worth of these in the header and ended up crashing my text editor)

Click to view
# ---
# jupyter:
#   jupytext:
#     formats: ipynb,py:light
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.3'
#       jupytext_version: 0.8.3
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
#   language_info:
#     codemirror_mode:
#       name: ipython
#       version: 3
#     file_extension: .py
#     mimetype: text/x-python
#     name: python
#     nbconvert_exporter: python
#     pygments_lexer: ipython3
#     version: 3.6.6
#   toc:
#     base_numbering: 1
#     nav_menu: {}
#     number_sections: false
#     sideBar: false
#     skip_h1_title: false
#     title_cell: Table of Contents
#     title_sidebar: Contents
#     toc_cell: false
#     toc_position: {}
#     toc_section_display: true
#     toc_window_display: false
#   varInspector:
#     cols:
#       lenName: 16
#       lenType: 16
#       lenVar: 40
#     kernels_config:
#       python:
#         delete_cmd_postfix: ''
#         delete_cmd_prefix: 'del '
#         library: var_list.py
#         varRefreshCmd: print(var_dic_list())
#       r:
#         delete_cmd_postfix: ') '
#         delete_cmd_prefix: rm(
#         library: var_list.r
#         varRefreshCmd: 'cat(var_dic_list()) '
#     types_to_exclude:
#     - module
#     - function
#     - builtin_function_or_method
#     - instance
#     - _Feature
#     window_display: false
#   widgets:
#     application/vnd.jupyter.widget-state+json:
#       state:
#         17a76c5b851a428ea03a3f46bdfb2aa1:
#           buffers:
#           - data: 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
#             encoding: base64
#             path:
#             - value
#           model_module: '@jupyter-widgets/controls'
#           model_module_version: 1.4.0
#           model_name: ImageModel
#           state:
#             layout: IPY_MODEL_9ec13b10f8e94aa7ab957bb69eed3358
#             value: {}
#         3271d5a76f974617b2211a2193b582e7:
#           buffers:
#           - data: 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
#             encoding: base64
#             path:
#             - value
#           model_module: '@jupyter-widgets/controls'
#           model_module_version: 1.4.0
#           model_name: ImageModel
#           state:
#             layout: IPY_MODEL_9cf1316b0a194773b45c0133cdfb3fd8
#             value: {}
#         554d40eb74df4a2eac782b4322600a3d:
#           model_module: '@jupyter-widgets/controls'
#           model_module_version: 1.4.0
#           model_name: ButtonModel
#           state:
#             description: click me
#             layout: IPY_MODEL_b13b62ee342743c092951bf3de341efa
#             style: IPY_MODEL_c6c425f66c8f4426b80fed0e97368fa7
#         781f55b660b145e39b98e31a714fe9c9:
#           model_module: '@jupyter-widgets/controls'
#           model_module_version: 1.4.0
#           model_name: VBoxModel
#           state:
#             children:
#             - IPY_MODEL_554d40eb74df4a2eac782b4322600a3d
#             - IPY_MODEL_554d40eb74df4a2eac782b4322600a3d
#             - IPY_MODEL_554d40eb74df4a2eac782b4322600a3d
#             - IPY_MODEL_554d40eb74df4a2eac782b4322600a3d
#             - IPY_MODEL_554d40eb74df4a2eac782b4322600a3d
#             layout: IPY_MODEL_906b1a29a7a749108d0f0625984a3156
#         906b1a29a7a749108d0f0625984a3156:
#           model_module: '@jupyter-widgets/base'
#           model_module_version: 1.1.0
#           model_name: LayoutModel
#           state: {}
#         91a5a7cea40d457189566453e355dd7e:
#           model_module: '@jupyter-widgets/base'
#           model_module_version: 1.1.0
#           model_name: LayoutModel
#           state: {}
#         9cf1316b0a194773b45c0133cdfb3fd8:
#           model_module: '@jupyter-widgets/base'
#           model_module_version: 1.1.0
#           model_name: LayoutModel
#           state: {}
#         9ec13b10f8e94aa7ab957bb69eed3358:
#           model_module: '@jupyter-widgets/base'
#           model_module_version: 1.1.0
#           model_name: LayoutModel
#           state: {}
#         b13b62ee342743c092951bf3de341efa:
#           model_module: '@jupyter-widgets/base'
#           model_module_version: 1.1.0
#           model_name: LayoutModel
#           state: {}
#         b8f33acb0fed42b2a101166a513fb624:
#           model_module: '@jupyter-widgets/controls'
#           model_module_version: 1.4.0
#           model_name: HBoxModel
#           state:
#             children:
#             - IPY_MODEL_781f55b660b145e39b98e31a714fe9c9
#             - IPY_MODEL_3271d5a76f974617b2211a2193b582e7
#             layout: IPY_MODEL_91a5a7cea40d457189566453e355dd7e
#         c6c425f66c8f4426b80fed0e97368fa7:
#           model_module: '@jupyter-widgets/controls'
#           model_module_version: 1.4.0
#           model_name: ButtonStyleModel
#           state: {}
#       version_major: 2
#       version_minor: 0
# ---

# + {"deletable": false, "editable": false}
from io import BytesIO
import ipywidgets as widgets
import requests
# + {"tags": ["#A"]}
url = "http://jupyter.org/assets/try/jupyter.png"
img = widgets.Image(value=BytesIO(requests.get(url).content).getvalue())
# + {"tags": ["=>A"]}
button = widgets.Button(description="click me")
widgets.HBox([
    widgets.VBox([button] * 5),
    img
])

One more thing - how should we go about installing and using the 0.8.4 dev version? Though I may not have the time to test it much..

@mwouts
Copy link
Owner

mwouts commented Oct 24, 2018

Thanks @yuhan0 for your feedback. Indeed the size of the notebook metadata is impressive !

I will soon update the documentation to make it clear how the metadata filtering works in v0.8.4. And please do not bother to install the dev version if that sounds uneasy - let me prepare a new pip release (possibly a release candidate) for v0.8.4, that will be simpler.

@mwouts
Copy link
Owner

mwouts commented Oct 24, 2018

The pre-release is available with

pip install jupytext==v0.8.4rc0

The documentation for the metadata filtering is here.

@yuhan0 , that would be very nice if you could test that the RC works well for you, and also, if you could check that the corresponding part of the documentation is not too hard to follow.

@yuhan0
Copy link
Author

yuhan0 commented Oct 25, 2018

Small correction to the docs: metadata title should be 'widgets', not 'widget'

If you want to preserve all the notebook metadata but widget and varInspector, set a notebook metadata

"jupytext": {"metadata_filter": {"notebook": "all-widget,varInspector"}}

If you want to preserve the toc section (in addition to the default YAML header), use

"jupytext": {"metadata_filter": {"notebook": "toc"}}

At last, if you want to modify the default cell filter and allow ExecuteTime and autoscroll, but not hide_ouput, use

"jupytext": {"metadata_filter": {"cells": "ExecuteTime,autoscroll-hide_ouput"}}

This might be a matter of opinion, but I don't think it's very user-friendly or idiomatic in JSON to overload a single string with multiple attributes by essentially inventing a mini-DSL and dealing with all the edge cases of parsing user input strings. (it's not the Unix command line, after all!)
Eg. what if the metadata title includes a comma or hyphen as part of its name?

Also I found it highly unintuitive that "A,-B" and "-B,A" have different meanings - no other language I know has the negation operator right-associative and take precedence over list/array syntax.

Maybe it would be less ambiguous to require a + or - in front of every item?
So the above examples could be written as:

{"notebook": "+all, -widget, -varInspector"}
{"cells": "+ExecuteTime, +autoscroll, -hide_output"}

with the items in any order.

Edit: Just tried out the 0.8.4rc, it seems that simply adding spaces anywhere between items ({"all -widgets, varInspector"})") breaks the parser, making it fail silently and use default behaviour.

Same thing with the "formats" field: it's slightly annoying that {"formats": "ipynb, py, md"} throws an error instead of ignoring the whitespace.

@mwouts
Copy link
Owner

mwouts commented Oct 25, 2018

Thanks @yuhan0 , this is a very helpful feedback.

  • I agree that spaces should be allowed in comma separated strings
  • I also agree that a minus sign in front of every negated metadata name would be better
  • Indeed, this is not very JSON compliant. For formats, I expect that a list ["ipynb", "py", "md"] will be supported by the parser, but I find akward to ask people to type a list in JSON. And you are right, there are limitations to using minus sign and comma, and also the all keyword. We could offer support for metadata filters coded as a pair of additional/excluded keys, like {"notebook": {"additional":"all", "excluded":["widget", "varInspector"]}}. Note the special meaning of the "all" entry here (it is not in a list). Would you prefer that implementation?

@yuhan0
Copy link
Author

yuhan0 commented Oct 25, 2018

So the full spec would look like this? (informal choice type notation)

{
    "jupytext": {
        "metadata_filter": {
            "notebook": {
                "additional": "all" OR ["strings"]
                "excluded":   "all" OR ["strings"]
            },
            "cells": {
                "additional": "all" OR ["strings"]
                "excluded":   "all" OR ["strings"]
            }
        },
        "formats": ""
    }
}

Perhaps mutually exclusive options would be more compact and remove the ambiguity of having the same item specified in multiple places:

"notebook":{
    "only": ["strings"]        // overrides the defaults
    OR
    "all_except": ["strings"]  // overrides the defaults
    OR
    "additional": ["strings"]  // modifies the defaults
}

This way the default value can be expressed as

"only": [
    "jupytext",
    "kernelspecs",
    "language_info"
]

(Does it make sense to allow the user to exclude any of these?)

My assumption was that an nbextension would be developed sooner or later which would remove the need for the user to manually edit JSON, and it should be more important to make it easy to machine-generate and parse.

To address the trouble of typing in JSON lists, there could be a canonicalization step where a user input comma-separated string in a position where a list of strings was expected would be automatically converted and saved as the list format.

@mwouts
Copy link
Owner

mwouts commented Oct 25, 2018

Thanks @yuhan0 . Let me see if I can implement the excluded / additional representation, and the string to dict converter.

My assumption was that an nbextension would be developed sooner or later which would remove the need for the user to manually edit JSON
Sure! It's #86 , but we need another contributor for this ;-) I have not enough experience with JS...

Another question: do you think the default filtering in the YAML header is good enough? Are you aware of other notebook metadata that users expect to be resilient to .ipynb removal?

@mwouts
Copy link
Owner

mwouts commented Oct 25, 2018

Hello @yuhan0 , I just published another pre-release, available with

pip install jupytext==0.8.4rc1

That release includes the support for the metadata filter as dictionaries, as strings, also allows spaces in strings, and has the automated string to dict conversion (the conversion occurs when the notebook is reloaded).

Could you please let me know if it works well for you?

Are you aware of other notebook metadata that users expect to be resilient to .ipynb removal?

If you have any clue on this, please tell me! We are introducing a significant change in 0.8.4 by keeping only jupytext, kernelspecs and language_info per default in the text representation...

@mwouts
Copy link
Owner

mwouts commented Oct 29, 2018

Available in v0.8.4.

@mwouts mwouts closed this as completed Oct 29, 2018
@mwouts
Copy link
Owner

mwouts commented Nov 18, 2018

@andrethrill , @yuhan0 , I was thinking of removing the language_info section from the notebook metadata that is exported to the script. Indeed, the name of the language is also available in kernelspec. Is that allright with your use cases?

@mwouts mwouts reopened this Nov 18, 2018
mwouts added a commit that referenced this issue Nov 18, 2018
'language_info' section is not in the text metadata any more. Instead, the notebook language is infered from 'kernelspec.name'.
@erdnaavlis
Copy link
Contributor

Hi @mwouts , from my side I believe it's alright yes!

@yuhan0
Copy link
Author

yuhan0 commented Nov 22, 2018

Same with me :) Glad to see such active development on this project!

mwouts added a commit that referenced this issue Nov 25, 2018
'language_info' section is not in the text metadata any more. Instead, the notebook language is infered from 'kernelspec.name'.
@mwouts
Copy link
Owner

mwouts commented Nov 25, 2018

Thanks for your feedback! This is available in the new RC. Please let me know if you find anything wrong with it...

pip install jupytext==0.8.6rc1

@mwouts mwouts mentioned this issue Nov 27, 2018
@mwouts
Copy link
Owner

mwouts commented Nov 29, 2018

Version 0.8.6 is now available.

@mwouts mwouts closed this as completed Nov 29, 2018
mwouts added a commit that referenced this issue Dec 12, 2018
Metadata filters are represented as strings rather than dictionaries, in order to make the YAML header shorter.
mwouts added a commit that referenced this issue Jan 14, 2019
Metadata filters are represented as strings rather than dictionaries, in order to make the YAML header shorter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants