├── .flake8 ├── .gitignore ├── LICENSE ├── Pipfile ├── Pipfile.lock ├── README.md ├── build_package.sh ├── examples ├── example_notebook.html ├── example_notebook.ipynb ├── example_notebook.mystnb └── render_file.py ├── mystify ├── __init__.py ├── convert.py └── myst_contents_manager.py ├── push_branch.sh ├── setup.cfg ├── setup.py └── tests ├── __init__.py ├── context.py ├── execute_functions.py └── test_e2e.py /.flake8: -------------------------------------------------------------------------------- 1 | # .flake8 2 | # 3 | # DESCRIPTION 4 | # Configuration file for the python linter flake8. 5 | # 6 | # This configuration is based on the generic 7 | # configuration published on GitHub. 8 | # 9 | # AUTHOR 10 | # krnd 11 | # 12 | # VERSION 13 | # 1.0 14 | # 15 | # SEE ALSO 16 | # http://flake8.pycqa.org/en/latest/user/options.html 17 | # http://flake8.pycqa.org/en/latest/user/error-codes.html 18 | # https://pycodestyle.readthedocs.io/en/latest/intro.html#error-codes 19 | # https://gist.github.com/krnd 20 | # 21 | 22 | 23 | [flake8] 24 | 25 | ################### PROGRAM ################################ 26 | 27 | # Specify the number of subprocesses that Flake8 will use to run checks in parallel. 28 | jobs = auto 29 | 30 | 31 | ################### OUTPUT ################################# 32 | 33 | ########## VERBOSITY ########## 34 | 35 | # Increase the verbosity of Flake8’s output. 36 | verbose = 0 37 | # Decrease the verbosity of Flake8’s output. 38 | quiet = 0 39 | 40 | 41 | ########## FORMATTING ########## 42 | 43 | # Select the formatter used to display errors to the user. 44 | format = default 45 | 46 | # Print the total number of errors. 47 | count = True 48 | # Print the source code generating the error/warning in question. 49 | show-source = True 50 | # Count the number of occurrences of each error/warning code and print a report. 51 | statistics = True 52 | 53 | 54 | ########## TARGETS ########## 55 | 56 | # Redirect all output to the specified file. 57 | output-file = .flake8.log 58 | # Also print output to stdout if output-file has been configured. 59 | tee = True 60 | 61 | 62 | ################### FILE PATTERNS ########################## 63 | 64 | # Provide a comma-separated list of glob patterns to exclude from checks. 65 | exclude = 66 | # git folder 67 | .git, 68 | # python cache 69 | __pycache__, 70 | experiment/*, 71 | # Provide a comma-separate list of glob patterns to include for checks. 72 | filename = 73 | *.py 74 | 75 | 76 | ################### LINTING ################################ 77 | 78 | ########## ENVIRONMENT ########## 79 | 80 | # Provide a custom list of builtin functions, objects, names, etc. 81 | builtins = 82 | 83 | 84 | ########## OPTIONS ########## 85 | 86 | # Report all errors, even if it is on the same line as a `# NOQA` comment. 87 | disable-noqa = False 88 | 89 | # Toggle whether pycodestyle should enforce matching the indentation of the opening bracket’s line. 90 | # incluences E131 and E133 91 | hang-closing = True 92 | 93 | 94 | ########## RULES ########## 95 | 96 | # ERROR CODES 97 | # 98 | # E/W - PEP8 errors/warnings (pycodestyle) 99 | # F - linting errors (pyflakes) 100 | # C - McCabe complexity error (mccabe) 101 | # 102 | # W503 - line break before binary operator 103 | 104 | # Specify a list of codes to `. 105 | ignore = E203, E266, E501, W503, F403, F401, E133, E402 106 | max-line-length = 79 107 | max-complexity = 18 108 | # Specify the list of error codes you wish Flake8 to report. 109 | select = B,C,E,F,W,T4,B9 110 | 111 | # Enable off-by-default extensions. 112 | enable-extensions = 113 | 114 | 115 | ########## DOCSTRING ########## 116 | 117 | # Enable PyFlakes syntax checking of doctests in docstrings. 118 | doctests = True 119 | 120 | # Specify which files are checked by PyFlakes for doctest syntax. 121 | include-in-doctest = *.py 122 | # Specify which files are not to be checked by PyFlakes for doctest syntax. 123 | exclude-in-doctest = -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | 130 | .pyre/ 131 | 132 | .vscode/ 133 | .DS_Store 134 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 ML Apps 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | flake8 = "*" 8 | black = "*" 9 | pytest = "*" 10 | pylint = "*" 11 | 12 | [packages] 13 | flake8 = "*" 14 | pyyaml = "*" 15 | jinja2 = "*" 16 | notebook = "*" 17 | jupyter = "*" 18 | pytest = "*" 19 | myst-parser = "*" 20 | black = "*" 21 | 22 | [requires] 23 | python_version = "3.8" 24 | 25 | [pipenv] 26 | allow_prereleases = true 27 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "bd128159b98f70f1dd60d02ef859abddcfdfd5fada80b3598b7eb796d49527af" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.8" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "alabaster": { 20 | "hashes": [ 21 | "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", 22 | "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02" 23 | ], 24 | "version": "==0.7.12" 25 | }, 26 | "appdirs": { 27 | "hashes": [ 28 | "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", 29 | "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" 30 | ], 31 | "version": "==1.4.4" 32 | }, 33 | "async-generator": { 34 | "hashes": [ 35 | "sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b", 36 | "sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144" 37 | ], 38 | "version": "==1.10" 39 | }, 40 | "attrs": { 41 | "hashes": [ 42 | "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", 43 | "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" 44 | ], 45 | "version": "==19.3.0" 46 | }, 47 | "babel": { 48 | "hashes": [ 49 | "sha256:1aac2ae2d0d8ea368fa90906567f5c08463d98ade155c0c4bfedd6a0f7160e38", 50 | "sha256:d670ea0b10f8b723672d3a6abeb87b565b244da220d76b4dba1b66269ec152d4" 51 | ], 52 | "version": "==2.8.0" 53 | }, 54 | "backcall": { 55 | "hashes": [ 56 | "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e", 57 | "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255" 58 | ], 59 | "version": "==0.2.0" 60 | }, 61 | "black": { 62 | "hashes": [ 63 | "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", 64 | "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539" 65 | ], 66 | "index": "pypi", 67 | "version": "==19.10b0" 68 | }, 69 | "bleach": { 70 | "hashes": [ 71 | "sha256:2bce3d8fab545a6528c8fa5d9f9ae8ebc85a56da365c7f85180bfe96a35ef22f", 72 | "sha256:3c4c520fdb9db59ef139915a5db79f8b51bc2a7257ea0389f30c846883430a4b" 73 | ], 74 | "version": "==3.1.5" 75 | }, 76 | "certifi": { 77 | "hashes": [ 78 | "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3", 79 | "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41" 80 | ], 81 | "version": "==2020.6.20" 82 | }, 83 | "chardet": { 84 | "hashes": [ 85 | "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", 86 | "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" 87 | ], 88 | "version": "==3.0.4" 89 | }, 90 | "click": { 91 | "hashes": [ 92 | "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", 93 | "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" 94 | ], 95 | "version": "==7.1.2" 96 | }, 97 | "decorator": { 98 | "hashes": [ 99 | "sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760", 100 | "sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7" 101 | ], 102 | "version": "==4.4.2" 103 | }, 104 | "defusedxml": { 105 | "hashes": [ 106 | "sha256:8ede8ba04cf5bf7999e1492fa77df545db83717f52c5eab625f97228ebd539bf", 107 | "sha256:aa621655d72cdd30f57073893b96cd0c3831a85b08b8e4954531bdac47e3e8c8" 108 | ], 109 | "version": "==0.7.0rc1" 110 | }, 111 | "docutils": { 112 | "hashes": [ 113 | "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af", 114 | "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc" 115 | ], 116 | "version": "==0.16" 117 | }, 118 | "entrypoints": { 119 | "hashes": [ 120 | "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19", 121 | "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451" 122 | ], 123 | "version": "==0.3" 124 | }, 125 | "flake8": { 126 | "hashes": [ 127 | "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c", 128 | "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208" 129 | ], 130 | "index": "pypi", 131 | "version": "==3.8.3" 132 | }, 133 | "idna": { 134 | "hashes": [ 135 | "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6", 136 | "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0" 137 | ], 138 | "version": "==2.10" 139 | }, 140 | "imagesize": { 141 | "hashes": [ 142 | "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1", 143 | "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1" 144 | ], 145 | "version": "==1.2.0" 146 | }, 147 | "ipykernel": { 148 | "hashes": [ 149 | "sha256:731adb3f2c4ebcaff52e10a855ddc87670359a89c9c784d711e62d66fccdafae", 150 | "sha256:a8362e3ae365023ca458effe93b026b8cdadc0b73ff3031472128dd8a2cf0289" 151 | ], 152 | "version": "==5.3.0" 153 | }, 154 | "ipython": { 155 | "hashes": [ 156 | "sha256:2dbcc8c27ca7d3cfe4fcdff7f45b27f9a8d3edfa70ff8024a71c7a8eb5f09d64", 157 | "sha256:9f4fcb31d3b2c533333893b9172264e4821c1ac91839500f31bd43f2c59b3ccf" 158 | ], 159 | "version": "==7.16.1" 160 | }, 161 | "ipython-genutils": { 162 | "hashes": [ 163 | "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", 164 | "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8" 165 | ], 166 | "version": "==0.2.0" 167 | }, 168 | "ipywidgets": { 169 | "hashes": [ 170 | "sha256:87b30e4dfd68a7c4e3c6462eedb95ac7d1a776cc182f87168d960151151de31c", 171 | "sha256:9cb5590e583b8ea309a2d8e88fb02e44d054df2a77891f7d3356b0b883b99d3d" 172 | ], 173 | "version": "==8.0.0a0" 174 | }, 175 | "jedi": { 176 | "hashes": [ 177 | "sha256:1ddb0ec78059e8e27ec9eb5098360b4ea0a3dd840bedf21415ea820c21b40a22", 178 | "sha256:807d5d4f96711a2bcfdd5dfa3b1ae6d09aa53832b182090b222b5efb81f52f63" 179 | ], 180 | "version": "==0.17.1" 181 | }, 182 | "jinja2": { 183 | "hashes": [ 184 | "sha256:c10142f819c2d22bdcd17548c46fa9b77cf4fda45097854c689666bf425e7484", 185 | "sha256:c922560ac46888d47384de1dbdc3daaa2ea993af4b26a436dec31fa2c19ec668" 186 | ], 187 | "index": "pypi", 188 | "version": "==3.0.0a1" 189 | }, 190 | "jsonschema": { 191 | "hashes": [ 192 | "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", 193 | "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" 194 | ], 195 | "version": "==3.2.0" 196 | }, 197 | "jupyter": { 198 | "hashes": [ 199 | "sha256:3e1f86076bbb7c8c207829390305a2b1fe836d471ed54be66a3b8c41e7f46cc7", 200 | "sha256:5b290f93b98ffbc21c0c7e749f054b3267782166d72fa5e3ed1ed4eaf34a2b78", 201 | "sha256:d9dc4b3318f310e34c82951ea5d6683f67bed7def4b259fafbfe4f1beb1d8e5f" 202 | ], 203 | "index": "pypi", 204 | "version": "==1.0.0" 205 | }, 206 | "jupyter-client": { 207 | "hashes": [ 208 | "sha256:5099cda1ac86b27b655a715c51e15bdc8bd9595b2b17adb41a2bd446bbbafc4a", 209 | "sha256:9f0092a0951d878e7521924899e1fba6f689c7a99d43735a4c0bc05c6f311452" 210 | ], 211 | "version": "==6.1.5" 212 | }, 213 | "jupyter-console": { 214 | "hashes": [ 215 | "sha256:6f6ead433b0534909df789ea64f0a14cdf9b6b2360757756f08182be4b9e431b", 216 | "sha256:b392155112ec86a329df03b225749a0fa903aa80811e8eda55796a40b5e470d8" 217 | ], 218 | "version": "==6.1.0" 219 | }, 220 | "jupyter-core": { 221 | "hashes": [ 222 | "sha256:394fd5dd787e7c8861741880bdf8a00ce39f95de5d18e579c74b882522219e7e", 223 | "sha256:a4ee613c060fe5697d913416fc9d553599c05e4492d58fac1192c9a6844abb21" 224 | ], 225 | "version": "==4.6.3" 226 | }, 227 | "jupyterlab-pygments": { 228 | "hashes": [ 229 | "sha256:19a0ccde7daddec638363cd3d60b63a4f6544c9181d65253317b2fb492a797b9", 230 | "sha256:c9535e5999f29bff90bd0fa423717dcaf247b71fad505d66b17d3217e9021fc5" 231 | ], 232 | "version": "==0.1.1" 233 | }, 234 | "markdown-it-py": { 235 | "hashes": [ 236 | "sha256:5aadd75fc225f8d9a88acd870f326e6717a24eda82d13f4e8e45f2681fcdcc64", 237 | "sha256:8604eb6005736dda3799aad37727cfcdf8640f79691b94c7660968f10306a044" 238 | ], 239 | "version": "==0.4.7" 240 | }, 241 | "markupsafe": { 242 | "hashes": [ 243 | "sha256:06358015a4dee8ee23ae426bf885616ab3963622defd829eb45b44e3dee3515f", 244 | "sha256:0b0c4fc852c5f02c6277ef3b33d23fcbe89b1b227460423e3335374da046b6db", 245 | "sha256:267677fc42afed5094fc5ea1c4236bbe4b6a00fe4b08e93451e65ae9048139c7", 246 | "sha256:303cb70893e2c345588fb5d5b86e0ca369f9bb56942f03064c5e3e75fa7a238a", 247 | "sha256:3c9b624a0d9ed5a5093ac4edc4e823e6b125441e60ef35d36e6f4a6fdacd5054", 248 | "sha256:42033e14cae1f6c86fc0c3e90d04d08ce73ac8e46ba420a0d22d545c2abd4977", 249 | "sha256:4e4a99b6af7bdc0856b50020c095848ec050356a001e1f751510aef6ab14d0e0", 250 | "sha256:4eb07faad54bb07427d848f31030a65a49ebb0cec0b30674f91cf1ddd456bfe4", 251 | "sha256:63a7161cd8c2bc563feeda45df62f42c860dd0675e2b8da2667f25bb3c95eaba", 252 | "sha256:68e0fd039b68d2945b4beb947d4023ca7f8e95b708031c345762efba214ea761", 253 | "sha256:8092a63397025c2f655acd42784b2a1528339b90b987beb9253f22e8cdbb36c3", 254 | "sha256:841218860683c0f2223e24756843d84cc49cccdae6765e04962607754a52d3e0", 255 | "sha256:94076b2314bd2f6cfae508ad65b4d493e3a58a50112b7a2cbb6287bdbc404ae8", 256 | "sha256:9d22aff1c5322e402adfb3ce40839a5056c353e711c033798cf4f02eb9f5124d", 257 | "sha256:b0e4584f62b3e5f5c1a7bcefd2b52f236505e6ef032cc508caa4f4c8dc8d3af1", 258 | "sha256:b1163ffc1384d242964426a8164da12dbcdbc0de18ea36e2c34b898ed38c3b45", 259 | "sha256:beac28ed60c8e838301226a7a85841d0af2068eba2dcb1a58c2d32d6c05e440e", 260 | "sha256:c29f096ce79c03054a1101d6e5fe6bf04b0bb489165d5e0e9653fb4fe8048ee1", 261 | "sha256:c58779966d53e5f14ba393d64e2402a7926601d1ac8adeb4e83893def79d0428", 262 | "sha256:cfe14b37908eaf7d5506302987228bff69e1b8e7071ccd4e70fd0283b1b47f0b", 263 | "sha256:e834249c45aa9837d0753351cdca61a4b8b383cc9ad0ff2325c97ff7b69e72a6", 264 | "sha256:eed1b234c4499811ee85bcefa22ef5e466e75d132502226ed29740d593316c1f" 265 | ], 266 | "version": "==2.0.0a1" 267 | }, 268 | "mccabe": { 269 | "hashes": [ 270 | "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", 271 | "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" 272 | ], 273 | "version": "==0.6.1" 274 | }, 275 | "mistune": { 276 | "hashes": [ 277 | "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e", 278 | "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4" 279 | ], 280 | "version": "==0.8.4" 281 | }, 282 | "more-itertools": { 283 | "hashes": [ 284 | "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5", 285 | "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2" 286 | ], 287 | "version": "==8.4.0" 288 | }, 289 | "myst-parser": { 290 | "hashes": [ 291 | "sha256:37013a654b490681fed9fecef8cf62b613d609beb2e03a3f6d941eb7b3392424", 292 | "sha256:5715f69c74199e94816f77239ee9161d9277b743b1262b47c3eaa319d53f64e3" 293 | ], 294 | "index": "pypi", 295 | "version": "==0.9.0" 296 | }, 297 | "nbclient": { 298 | "hashes": [ 299 | "sha256:930a31304f348e029c6669776a9862a9353829ec5f79c0c55e574e4a9ba8a6c5", 300 | "sha256:fcee4c1288c904cf5e4f087aced20b76c86e1565d09b85633396ac55dcd29dea" 301 | ], 302 | "version": "==0.4.0" 303 | }, 304 | "nbconvert": { 305 | "hashes": [ 306 | "sha256:083f90594c371ded912b8863caf6e9010570ee968d89ee4f352bae7d99d4b0f9", 307 | "sha256:4a46c3c76897eb963ec49174c9f60395b6fcd6c98be81a53d26b2657c67e9c85" 308 | ], 309 | "version": "==6.0.0a3" 310 | }, 311 | "nbformat": { 312 | "hashes": [ 313 | "sha256:54d4d6354835a936bad7e8182dcd003ca3dc0cedfee5a306090e04854343b340", 314 | "sha256:ea55c9b817855e2dfcd3f66d74857342612a60b1f09653440f4a5845e6e3523f" 315 | ], 316 | "version": "==5.0.7" 317 | }, 318 | "nest-asyncio": { 319 | "hashes": [ 320 | "sha256:75dad56eaa7078e2e29c6630f114077fc5060069658d74545b0409e63ca8a028", 321 | "sha256:766ee832cdef108497a70dd729cc4ff56d16a8d3e08404ae138bdf15913f66f9" 322 | ], 323 | "version": "==1.3.3" 324 | }, 325 | "notebook": { 326 | "hashes": [ 327 | "sha256:162747997b118ab302efb8e8e60e0c1fac4b9cdd74ebef5d9829294ed873de9a", 328 | "sha256:26ec53ac302735bc650eb112cc90ec73ce29dd38da0c61b5c1da4ab1dc0d96a7" 329 | ], 330 | "index": "pypi", 331 | "version": "==6.1.0rc1" 332 | }, 333 | "packaging": { 334 | "hashes": [ 335 | "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", 336 | "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" 337 | ], 338 | "version": "==20.4" 339 | }, 340 | "pandocfilters": { 341 | "hashes": [ 342 | "sha256:b3dd70e169bb5449e6bc6ff96aea89c5eea8c5f6ab5e207fc2f521a2cf4a0da9" 343 | ], 344 | "version": "==1.4.2" 345 | }, 346 | "parso": { 347 | "hashes": [ 348 | "sha256:158c140fc04112dc45bca311633ae5033c2c2a7b732fa33d0955bad8152a8dd0", 349 | "sha256:908e9fae2144a076d72ae4e25539143d40b8e3eafbaeae03c1bfe226f4cdf12c" 350 | ], 351 | "version": "==0.7.0" 352 | }, 353 | "pathspec": { 354 | "hashes": [ 355 | "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", 356 | "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061" 357 | ], 358 | "version": "==0.8.0" 359 | }, 360 | "pexpect": { 361 | "hashes": [ 362 | "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", 363 | "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" 364 | ], 365 | "markers": "sys_platform != 'win32'", 366 | "version": "==4.8.0" 367 | }, 368 | "pickleshare": { 369 | "hashes": [ 370 | "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", 371 | "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" 372 | ], 373 | "version": "==0.7.5" 374 | }, 375 | "pluggy": { 376 | "hashes": [ 377 | "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", 378 | "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" 379 | ], 380 | "version": "==0.13.1" 381 | }, 382 | "prometheus-client": { 383 | "hashes": [ 384 | "sha256:983c7ac4b47478720db338f1491ef67a100b474e3bc7dafcbaefb7d0b8f9b01c", 385 | "sha256:c6e6b706833a6bd1fd51711299edee907857be10ece535126a158f911ee80915" 386 | ], 387 | "version": "==0.8.0" 388 | }, 389 | "prompt-toolkit": { 390 | "hashes": [ 391 | "sha256:563d1a4140b63ff9dd587bda9557cffb2fe73650205ab6f4383092fb882e7dc8", 392 | "sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04" 393 | ], 394 | "version": "==3.0.5" 395 | }, 396 | "ptyprocess": { 397 | "hashes": [ 398 | "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0", 399 | "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f" 400 | ], 401 | "markers": "os_name != 'nt'", 402 | "version": "==0.6.0" 403 | }, 404 | "py": { 405 | "hashes": [ 406 | "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2", 407 | "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342" 408 | ], 409 | "version": "==1.9.0" 410 | }, 411 | "pycodestyle": { 412 | "hashes": [ 413 | "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", 414 | "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" 415 | ], 416 | "version": "==2.6.0" 417 | }, 418 | "pyflakes": { 419 | "hashes": [ 420 | "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", 421 | "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" 422 | ], 423 | "version": "==2.2.0" 424 | }, 425 | "pygments": { 426 | "hashes": [ 427 | "sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44", 428 | "sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324" 429 | ], 430 | "version": "==2.6.1" 431 | }, 432 | "pyparsing": { 433 | "hashes": [ 434 | "sha256:1060635ca5ac864c2b7bc7b05a448df4e32d7d8c65e33cbe1514810d339672a2", 435 | "sha256:56a551039101858c9e189ac9e66e330a03fb7079e97ba6b50193643905f450ce" 436 | ], 437 | "version": "==3.0.0a2" 438 | }, 439 | "pyrsistent": { 440 | "hashes": [ 441 | "sha256:28669905fe725965daa16184933676547c5bb40a5153055a8dee2a4bd7933ad3" 442 | ], 443 | "version": "==0.16.0" 444 | }, 445 | "pytest": { 446 | "hashes": [ 447 | "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1", 448 | "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8" 449 | ], 450 | "index": "pypi", 451 | "version": "==5.4.3" 452 | }, 453 | "python-dateutil": { 454 | "hashes": [ 455 | "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", 456 | "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a" 457 | ], 458 | "version": "==2.8.1" 459 | }, 460 | "pytz": { 461 | "hashes": [ 462 | "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed", 463 | "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048" 464 | ], 465 | "version": "==2020.1" 466 | }, 467 | "pyyaml": { 468 | "hashes": [ 469 | "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97", 470 | "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76", 471 | "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2", 472 | "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648", 473 | "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf", 474 | "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f", 475 | "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2", 476 | "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee", 477 | "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d", 478 | "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c", 479 | "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a" 480 | ], 481 | "index": "pypi", 482 | "version": "==5.3.1" 483 | }, 484 | "pyzmq": { 485 | "hashes": [ 486 | "sha256:07fb8fe6826a229dada876956590135871de60dbc7de5a18c3bcce2ed1f03c98", 487 | "sha256:13a5638ab24d628a6ade8f794195e1a1acd573496c3b85af2f1183603b7bf5e0", 488 | "sha256:15b4cb21118f4589c4db8be4ac12b21c8b4d0d42b3ee435d47f686c32fe2e91f", 489 | "sha256:21f7d91f3536f480cb2c10d0756bfa717927090b7fb863e6323f766e5461ee1c", 490 | "sha256:2a88b8fabd9cc35bd59194a7723f3122166811ece8b74018147a4ed8489e6421", 491 | "sha256:342fb8a1dddc569bc361387782e8088071593e7eaf3e3ecf7d6bd4976edff112", 492 | "sha256:4ee0bfd82077a3ff11c985369529b12853a4064320523f8e5079b630f9551448", 493 | "sha256:54aa24fd60c4262286fc64ca632f9e747c7cc3a3a1144827490e1dc9b8a3a960", 494 | "sha256:58688a2dfa044fad608a8e70ba8d019d0b872ec2acd75b7b5e37da8905605891", 495 | "sha256:5b99c2ae8089ef50223c28bac57510c163bfdff158c9e90764f812b94e69a0e6", 496 | "sha256:5b9d21fc56c8aacd2e6d14738021a9d64f3f69b30578a99325a728e38a349f85", 497 | "sha256:5f1f2eb22aab606f808163eb1d537ac9a0ba4283fbeb7a62eb48d9103cf015c2", 498 | "sha256:6ca519309703e95d55965735a667809bbb65f52beda2fdb6312385d3e7a6d234", 499 | "sha256:87c78f6936e2654397ca2979c1d323ee4a889eef536cc77a938c6b5be33351a7", 500 | "sha256:8952f6ba6ae598e792703f3134af5a01af8f5c7cf07e9a148f05a12b02412cea", 501 | "sha256:931339ac2000d12fe212e64f98ce291e81a7ec6c73b125f17cf08415b753c087", 502 | "sha256:956775444d01331c7eb412c5fb9bb62130dfaac77e09f32764ea1865234e2ca9", 503 | "sha256:97b6255ae77328d0e80593681826a0479cb7bac0ba8251b4dd882f5145a2293a", 504 | "sha256:aaa8b40b676576fd7806839a5de8e6d5d1b74981e6376d862af6c117af2a3c10", 505 | "sha256:af0c02cf49f4f9eedf38edb4f3b6bb621d83026e7e5d76eb5526cc5333782fd6", 506 | "sha256:b08780e3a55215873b3b8e6e7ca8987f14c902a24b6ac081b344fd430d6ca7cd", 507 | "sha256:ba6f24431b569aec674ede49cad197cad59571c12deed6ad8e3c596da8288217", 508 | "sha256:bafd651b557dd81d89bd5f9c678872f3e7b7255c1c751b78d520df2caac80230", 509 | "sha256:bfff5ffff051f5aa47ba3b379d87bd051c3196b0c8a603e8b7ed68a6b4f217ec", 510 | "sha256:cf5d689ba9513b9753959164cf500079383bc18859f58bf8ce06d8d4bef2b054", 511 | "sha256:dcbc3f30c11c60d709c30a213dc56e88ac016fe76ac6768e64717bd976072566", 512 | "sha256:f9d7e742fb0196992477415bb34366c12e9bb9a0699b8b3f221ff93b213d7bec", 513 | "sha256:faee2604f279d31312bc455f3d024f160b6168b9c1dde22bf62d8c88a4deca8e" 514 | ], 515 | "version": "==19.0.1" 516 | }, 517 | "qtconsole": { 518 | "hashes": [ 519 | "sha256:4f43d0b049eacb7d723772847f0c465feccce0ccb398871a6e146001a22bad23", 520 | "sha256:f5cb275d30fc8085e2d1d18bc363e5ba0ce6e559bf37d7d6727b773134298754" 521 | ], 522 | "version": "==4.7.5" 523 | }, 524 | "qtpy": { 525 | "hashes": [ 526 | "sha256:2db72c44b55d0fe1407be8fba35c838ad0d6d3bb81f23007886dc1fc0f459c8d", 527 | "sha256:fa0b8363b363e89b2a6f49eddc162a04c0699ae95e109a6be3bb145a913190ea" 528 | ], 529 | "version": "==1.9.0" 530 | }, 531 | "regex": { 532 | "hashes": [ 533 | "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a", 534 | "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938", 535 | "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29", 536 | "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae", 537 | "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387", 538 | "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a", 539 | "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf", 540 | "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610", 541 | "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9", 542 | "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5", 543 | "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3", 544 | "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89", 545 | "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded", 546 | "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754", 547 | "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f", 548 | "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868", 549 | "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd", 550 | "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910", 551 | "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3", 552 | "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac", 553 | "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c" 554 | ], 555 | "version": "==2020.6.8" 556 | }, 557 | "requests": { 558 | "hashes": [ 559 | "sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b", 560 | "sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898" 561 | ], 562 | "version": "==2.24.0" 563 | }, 564 | "send2trash": { 565 | "hashes": [ 566 | "sha256:522b8f5774aafc63d97703b357316220fff78ac7fcc004f37ef500fdb205892a", 567 | "sha256:c9bd4195a93b5310149e06f246bd41dfdd13c67353fd767d6955af452d4ac16a" 568 | ], 569 | "version": "==1.6.0b1" 570 | }, 571 | "six": { 572 | "hashes": [ 573 | "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", 574 | "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" 575 | ], 576 | "version": "==1.15.0" 577 | }, 578 | "snowballstemmer": { 579 | "hashes": [ 580 | "sha256:209f257d7533fdb3cb73bdbd24f436239ca3b2fa67d56f6ff88e86be08cc5ef0", 581 | "sha256:df3bac3df4c2c01363f3dd2cfa78cce2840a79b9f1c2d2de9ce8d31683992f52" 582 | ], 583 | "version": "==2.0.0" 584 | }, 585 | "sphinx": { 586 | "hashes": [ 587 | "sha256:b4c750d546ab6d7e05bdff6ac24db8ae3e8b8253a3569b754e445110a0a12b66", 588 | "sha256:fc312670b56cb54920d6cc2ced455a22a547910de10b3142276495ced49231cb" 589 | ], 590 | "version": "==2.4.4" 591 | }, 592 | "sphinxcontrib-applehelp": { 593 | "hashes": [ 594 | "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a", 595 | "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58" 596 | ], 597 | "version": "==1.0.2" 598 | }, 599 | "sphinxcontrib-devhelp": { 600 | "hashes": [ 601 | "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e", 602 | "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4" 603 | ], 604 | "version": "==1.0.2" 605 | }, 606 | "sphinxcontrib-htmlhelp": { 607 | "hashes": [ 608 | "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f", 609 | "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b" 610 | ], 611 | "version": "==1.0.3" 612 | }, 613 | "sphinxcontrib-jsmath": { 614 | "hashes": [ 615 | "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", 616 | "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8" 617 | ], 618 | "version": "==1.0.1" 619 | }, 620 | "sphinxcontrib-qthelp": { 621 | "hashes": [ 622 | "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72", 623 | "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6" 624 | ], 625 | "version": "==1.0.3" 626 | }, 627 | "sphinxcontrib-serializinghtml": { 628 | "hashes": [ 629 | "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc", 630 | "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a" 631 | ], 632 | "version": "==1.1.4" 633 | }, 634 | "terminado": { 635 | "hashes": [ 636 | "sha256:4804a774f802306a7d9af7322193c5390f1da0abb429e082a10ef1d46e6fb2c2", 637 | "sha256:a43dcb3e353bc680dd0783b1d9c3fc28d529f190bc54ba9a229f72fe6e7a54d7" 638 | ], 639 | "version": "==0.8.3" 640 | }, 641 | "testpath": { 642 | "hashes": [ 643 | "sha256:60e0a3261c149755f4399a1fff7d37523179a70fdc3abdf78de9fc2604aeec7e", 644 | "sha256:bfcf9411ef4bf3db7579063e0546938b1edda3d69f4e1fb8756991f5951f85d4" 645 | ], 646 | "version": "==0.4.4" 647 | }, 648 | "toml": { 649 | "hashes": [ 650 | "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", 651 | "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" 652 | ], 653 | "version": "==0.10.1" 654 | }, 655 | "tornado": { 656 | "hashes": [ 657 | "sha256:0fe2d45ba43b00a41cd73f8be321a44936dc1aba233dee979f17a042b83eb6dc", 658 | "sha256:22aed82c2ea340c3771e3babc5ef220272f6fd06b5108a53b4976d0d722bcd52", 659 | "sha256:2c027eb2a393d964b22b5c154d1a23a5f8727db6fda837118a776b29e2b8ebc6", 660 | "sha256:5217e601700f24e966ddab689f90b7ea4bd91ff3357c3600fa1045e26d68e55d", 661 | "sha256:5618f72e947533832cbc3dec54e1dffc1747a5cb17d1fd91577ed14fa0dc081b", 662 | "sha256:5f6a07e62e799be5d2330e68d808c8ac41d4a259b9cea61da4101b83cb5dc673", 663 | "sha256:c58d56003daf1b616336781b26d184023ea4af13ae143d9dda65e31e534940b9", 664 | "sha256:c952975c8ba74f546ae6de2e226ab3cc3cc11ae47baf607459a6728585bb542a", 665 | "sha256:c98232a3ac391f5faea6821b53db8db461157baa788f5d6222a193e9456e1740" 666 | ], 667 | "version": "==6.0.4" 668 | }, 669 | "traitlets": { 670 | "hashes": [ 671 | "sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44", 672 | "sha256:d023ee369ddd2763310e4c3eae1ff649689440d4ae59d7485eb4cfbbe3e359f7" 673 | ], 674 | "version": "==4.3.3" 675 | }, 676 | "typed-ast": { 677 | "hashes": [ 678 | "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", 679 | "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", 680 | "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", 681 | "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", 682 | "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", 683 | "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", 684 | "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", 685 | "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", 686 | "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", 687 | "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", 688 | "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", 689 | "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", 690 | "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", 691 | "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", 692 | "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", 693 | "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", 694 | "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", 695 | "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", 696 | "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", 697 | "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", 698 | "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" 699 | ], 700 | "version": "==1.4.1" 701 | }, 702 | "urllib3": { 703 | "hashes": [ 704 | "sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527", 705 | "sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115" 706 | ], 707 | "version": "==1.25.9" 708 | }, 709 | "wcwidth": { 710 | "hashes": [ 711 | "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", 712 | "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" 713 | ], 714 | "version": "==0.2.5" 715 | }, 716 | "webencodings": { 717 | "hashes": [ 718 | "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", 719 | "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" 720 | ], 721 | "version": "==0.5.1" 722 | }, 723 | "widgetsnbextension": { 724 | "hashes": [ 725 | "sha256:cb6181b4037da02deeabab39d5cb1113a7390aee7468b1f8237c2abbd6df6107", 726 | "sha256:fee3b6ec261393db5b4ec7c4fc96bf85c146cc6e5f38069c27d54fb7892bbb15" 727 | ], 728 | "version": "==4.0.0a0" 729 | } 730 | }, 731 | "develop": { 732 | "appdirs": { 733 | "hashes": [ 734 | "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", 735 | "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" 736 | ], 737 | "version": "==1.4.4" 738 | }, 739 | "astroid": { 740 | "hashes": [ 741 | "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", 742 | "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" 743 | ], 744 | "version": "==2.4.2" 745 | }, 746 | "attrs": { 747 | "hashes": [ 748 | "sha256:08a96c641c3a74e44eb59afb61a24f2cb9f4d7188748e76ba4bb5edfa3cb7d1c", 749 | "sha256:f7b7ce16570fe9965acd6d30101a28f62fb4a7f9e926b3bbc9b61f8b04247e72" 750 | ], 751 | "version": "==19.3.0" 752 | }, 753 | "black": { 754 | "hashes": [ 755 | "sha256:1b30e59be925fafc1ee4565e5e08abef6b03fe455102883820fe5ee2e4734e0b", 756 | "sha256:c2edb73a08e9e0e6f65a0e6af18b059b8b1cdd5bef997d7a0b181df93dc81539" 757 | ], 758 | "index": "pypi", 759 | "version": "==19.10b0" 760 | }, 761 | "click": { 762 | "hashes": [ 763 | "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a", 764 | "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc" 765 | ], 766 | "version": "==7.1.2" 767 | }, 768 | "flake8": { 769 | "hashes": [ 770 | "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c", 771 | "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208" 772 | ], 773 | "index": "pypi", 774 | "version": "==3.8.3" 775 | }, 776 | "isort": { 777 | "hashes": [ 778 | "sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1", 779 | "sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd" 780 | ], 781 | "version": "==4.3.21" 782 | }, 783 | "lazy-object-proxy": { 784 | "hashes": [ 785 | "sha256:0c4b206227a8097f05c4dbdd323c50edf81f15db3b8dc064d08c62d37e1a504d", 786 | "sha256:194d092e6f246b906e8f70884e620e459fc54db3259e60cf69a4d66c3fda3449", 787 | "sha256:1be7e4c9f96948003609aa6c974ae59830a6baecc5376c25c92d7d697e684c08", 788 | "sha256:4677f594e474c91da97f489fea5b7daa17b5517190899cf213697e48d3902f5a", 789 | "sha256:48dab84ebd4831077b150572aec802f303117c8cc5c871e182447281ebf3ac50", 790 | "sha256:5541cada25cd173702dbd99f8e22434105456314462326f06dba3e180f203dfd", 791 | "sha256:59f79fef100b09564bc2df42ea2d8d21a64fdcda64979c0fa3db7bdaabaf6239", 792 | "sha256:8d859b89baf8ef7f8bc6b00aa20316483d67f0b1cbf422f5b4dc56701c8f2ffb", 793 | "sha256:9254f4358b9b541e3441b007a0ea0764b9d056afdeafc1a5569eee1cc6c1b9ea", 794 | "sha256:9651375199045a358eb6741df3e02a651e0330be090b3bc79f6d0de31a80ec3e", 795 | "sha256:97bb5884f6f1cdce0099f86b907aa41c970c3c672ac8b9c8352789e103cf3156", 796 | "sha256:9b15f3f4c0f35727d3a0fba4b770b3c4ebbb1fa907dbcc046a1d2799f3edd142", 797 | "sha256:a2238e9d1bb71a56cd710611a1614d1194dc10a175c1e08d75e1a7bcc250d442", 798 | "sha256:a6ae12d08c0bf9909ce12385803a543bfe99b95fe01e752536a60af2b7797c62", 799 | "sha256:ca0a928a3ddbc5725be2dd1cf895ec0a254798915fb3a36af0964a0a4149e3db", 800 | "sha256:cb2c7c57005a6804ab66f106ceb8482da55f5314b7fcb06551db1edae4ad1531", 801 | "sha256:d74bb8693bf9cf75ac3b47a54d716bbb1a92648d5f781fc799347cfc95952383", 802 | "sha256:d945239a5639b3ff35b70a88c5f2f491913eb94871780ebfabb2568bd58afc5a", 803 | "sha256:eba7011090323c1dadf18b3b689845fd96a61ba0a1dfbd7f24b921398affc357", 804 | "sha256:efa1909120ce98bbb3777e8b6f92237f5d5c8ea6758efea36a473e1d38f7d3e4", 805 | "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0" 806 | ], 807 | "version": "==1.4.3" 808 | }, 809 | "mccabe": { 810 | "hashes": [ 811 | "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42", 812 | "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f" 813 | ], 814 | "version": "==0.6.1" 815 | }, 816 | "more-itertools": { 817 | "hashes": [ 818 | "sha256:68c70cc7167bdf5c7c9d8f6954a7837089c6a36bf565383919bb595efb8a17e5", 819 | "sha256:b78134b2063dd214000685165d81c154522c3ee0a1c0d4d113c80361c234c5a2" 820 | ], 821 | "version": "==8.4.0" 822 | }, 823 | "packaging": { 824 | "hashes": [ 825 | "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8", 826 | "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181" 827 | ], 828 | "version": "==20.4" 829 | }, 830 | "pathspec": { 831 | "hashes": [ 832 | "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0", 833 | "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061" 834 | ], 835 | "version": "==0.8.0" 836 | }, 837 | "pluggy": { 838 | "hashes": [ 839 | "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0", 840 | "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d" 841 | ], 842 | "version": "==0.13.1" 843 | }, 844 | "py": { 845 | "hashes": [ 846 | "sha256:366389d1db726cd2fcfc79732e75410e5fe4d31db13692115529d34069a043c2", 847 | "sha256:9ca6883ce56b4e8da7e79ac18787889fa5206c79dcc67fb065376cd2fe03f342" 848 | ], 849 | "version": "==1.9.0" 850 | }, 851 | "pycodestyle": { 852 | "hashes": [ 853 | "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367", 854 | "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e" 855 | ], 856 | "version": "==2.6.0" 857 | }, 858 | "pyflakes": { 859 | "hashes": [ 860 | "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92", 861 | "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8" 862 | ], 863 | "version": "==2.2.0" 864 | }, 865 | "pylint": { 866 | "hashes": [ 867 | "sha256:7dd78437f2d8d019717dbf287772d0b2dbdfd13fc016aa7faa08d67bccc46adc", 868 | "sha256:d0ece7d223fe422088b0e8f13fa0a1e8eb745ebffcb8ed53d3e95394b6101a1c" 869 | ], 870 | "index": "pypi", 871 | "version": "==2.5.3" 872 | }, 873 | "pyparsing": { 874 | "hashes": [ 875 | "sha256:1060635ca5ac864c2b7bc7b05a448df4e32d7d8c65e33cbe1514810d339672a2", 876 | "sha256:56a551039101858c9e189ac9e66e330a03fb7079e97ba6b50193643905f450ce" 877 | ], 878 | "version": "==3.0.0a2" 879 | }, 880 | "pytest": { 881 | "hashes": [ 882 | "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1", 883 | "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8" 884 | ], 885 | "index": "pypi", 886 | "version": "==5.4.3" 887 | }, 888 | "regex": { 889 | "hashes": [ 890 | "sha256:08997a37b221a3e27d68ffb601e45abfb0093d39ee770e4257bd2f5115e8cb0a", 891 | "sha256:112e34adf95e45158c597feea65d06a8124898bdeac975c9087fe71b572bd938", 892 | "sha256:1700419d8a18c26ff396b3b06ace315b5f2a6e780dad387e4c48717a12a22c29", 893 | "sha256:2f6f211633ee8d3f7706953e9d3edc7ce63a1d6aad0be5dcee1ece127eea13ae", 894 | "sha256:52e1b4bef02f4040b2fd547357a170fc1146e60ab310cdbdd098db86e929b387", 895 | "sha256:55b4c25cbb3b29f8d5e63aeed27b49fa0f8476b0d4e1b3171d85db891938cc3a", 896 | "sha256:5aaa5928b039ae440d775acea11d01e42ff26e1561c0ffcd3d805750973c6baf", 897 | "sha256:654cb773b2792e50151f0e22be0f2b6e1c3a04c5328ff1d9d59c0398d37ef610", 898 | "sha256:690f858d9a94d903cf5cada62ce069b5d93b313d7d05456dbcd99420856562d9", 899 | "sha256:6ad8663c17db4c5ef438141f99e291c4d4edfeaacc0ce28b5bba2b0bf273d9b5", 900 | "sha256:89cda1a5d3e33ec9e231ece7307afc101b5217523d55ef4dc7fb2abd6de71ba3", 901 | "sha256:92d8a043a4241a710c1cf7593f5577fbb832cf6c3a00ff3fc1ff2052aff5dd89", 902 | "sha256:95fa7726d073c87141f7bbfb04c284901f8328e2d430eeb71b8ffdd5742a5ded", 903 | "sha256:97712e0d0af05febd8ab63d2ef0ab2d0cd9deddf4476f7aa153f76feef4b2754", 904 | "sha256:b2ba0f78b3ef375114856cbdaa30559914d081c416b431f2437f83ce4f8b7f2f", 905 | "sha256:bae83f2a56ab30d5353b47f9b2a33e4aac4de9401fb582b55c42b132a8ac3868", 906 | "sha256:c78e66a922de1c95a208e4ec02e2e5cf0bb83a36ceececc10a72841e53fbf2bd", 907 | "sha256:cf59bbf282b627130f5ba68b7fa3abdb96372b24b66bdf72a4920e8153fc7910", 908 | "sha256:e3cdc9423808f7e1bb9c2e0bdb1c9dc37b0607b30d646ff6faf0d4e41ee8fee3", 909 | "sha256:e9b64e609d37438f7d6e68c2546d2cb8062f3adb27e6336bc129b51be20773ac", 910 | "sha256:fbff901c54c22425a5b809b914a3bfaf4b9570eee0e5ce8186ac71eb2025191c" 911 | ], 912 | "version": "==2020.6.8" 913 | }, 914 | "six": { 915 | "hashes": [ 916 | "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259", 917 | "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced" 918 | ], 919 | "version": "==1.15.0" 920 | }, 921 | "toml": { 922 | "hashes": [ 923 | "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f", 924 | "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88" 925 | ], 926 | "version": "==0.10.1" 927 | }, 928 | "typed-ast": { 929 | "hashes": [ 930 | "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355", 931 | "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919", 932 | "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa", 933 | "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652", 934 | "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75", 935 | "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01", 936 | "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d", 937 | "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1", 938 | "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907", 939 | "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c", 940 | "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3", 941 | "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b", 942 | "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614", 943 | "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb", 944 | "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b", 945 | "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41", 946 | "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6", 947 | "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34", 948 | "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe", 949 | "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4", 950 | "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7" 951 | ], 952 | "version": "==1.4.1" 953 | }, 954 | "wcwidth": { 955 | "hashes": [ 956 | "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", 957 | "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" 958 | ], 959 | "version": "==0.2.5" 960 | }, 961 | "wrapt": { 962 | "hashes": [ 963 | "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7" 964 | ], 965 | "version": "==1.12.1" 966 | } 967 | } 968 | } 969 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | TODO: publish to pip 4 | 5 | `pip install mystify` 6 | 7 | ### Human readable, diffable and reviewable notebook format 8 | 9 | The Myst `ContentManager` provides you with a way to save notebooks in a format that's easier to operate with git. 10 | 11 | To do so, first generate the jupyter config file following the directions [here](https://jupyter-notebook.readthedocs.io/en/stable/config.html#config-file-and-command-line-options) - `jupyter notebook --generate-config` 12 | 13 | To enable the content manager, then add the following line to your `jupyter_notebook_config.py` 14 | 15 | ``` 16 | c.NotebookApp.contents_manager_class = 'mystify.myst_contents_manager.MystContentsManager' 17 | ``` 18 | 19 | To convert your existing notebooks into `mystify` format use `jupyter nbconvert` tool. 20 | 21 | ``` 22 | jupyter nbconvert --to mystify your_notebook.ipynb 23 | ``` 24 | -------------------------------------------------------------------------------- /build_package.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | pipenv shell 3 | pipenv install 4 | pipenv lock -r > requirement.txt 5 | git add . 6 | git commit -a -m 'updating requirements before building package' 7 | git push 8 | python3 -m pip install --upgrade setuptools wheel 9 | rm -rf dist/ 10 | python3 setup.py sdist bdist_wheel 11 | python3 -m pip install --upgrade twine 12 | python3 -m twine upload dist/* -------------------------------------------------------------------------------- /examples/example_notebook.html: -------------------------------------------------------------------------------- 1 |
2 |

kernelspec: 3 | display_name: Python 3 4 | language: python 5 | name: python3 6 | language_info: 7 | codemirror_mode: 8 | name: ipython 9 | version: 3 10 | file_extension: .py 11 | mimetype: text/x-python 12 | name: python 13 | nbconvert_exporter: python 14 | pygments_lexer: ipython3 15 | version: 3.7.7

16 |
17 |

cell_type: code 18 | execution_count: 1

19 |
print("fbddddoo")
20 | 
21 |

foo

22 |
23 |

cell_type: markdown

24 |

testtest

25 |

test of markdown2

26 |
27 |

cell_type: code 28 | execution_count: 1

29 |
import numpy as np
30 | import matplotlib.pyplot as plt
31 | 
32 | 
33 | N = 5
34 | menMeans = (20, 35, 30, 35, 27)
35 | womenMeans = (25, 32, 34, 20, 25)
36 | menStd = (2, 3, 4, 1, 2)
37 | womenStd = (3, 5, 2, 3, 3)
38 | ind = np.arange(N)    # the x locations for the groups
39 | width = 0.35       # the width of the bars: can also be len(x) sequence
40 | 
41 | p1 = plt.bar(ind, menMeans, width, yerr=menStd)
42 | p2 = plt.bar(ind, womenMeans, width,
43 |              bottom=menMeans, yerr=womenStd)
44 | 
45 | plt.ylabel('Scores')
46 | plt.title('Scores by group and gender')
47 | plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
48 | plt.yticks(np.arange(0, 81, 10))
49 | plt.legend((p1[0], p2[0]), ('Men', 'Women'))
50 | 
51 | plt.show()
52 | 
53 | -------------------------------------------------------------------------------- /examples/example_notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "foo\n" 13 | ] 14 | } 15 | ], 16 | "source": [ 17 | "print(\"foo\")" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "testtest\n", 25 | "---------\n", 26 | "\n", 27 | "*test*\n", 28 | "\n", 29 | "of markdown" 30 | ] 31 | } 32 | ], 33 | "metadata": { 34 | "kernelspec": { 35 | "display_name": "Python 3", 36 | "language": "python", 37 | "name": "python3" 38 | }, 39 | "language_info": { 40 | "codemirror_mode": { 41 | "name": "ipython", 42 | "version": 3 43 | }, 44 | "file_extension": ".py", 45 | "mimetype": "text/x-python", 46 | "name": "python", 47 | "nbconvert_exporter": "python", 48 | "pygments_lexer": "ipython3", 49 | "version": "3.7.7" 50 | } 51 | }, 52 | "nbformat": 4, 53 | "nbformat_minor": 4 54 | } 55 | -------------------------------------------------------------------------------- /examples/example_notebook.mystnb: -------------------------------------------------------------------------------- 1 | ```{metadata} 2 | --- 3 | nbformat_minor: 4 4 | nbformat: 4 5 | metadata: 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | language_info: 11 | codemirror_mode: 12 | name: ipython 13 | version: 3 14 | file_extension: .py 15 | mimetype: text/x-python 16 | name: python 17 | nbconvert_exporter: python 18 | pygments_lexer: ipython3 19 | version: 3.7.7 20 | ``` 21 | % cell 22 | ```{cell_meta} 23 | --- 24 | cell_type: code 25 | execution_count: 1 26 | ``` 27 | ```{source} 28 | print("foo") 29 | ``` 30 | ```{output} stream 31 | foo 32 | ``` 33 | % endcell 34 | % cell 35 | ```{cell_meta} 36 | --- 37 | cell_type: markdown 38 | ``` 39 | ```{source} 40 | testtest 41 | --------- 42 | 43 | *test* 44 | 45 | of markdown 46 | ``` 47 | % endcell 48 | 49 | -------------------------------------------------------------------------------- /examples/render_file.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from myst_parser.main import to_html 3 | 4 | 5 | infile = sys.argv[1] 6 | outfile = sys.argv[2] 7 | 8 | with open(infile, "r") as inf: 9 | content = inf.read() 10 | 11 | outf = to_html(content) 12 | 13 | with open(outfile, "w") as out: 14 | out.write(outf) 15 | -------------------------------------------------------------------------------- /mystify/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machine-learning-apps/mystify/38438de38daaf59620a9d6ae6895f8fa79041e40/mystify/__init__.py -------------------------------------------------------------------------------- /mystify/convert.py: -------------------------------------------------------------------------------- 1 | import json 2 | import yaml 3 | import re 4 | from myst_parser.main import default_parser 5 | 6 | 7 | def to_myst(model: str) -> str: 8 | myst_file = "" 9 | model_dict = json.loads(model) 10 | for key in model_dict: 11 | if key == "cells": 12 | myst_file = _handle_cells(model_dict[key]) 13 | elif key == "metadata": 14 | myst_file = _handle_metadata(model_dict[key]) 15 | elif key == "nbformat": 16 | myst_file = _handle_nbformat(model_dict[key]) 17 | elif key == "nbformat_minor": 18 | myst_file = _handle_nbformat_minor(model_dict[key]) 19 | else: 20 | raise ValueError("Attempting to parse unknown type.") 21 | 22 | return myst_file 23 | 24 | 25 | def _handle_cells(cell_nodes: list) -> str: 26 | """ 27 | Cells can be nested: 28 | cells (list) 29 | { 30 | "metadata" : { 31 | "kernel_info": { 32 | # if kernel_info is defined, its name field is required. 33 | "name" : "the name of the kernel" 34 | }, 35 | "language_info": { 36 | # if language_info is defined, its name field is required. 37 | "name" : "the programming language of the kernel", 38 | "version": "the version of the language", 39 | "codemirror_mode": "The name of the codemirror mode to use [optional]" 40 | } 41 | }, 42 | "nbformat": 4, 43 | "nbformat_minor": 0, 44 | "cells" : [ 45 | # list of cell dictionaries, see below 46 | ], 47 | } 48 | """ 49 | pass 50 | 51 | 52 | def _handle_metadata(metadata_nodes: dict) -> str: 53 | """ 54 | metadata (dict) 55 | "metadata" : { 56 | "kernel_info": { 57 | # if kernel_info is defined, its name field is required. 58 | "name" : "the name of the kernel" 59 | }, 60 | "language_info": { 61 | # if language_info is defined, its name field is required. 62 | "name" : "the programming language of the kernel", 63 | "version": "the version of the language", 64 | "codemirror_mode": "The name of the codemirror mode to use [optional]" 65 | } 66 | }, 67 | 68 | """ 69 | pass 70 | 71 | 72 | def _handle_nbformat(nbformat: int) -> str: 73 | """ 74 | "nbformat" (int) 75 | """ 76 | pass 77 | 78 | 79 | def _handle_nbformat_minor(nbformat_minor: int) -> str: 80 | """ 81 | "nbformat_minor" (int) 82 | """ 83 | pass 84 | 85 | 86 | def _parse_code_output(cell_section): 87 | out = {} 88 | out["output_type"] = cell_section.info.split(" ")[1] 89 | if out["output_type"] == "stream": 90 | out["text"] = cell_section.content.splitlines(True) 91 | out["name"] = "stdout" 92 | return out 93 | 94 | 95 | def _parse_cell(cell): 96 | cell_meta = yaml.safe_load(cell[0].content) 97 | if "metadata" not in cell_meta: 98 | cell_meta["metadata"] = {} 99 | for cell_section in cell[1:]: 100 | if cell_section.info == "{source}": 101 | cell_meta["source"] = cell_section.content.splitlines(True) 102 | cell_meta["source"][-1] = cell_meta["source"][-1].strip() 103 | if cell_section.info.startswith("{output}"): 104 | out = _parse_code_output(cell_section) 105 | if "outputs" not in cell_meta: 106 | cell_meta["outputs"] = [] 107 | cell_meta["outputs"].append(out) 108 | return cell_meta 109 | 110 | 111 | def _split_sections(tokens): 112 | append_to_cell = None 113 | sections = {} 114 | for token in tokens: 115 | if token.type == "fence" and token.info == "{metadata}": 116 | # Metadata yaml block 117 | sections = yaml.safe_load(token.content) 118 | sections["cells"] = [] 119 | if append_to_cell is not None: 120 | append_to_cell.append(token) 121 | if token.type == "myst_line_comment" and token.content == "cell": 122 | append_to_cell = [] 123 | if token.type == "myst_line_comment" and token.content == "endcell": 124 | sections["cells"].append(_parse_cell(append_to_cell)) 125 | append_to_cell = None 126 | return sections 127 | 128 | 129 | def to_model(myst): 130 | md = default_parser("docutils") 131 | tokens = md.parse(myst) 132 | sections = _split_sections(tokens) 133 | return sections 134 | 135 | 136 | """ 137 | Some fields, such as code input and text output, are characteristically multi-line strings. When these fields are written to disk, they may be written as a list of strings, which should be joined with '' when reading back into memory. In programmatic APIs for working with notebooks (Python, Javascript), these are always re-joined into the original multi-line string. If you intend to work with notebook files directly, you must allow multi-line string fields to be either a string or list of strings. 138 | 139 | Cell Types 140 | There are a few basic cell types for encapsulating code and text. All cells have the following basic structure: 141 | 142 | { 143 | "cell_type" : "type", 144 | "metadata" : {}, 145 | "source" : "single string or [list, of, strings]", 146 | } 147 | Note 148 | 149 | On disk, multi-line strings MAY be split into lists of strings. When read with the nbformat Python API, these multi-line strings will always be a single string. 150 | 151 | Markdown cells 152 | Markdown cells are used for body-text, and contain markdown, as defined in GitHub-flavored markdown, and implemented in marked. 153 | 154 | { 155 | "cell_type" : "markdown", 156 | "metadata" : {}, 157 | "source" : "[multi-line *markdown*]", 158 | } 159 | Changed in version nbformat: 4.0 160 | 161 | Heading cells have been removed in favor of simple headings in markdown. 162 | 163 | Code cells 164 | Code cells are the primary content of Jupyter notebooks. They contain source code in the language of the document’s associated kernel, and a list of outputs associated with executing that code. They also have an execution_count, which must be an integer or null. 165 | 166 | { 167 | "cell_type" : "code", 168 | "execution_count": 1, # integer or null 169 | "metadata" : { 170 | "collapsed" : True, # whether the output of the cell is collapsed 171 | "scrolled": False, # any of true, false or "auto" 172 | }, 173 | "source" : "[some multi-line code]", 174 | "outputs": [{ 175 | # list of output dicts (described below) 176 | "output_type": "stream", 177 | ... 178 | }], 179 | } 180 | Changed in version nbformat: 4.0 181 | 182 | input was renamed to source, for consistency among cell types. 183 | 184 | Changed in version nbformat: 4.0 185 | 186 | prompt_number renamed to execution_count 187 | 188 | Code cell outputs 189 | A code cell can have a variety of outputs (stream data or rich mime-type output). These correspond to messages produced as a result of executing the cell. 190 | 191 | All outputs have an output_type field, which is a string defining what type of output it is. 192 | 193 | stream output 194 | { 195 | "output_type" : "stream", 196 | "name" : "stdout", # or stderr 197 | "text" : "[multiline stream text]", 198 | } 199 | Changed in version nbformat: 4.0 200 | 201 | The stream key was changed to name to match the stream message. 202 | 203 | display_data 204 | Rich display outputs, as created by display_data messages, contain data keyed by mime-type. This is often called a mime-bundle, and shows up in various locations in the notebook format and message spec. The metadata of these messages may be keyed by mime-type as well. 205 | 206 | { 207 | "output_type" : "display_data", 208 | "data" : { 209 | "text/plain" : "[multiline text data]", 210 | "image/png": "[base64-encoded-multiline-png-data]", 211 | "application/json": { 212 | # JSON data is included as-is 213 | "key1": "data", 214 | "key2": ["some", "values"], 215 | "key3": {"more": "data"} 216 | }, 217 | "application/vnd.exampleorg.type+json": { 218 | # JSON data, included as-is, when the mime-type key ends in +json 219 | "key1": "data", 220 | "key2": ["some", "values"], 221 | "key3": {"more": "data"} 222 | } 223 | }, 224 | "metadata" : { 225 | "image/png": { 226 | "width": 640, 227 | "height": 480, 228 | }, 229 | }, 230 | } 231 | Changed in version nbformat: 4.0 232 | 233 | application/json output is no longer double-serialized into a string. 234 | 235 | Changed in version nbformat: 4.0 236 | 237 | mime-types are used for keys, instead of a combination of short names (text) and mime-types, and are stored in a data key, rather than the top-level. i.e. output.data['image/png'] instead of output.png. 238 | 239 | execute_result 240 | Results of executing a cell (as created by displayhook in Python) are stored in execute_result outputs. execute_result outputs are identical to display_data, adding only a execution_count field, which must be an integer. 241 | 242 | { 243 | "output_type" : "execute_result", 244 | "execution_count": 42, 245 | "data" : { 246 | "text/plain" : "[multiline text data]", 247 | "image/png": "[base64-encoded-multiline-png-data]", 248 | "application/json": { 249 | # JSON data is included as-is 250 | "json": "data", 251 | }, 252 | }, 253 | "metadata" : { 254 | "image/png": { 255 | "width": 640, 256 | "height": 480, 257 | }, 258 | }, 259 | } 260 | Changed in version nbformat: 4.0 261 | 262 | pyout renamed to execute_result 263 | 264 | Changed in version nbformat: 4.0 265 | 266 | prompt_number renamed to execution_count 267 | 268 | error 269 | Failed execution may show a traceback 270 | 271 | { 272 | 'output_type': 'error', 273 | 'ename' : str, # Exception name, as a string 274 | 'evalue' : str, # Exception value, as a string 275 | 276 | # The traceback will contain a list of frames, 277 | # represented each as a string. 278 | 'traceback' : list, 279 | } 280 | Changed in version nbformat: 4.0 281 | 282 | pyerr renamed to error 283 | 284 | Raw NBConvert cells 285 | A raw cell is defined as content that should be included unmodified in nbconvert output. For example, this cell could include raw LaTeX for nbconvert to pdf via latex, or restructured text for use in Sphinx documentation. 286 | 287 | The notebook authoring environment does not render raw cells. 288 | 289 | The only logic in a raw cell is the format metadata field. If defined, it specifies which nbconvert output format is the intended target for the raw cell. When outputting to any other format, the raw cell’s contents will be excluded. In the default case when this value is undefined, a raw cell’s contents will be included in any nbconvert output, regardless of format. 290 | 291 | { 292 | "cell_type" : "raw", 293 | "metadata" : { 294 | # the mime-type of the target nbconvert format. 295 | # nbconvert to formats other than this will exclude this cell. 296 | "format" : "mime/type" 297 | }, 298 | "source" : "[some nbformat output text]" 299 | } 300 | Cell attachments 301 | Markdown and raw cells can have a number of attachments, typically inline images that can be referenced in the markdown content of a cell. The attachments dictionary of a cell contains a set of mime-bundles (see display_data) keyed by filename that represents the files attached to the cell. 302 | 303 | Note 304 | 305 | The attachments dictionary is an optional field and can be undefined or empty if the cell does not have any attachments. 306 | 307 | { 308 | "cell_type" : "markdown", 309 | "metadata" : {}, 310 | "source" : ["Here is an *inline* image ![inline image](attachment:test.png)"], 311 | "attachments" : { 312 | "test.png": { 313 | "image/png" : "base64-encoded-png-data" 314 | } 315 | } 316 | } 317 | Backward-compatible changes 318 | The notebook format is an evolving format. When backward-compatible changes are made, the notebook format minor version is incremented. When backward-incompatible changes are made, the major version is incremented. 319 | 320 | As of nbformat 4.x, backward-compatible changes include: 321 | 322 | new fields in any dictionary (notebook, cell, output, metadata, etc.) 323 | new cell types 324 | new output types 325 | New cell or output types will not be rendered in versions that do not recognize them, but they will be preserved. 326 | 327 | Because the nbformat python package used to be less strict about validating notebook files, two features have been backported from nbformat 4.x to nbformat 4.0. These are: 328 | 329 | attachment top-level keys in the Markdown and raw cell types (backported from nbformat 4.1) 330 | Mime-bundle attributes are JSON data if the mime-type key ends in +json (backported from nbformat 4.2) 331 | These backports ensure that any valid nbformat 4.4 file is also a valid nbformat 4.0 file. 332 | 333 | Metadata 334 | Metadata is a place that you can put arbitrary JSONable information about your notebook, cell, or output. Because it is a shared namespace, any custom metadata should use a sufficiently unique namespace, such as metadata.kaylees_md.foo = “bar”. 335 | 336 | Metadata fields officially defined for Jupyter notebooks are listed here: 337 | 338 | Notebook metadata 339 | The following metadata keys are defined at the notebook level: 340 | 341 | Key Value Interpretation 342 | kernelspec dict A kernel specification 343 | authors list of dicts A list of authors of the document 344 | A notebook’s authors is a list of dictionaries containing information about each author of the notebook. Currently, only the name is required. Additional fields may be added. 345 | 346 | nb.metadata.authors = [ 347 | { 348 | 'name': 'Fernando Perez', 349 | }, 350 | { 351 | 'name': 'Brian Granger', 352 | }, 353 | ] 354 | Cell metadata 355 | Official Jupyter metadata, as used by Jupyter frontends should be placed in the metadata.jupyter namespace, for example metadata.jupyter.foo = “bar”. 356 | 357 | The following metadata keys are defined at the cell level: 358 | 359 | Key Value Interpretation 360 | collapsed bool Whether the cell’s output container should be collapsed 361 | scrolled bool or ‘auto’ Whether the cell’s output is scrolled, unscrolled, or autoscrolled 362 | deletable bool If False, prevent deletion of the cell 363 | editable bool If False, prevent editing of the cell (by definition, this also prevents deleting the cell) 364 | format ‘mime/type’ The mime-type of a Raw NBConvert Cell 365 | name str A name for the cell. Should be unique across the notebook. Uniqueness must be verified outside of the json schema. 366 | tags list of str A list of string tags on the cell. Commas are not allowed in a tag 367 | jupyter dict A namespace holding jupyter specific fields. See docs below for more details 368 | execution dict A namespace holding execution specific fields. See docs below for more details 369 | The following metadata keys are defined at the cell level within the jupyter namespace 370 | 371 | Key Value Interpretation 372 | source_hidden bool Whether the cell’s source should be shown 373 | outputs_hidden bool Whether the cell’s outputs should be shown 374 | The following metadata keys are defined at the cell level within the execution namespace. These are lower level fields capturing common kernel message timestamps for better visibility in applications where needed. Most users will not look at these directly. 375 | 376 | Key Value Interpretation 377 | iopub.execute_input ISO 8601 format Indicates the time at which the kernel broadcasts an execute_input message. This represents the time when request for work was received by the kernel. 378 | iopub.status.busy ISO 8601 format Indicates the time at which the iopub channel’s kernel status message is ‘busy’. This represents the time when work was started by the kernel. 379 | shell.execute_reply ISO 8601 format Indicates the time at which the shell channel’s execute_reply status message was created. This represents the time when work was completed by the kernel. 380 | iopub.status.idle ISO 8601 format Indicates the time at which the iopub channel’s kernel status message is ‘idle’. This represents the time when the kernel is ready to accept new work. 381 | Output metadata 382 | The following metadata keys are defined for code cell outputs: 383 | 384 | Key Value Interpretation 385 | isolated bool Whether the output should be isolated into an IFrame 386 | © Copyright 2015, Jupyter Development Team Revision a06f4c84. 387 | """ -------------------------------------------------------------------------------- /mystify/myst_contents_manager.py: -------------------------------------------------------------------------------- 1 | import yaml 2 | from jinja2 import Template 3 | from notebook.services.contents.largefilemanager import LargeFileManager 4 | 5 | 6 | NOTEBOOK_TPL = """ 7 | 13 | {% for cell in cells %} 14 | 19 | 20 | {% if cell.cell_type == 'code' %} 21 | ``` 22 | {{ cell.source }} 23 | ``` 24 | {% for out in cell.outputs %} 25 | {% if out.output_type == 'stream' %} 26 | {{ out.text }} 27 | {% elif out.output_type == 'display_data' %} 28 | 29 | {% endif %} 30 | {% endfor %} 31 | 32 | {% elif cell.cell_type == 'markdown' %} 33 | {{ cell.source }} 34 | {% endif %} 35 | {% endfor %} 36 | """ 37 | 38 | 39 | class MystContentsManager(LargeFileManager): 40 | def save(self, model, path=''): 41 | # maybe we can use pre_save hooks (https://github.com/jupyter/notebook/blob/master/notebook/services/contents/manager.py#L86) 42 | self.log.debug("Converting into Myst markdown") 43 | return super(MystContentsManager, self).save(model, path) 44 | 45 | def get(self, path, content=True, type=None, format=None): 46 | # This is markdown to model 47 | self.log.debug("Opening Myst markdown") 48 | return super(MystContentsManager, self).get(path, content, type, format) 49 | -------------------------------------------------------------------------------- /push_branch.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Clone it locally (git clone git@github.com:aronchick/mystify.git) 4 | # Add upstream repo (git remote add upstream git@github.com:machine-learning-apps/mystify.git) 5 | # Create a feature/topic branch (`git checkout -b awesome_feature) 6 | # Code fix/feature 7 | # don’t forget to add tests/specs and make sure they pass 8 | # Commit code on feature/topic branch (git add . && git commit -m “awesome”) 9 | # Checkout master (git checkout master) 10 | git checkout main 11 | 12 | # Pull latest from upstream (git pull upstream master) 13 | git pull upstream main 14 | 15 | # Checkout feature/topic branch (git checkout awesome_feature) 16 | git checkout wb 17 | 18 | # Rebase your changes onto the latest changes in master (git rebase master) 19 | git rebase main 20 | 21 | # Push your fix/feature branch to your fork (git push origin awesome_feature) 22 | git push origin wb 23 | 24 | # On Github website -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | description-file = README.md 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | import os 3 | 4 | with open("README.md") as f: 5 | readme = f.read() 6 | 7 | 8 | def package_files(): 9 | paths = [] 10 | for (path, _, filenames) in os.walk("extra_files"): 11 | for filename in filenames: 12 | paths.append(os.path.join("..", path, filename)) 13 | return paths 14 | 15 | 16 | extra_files = package_files() 17 | 18 | setup( 19 | name="mystify", 20 | version="0.0.1", 21 | description="NYI", 22 | long_description=readme, 23 | long_description_content_type="text/markdown", 24 | author="NYI", 25 | author_email="NYI", 26 | url="https://github.com/machine-learning-apps/mystify", 27 | license="MIT License", 28 | keywords=[ 29 | "Jupyter", 30 | "Machine Learning", 31 | "Mystify", 32 | ], # Keywords that define your package best 33 | install_requires=["wheel", ], 34 | packages=["mystify"], 35 | include_package_data=True, 36 | package_data={"": extra_files}, 37 | zip_safe=False, 38 | classifiers=[ 39 | "Development Status :: 3 - Alpha", # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package 40 | "Intended Audience :: Developers", # Define that your audience are developers 41 | "Topic :: Software Development :: Build Tools", 42 | "License :: OSI Approved :: MIT License", # Again, pick a license 43 | "Programming Language :: Python :: 3", # Specify which pyhton versions that you want to support 44 | "Programming Language :: Python :: 3.4", 45 | "Programming Language :: Python :: 3.5", 46 | "Programming Language :: Python :: 3.6", 47 | "Programming Language :: Python :: 3.8", 48 | ], 49 | ) 50 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/machine-learning-apps/mystify/38438de38daaf59620a9d6ae6895f8fa79041e40/tests/__init__.py -------------------------------------------------------------------------------- /tests/context.py: -------------------------------------------------------------------------------- 1 | """ Context file for running tests - imports everything above this directory. """ 2 | # -*- coding: utf-8 -*- 3 | 4 | import sys 5 | import os 6 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) 7 | -------------------------------------------------------------------------------- /tests/execute_functions.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import json 3 | import sys 4 | import os 5 | from pathlib import Path 6 | 7 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) 8 | 9 | from mystify import convert 10 | 11 | a = convert.to_myst((Path.cwd() / "examples" / "example_notebook.ipynb").read_text()) 12 | -------------------------------------------------------------------------------- /tests/test_e2e.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import json 3 | import sys 4 | import os 5 | from pathlib import Path 6 | 7 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) 8 | 9 | from mystify import convert 10 | 11 | def test_convert_nb_to_myst(): 12 | ipynb_text = Path("examples/example_notebook.ipynb").read_text() 13 | temp_nb = convert.to_myst(ipynb_text) 14 | 15 | myst_nb = Path("examples/example_notebook.mystnb").read_text() 16 | 17 | assert temp_nb == myst_nb 18 | 19 | 20 | def test_convert_myst_to_nb(): 21 | with open("examples/example_notebook.mystnb") as f: 22 | myst_nb = f.read() 23 | myst_model = convert.to_model(myst_nb) 24 | with open("examples/example_notebook.ipynb") as f: 25 | ipynb_model = json.load(f) 26 | assert myst_model == ipynb_model 27 | --------------------------------------------------------------------------------