├── .gitignore ├── .travis.yml ├── LICENSE.txt ├── MANIFEST.in ├── Pipfile ├── Pipfile.lock ├── README.md ├── nbexec ├── __init__.py ├── __version__.py ├── cli.py └── core.py ├── setup.py └── test ├── notebooks ├── simple-with-kernelspec.ipynb └── simple-without-kernelspec.ipynb └── test_basics.py /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb_checkpoints 2 | .DS_Store 3 | #### joe made this: http://goel.io/joe 4 | 5 | #####=== Python ===##### 6 | 7 | # Byte-compiled / optimized / DLL files 8 | __pycache__/ 9 | *.py[cod] 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | env/ 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | 31 | # PyInstaller 32 | # Usually these files are written by a python script from a template 33 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 34 | *.manifest 35 | *.spec 36 | 37 | # Installer logs 38 | pip-log.txt 39 | pip-delete-this-directory.txt 40 | 41 | # Unit test / coverage reports 42 | htmlcov/ 43 | .tox/ 44 | .coverage 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | 56 | # Sphinx documentation 57 | docs/_build/ 58 | 59 | # PyBuilder 60 | target/ 61 | 62 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.4" 4 | - "3.5" 5 | - "3.6" 6 | - "3.7" 7 | - "3.8" 8 | install: 9 | - pip install . 10 | - pip install ipykernel 11 | - pip install nose 12 | - pip install coveralls 13 | script: nosetests --with-coverage --cover-package nbexec 14 | after_success: coveralls 15 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018, Jeremy Singer-Vine 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 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include *.txt *.md *.rst 2 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | jupyter_client = "*" 8 | nbconvert = "*" 9 | nbformat = "*" 10 | nbexec = {path = "."} 11 | 12 | [dev-packages] 13 | nose = "*" 14 | ipykernel = "*" 15 | 16 | [requires] 17 | python_version = "3.9" 18 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "59532f9ab5d20d7d6a822240b28e5bb730e05f5a426b1a0ae993ebe58b24464c" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.9" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "attrs": { 20 | "hashes": [ 21 | "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", 22 | "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" 23 | ], 24 | "markers": "python_version >= '3.5'", 25 | "version": "==22.1.0" 26 | }, 27 | "beautifulsoup4": { 28 | "hashes": [ 29 | "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30", 30 | "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693" 31 | ], 32 | "markers": "python_version >= '3.6'", 33 | "version": "==4.11.1" 34 | }, 35 | "bleach": { 36 | "hashes": [ 37 | "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a", 38 | "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c" 39 | ], 40 | "markers": "python_version >= '3.7'", 41 | "version": "==5.0.1" 42 | }, 43 | "defusedxml": { 44 | "hashes": [ 45 | "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", 46 | "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61" 47 | ], 48 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", 49 | "version": "==0.7.1" 50 | }, 51 | "entrypoints": { 52 | "hashes": [ 53 | "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4", 54 | "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f" 55 | ], 56 | "markers": "python_version >= '3.6'", 57 | "version": "==0.4" 58 | }, 59 | "fastjsonschema": { 60 | "hashes": [ 61 | "sha256:01e366f25d9047816fe3d288cbfc3e10541daf0af2044763f3d0ade42476da18", 62 | "sha256:21f918e8d9a1a4ba9c22e09574ba72267a6762d47822db9add95f6454e51cc1c" 63 | ], 64 | "version": "==2.16.2" 65 | }, 66 | "importlib-metadata": { 67 | "hashes": [ 68 | "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670", 69 | "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23" 70 | ], 71 | "markers": "python_version < '3.10'", 72 | "version": "==4.12.0" 73 | }, 74 | "jinja2": { 75 | "hashes": [ 76 | "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", 77 | "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" 78 | ], 79 | "markers": "python_version >= '3.7'", 80 | "version": "==3.1.2" 81 | }, 82 | "jsonschema": { 83 | "hashes": [ 84 | "sha256:165059f076eff6971bae5b742fc029a7b4ef3f9bcf04c14e4776a7605de14b23", 85 | "sha256:9e74b8f9738d6a946d70705dc692b74b5429cd0960d58e79ffecfc43b2221eb9" 86 | ], 87 | "markers": "python_version >= '3.7'", 88 | "version": "==4.16.0" 89 | }, 90 | "jupyter-client": { 91 | "hashes": [ 92 | "sha256:3c58466a1b8d55dba0bf3ce0834e4f5b7760baf98d1d73db0add6f19de9ecd1d", 93 | "sha256:b33222bdc9dd1714228bd286af006533a0abe2bbc093e8f3d29dc0b91bdc2be4" 94 | ], 95 | "index": "pypi", 96 | "version": "==7.3.5" 97 | }, 98 | "jupyter-core": { 99 | "hashes": [ 100 | "sha256:2e5f244d44894c4154d06aeae3419dd7f1b0ef4494dc5584929b398c61cfd314", 101 | "sha256:715e22bb6cc7db3718fddfac1f69f1c7e899ca00e42bdfd4bf3705452b9fd84a" 102 | ], 103 | "markers": "python_version >= '3.7'", 104 | "version": "==4.11.1" 105 | }, 106 | "jupyterlab-pygments": { 107 | "hashes": [ 108 | "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f", 109 | "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d" 110 | ], 111 | "markers": "python_version >= '3.7'", 112 | "version": "==0.2.2" 113 | }, 114 | "lxml": { 115 | "hashes": [ 116 | "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318", 117 | "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c", 118 | "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b", 119 | "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000", 120 | "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73", 121 | "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d", 122 | "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb", 123 | "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8", 124 | "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2", 125 | "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345", 126 | "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94", 127 | "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e", 128 | "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b", 129 | "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc", 130 | "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a", 131 | "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9", 132 | "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc", 133 | "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387", 134 | "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb", 135 | "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7", 136 | "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4", 137 | "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97", 138 | "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67", 139 | "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627", 140 | "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7", 141 | "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd", 142 | "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3", 143 | "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7", 144 | "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130", 145 | "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b", 146 | "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036", 147 | "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785", 148 | "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca", 149 | "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91", 150 | "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc", 151 | "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536", 152 | "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391", 153 | "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3", 154 | "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d", 155 | "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21", 156 | "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3", 157 | "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d", 158 | "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29", 159 | "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715", 160 | "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed", 161 | "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25", 162 | "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c", 163 | "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785", 164 | "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837", 165 | "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4", 166 | "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b", 167 | "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2", 168 | "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067", 169 | "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448", 170 | "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d", 171 | "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2", 172 | "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc", 173 | "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c", 174 | "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5", 175 | "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84", 176 | "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8", 177 | "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf", 178 | "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7", 179 | "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e", 180 | "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb", 181 | "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b", 182 | "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3", 183 | "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad", 184 | "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8", 185 | "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f" 186 | ], 187 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", 188 | "version": "==4.9.1" 189 | }, 190 | "markupsafe": { 191 | "hashes": [ 192 | "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003", 193 | "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88", 194 | "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5", 195 | "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7", 196 | "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a", 197 | "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603", 198 | "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1", 199 | "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135", 200 | "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247", 201 | "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6", 202 | "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601", 203 | "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77", 204 | "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02", 205 | "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e", 206 | "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63", 207 | "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f", 208 | "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980", 209 | "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b", 210 | "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812", 211 | "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff", 212 | "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96", 213 | "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1", 214 | "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925", 215 | "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a", 216 | "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6", 217 | "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e", 218 | "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f", 219 | "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4", 220 | "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f", 221 | "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3", 222 | "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c", 223 | "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a", 224 | "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417", 225 | "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a", 226 | "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a", 227 | "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37", 228 | "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452", 229 | "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933", 230 | "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a", 231 | "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7" 232 | ], 233 | "markers": "python_version >= '3.7'", 234 | "version": "==2.1.1" 235 | }, 236 | "mistune": { 237 | "hashes": [ 238 | "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d", 239 | "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808" 240 | ], 241 | "version": "==2.0.4" 242 | }, 243 | "nbclient": { 244 | "hashes": [ 245 | "sha256:268fde3457cafe1539e32eb1c6d796bbedb90b9e92bacd3e43d83413734bb0e8", 246 | "sha256:7cce8b415888539180535953f80ea2385cdbb444944cdeb73ffac1556fdbc228" 247 | ], 248 | "markers": "python_version >= '3.7'", 249 | "version": "==0.6.8" 250 | }, 251 | "nbconvert": { 252 | "hashes": [ 253 | "sha256:26843ae233167e8aae31c20e3e1d91f431f04c9f34363bbe2dd0d247f772641c", 254 | "sha256:fd1e361da30e30e4c5a5ae89f7cae95ca2a4d4407389672473312249a7ba0060" 255 | ], 256 | "index": "pypi", 257 | "version": "==7.0.0" 258 | }, 259 | "nbexec": { 260 | "path": ".", 261 | "version": "==0.1.0" 262 | }, 263 | "nbformat": { 264 | "hashes": [ 265 | "sha256:9ebe30e6c3b3e5b47d39ff0a3897a1acf523d2bfafcb4e2d04cdb70f8a66c507", 266 | "sha256:eb21018bbcdb29e7a4b8b29068d4b6794cdad685db8fcd569b97a09a048dc2e4" 267 | ], 268 | "index": "pypi", 269 | "version": "==5.5.0" 270 | }, 271 | "nest-asyncio": { 272 | "hashes": [ 273 | "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2", 274 | "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65" 275 | ], 276 | "markers": "python_version >= '3.5'", 277 | "version": "==1.5.5" 278 | }, 279 | "packaging": { 280 | "hashes": [ 281 | "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", 282 | "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" 283 | ], 284 | "markers": "python_version >= '3.6'", 285 | "version": "==21.3" 286 | }, 287 | "pandocfilters": { 288 | "hashes": [ 289 | "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38", 290 | "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f" 291 | ], 292 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 293 | "version": "==1.5.0" 294 | }, 295 | "pygments": { 296 | "hashes": [ 297 | "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1", 298 | "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42" 299 | ], 300 | "markers": "python_version >= '3.6'", 301 | "version": "==2.13.0" 302 | }, 303 | "pyparsing": { 304 | "hashes": [ 305 | "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", 306 | "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" 307 | ], 308 | "markers": "python_full_version >= '3.6.8'", 309 | "version": "==3.0.9" 310 | }, 311 | "pyrsistent": { 312 | "hashes": [ 313 | "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c", 314 | "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc", 315 | "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e", 316 | "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26", 317 | "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec", 318 | "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286", 319 | "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045", 320 | "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec", 321 | "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8", 322 | "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c", 323 | "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca", 324 | "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22", 325 | "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a", 326 | "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96", 327 | "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc", 328 | "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1", 329 | "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07", 330 | "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6", 331 | "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b", 332 | "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5", 333 | "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6" 334 | ], 335 | "markers": "python_version >= '3.7'", 336 | "version": "==0.18.1" 337 | }, 338 | "python-dateutil": { 339 | "hashes": [ 340 | "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", 341 | "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" 342 | ], 343 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 344 | "version": "==2.8.2" 345 | }, 346 | "pyzmq": { 347 | "hashes": [ 348 | "sha256:00a8a4f83259b91b238244c999a33e0a77c0427d496902fb75fdf1601e4c9d3d", 349 | "sha256:025a0815d36ccd54cf002feb9cbe0e37c2253eca305ee4dc72ccdb4a814eefb4", 350 | "sha256:0584420cbd2dac77f81bdc4b9da2635a54300563d4632433b08cb1f505341ef0", 351 | "sha256:0775b65e79cccfca2b017e80ffe6dbd224b035a47245c4140b08e93996425942", 352 | "sha256:0a07fb73ae006a5b565d19232e5a6592fd7c93e57e67c2e592bf0b21f1676767", 353 | "sha256:13b008bd142c9f6079ad75a30504eef2291502e9eac90e722b16fcf9ce856147", 354 | "sha256:1a53c6030c4f45859af9a75cfc0d8b551b8924f9b2503397c69d0fa2f62d2370", 355 | "sha256:1b978e1318311eb69523ed60f084b752f52f27ffea4ce2f60deab4d8a4cca6de", 356 | "sha256:1bdec8988cad1f9a8453b4d00fd11598a91604cd9b205640e98b2f22e0435921", 357 | "sha256:1c23568e1581f637b1a1e1fd15dcd5e9165332c94bf8101c562e7c50640d673e", 358 | "sha256:1f200cdca2fc842749a3f263ccf9e4b50e732ad14f53b60faf68ef656b75c32a", 359 | "sha256:201e4d5733cecfd469d9ceee57500a0f365f85d6f14dd524105e2a0be8cd93c1", 360 | "sha256:2e5a398955b1cfdd85dd699f2390661b7bbe9edcbadd70a444c79c69e6c31c91", 361 | "sha256:3823e5e613a61948b2e6b85fd91f872772717d24cd1df871836665d4c56d6b34", 362 | "sha256:38e9ff2918d50a588e56aa80dae0373ef9f67512fc5691f95db2f59edabc083e", 363 | "sha256:3b5107313c7f28b0e074da7a9d8c0132cb8dc32fdd3b5a4c6a224d30e50d6324", 364 | "sha256:3e66d3237a7e8a11cdb8b470c77a6fb43f49fe9407936a2c9ac468ba2ba0982e", 365 | "sha256:40cdb50e82393253d340b6a357474588eb01cfd90b06231d5bfbc14490490b1b", 366 | "sha256:44c1dc858b76d2ab28f5ea040dd5e816a71624a8cf38d4ca3208006fd2a9375e", 367 | "sha256:452c3d5bfbaf96f32ef20673e6ba238355891884009f0c87e0f97a985293ef42", 368 | "sha256:460f0ff945d4b46c2d568941be33cf08954fca1e3239cf6a6ee03b1371de8f64", 369 | "sha256:4985a82958d67eafd3f8c9c215c3da8f633592024f771420477f22f011846235", 370 | "sha256:4ec8847ab93200a94fd3e88e2824a6bba9a46d28161f1bf0be24f2237c40c291", 371 | "sha256:52d881c33f8db5ffcb0aabc14cc71098453f4700511195cebca846000b44b080", 372 | "sha256:534d13940b2476e4bacb54558c7b9b62fb275c2839e06267597a3e4b2f291196", 373 | "sha256:5439bef77fd3818c20e1bf5657836e105e4e48e1a7996e24ebb55402a681934e", 374 | "sha256:5c1c2d7ebe991d8e36365ccd6b47297b6b96393ad453cad990901c21924add30", 375 | "sha256:62ee069fe338d0b057b81e752dad2b9b6b206ba8570a878dbbe8b93b7b99ebb1", 376 | "sha256:65b532c95a4cde95bb4787b5545321ed5624fa8d7391bce17c4e2a0717b97bb7", 377 | "sha256:6814a6add1b7cb76e3fdfd961ce4c48c1f0a29e82bdb3d060a669b85bc6db454", 378 | "sha256:761016baa6ca720677ce01d453801e41db2d0e53cf052ed00ba8c2e6cae4d2cd", 379 | "sha256:8361c90701fc6ff5f16c81c969563c6915402fbecb2ddc9c5063fec0238e5e52", 380 | "sha256:844040d44cc4320cdffb258fe03768ff0b37e710d56a70dd1f6c2902738f1e28", 381 | "sha256:8698db54fd49af74333190fb154448dcfc67a382aa2b2d784ffe981b7cf421ec", 382 | "sha256:8988209d5efae9b5c9297fb48d153e2528384c1afe2c9fd8eeb474cd6e765199", 383 | "sha256:8a43105683a66de78489b30037b97c9ce5f821f57035f6944f633bbd4baadd15", 384 | "sha256:8a93abd67a46c6b91f28a7513b9f8b9a5432fd573c3d6444c083e07209bf96e4", 385 | "sha256:8ea1861512c7f32d0c585119a2caea6665eec6df429abf5810826b0df9587de1", 386 | "sha256:99bb8cff279f7d1f516919d82b35ed0796c53ce7da7dca191fabfa4c53f47740", 387 | "sha256:9ed10f5a942a2903a722d63806b7a9d2e0a966c038100dc763483d8fbe8ea074", 388 | "sha256:a5b9471e5e507f51f4c0acabec60a7ae2ea218ac6134a8e5ec5674845347a63a", 389 | "sha256:a5cdbede23aae133e50f786adc4a2cacf60bddde649e3dc122c32368daa2c007", 390 | "sha256:aa6d0dfa94ce89d050dca0104389e10c537715bf10e5b0bfe5ece79f17f1719e", 391 | "sha256:adbf2bb11a616210735d6a112186d378f7934be3f2935e6d9dd760c110840c3a", 392 | "sha256:ae33cb195304ac16996184b115f9e27eb9f0b14062e97fbd1d446e3e4a594ff0", 393 | "sha256:b1ef471c62c3d0681cfbaa8bbaf96f22e20cafd391ecad8a43317f6b1598478e", 394 | "sha256:b94a3453a18bb914b2cac1ac38c09f980a3c86a8cd0bb744dd6bd03ab8ff958a", 395 | "sha256:be67e7f48fce8dbefd602f779c7382c874a1a1a3d08f375366c4d28baaa0bfd4", 396 | "sha256:c37c0046d04c0fdd99a9a31d6a9ce7d703cca3b7fdde5738603503dfba58a25f", 397 | "sha256:c6736703c7581d18e3959c1d786035c620def2f096e762aefaf08cfa39844d1e", 398 | "sha256:ce8c61297a751c67062d11e44352e9379da03a90d95aa352395d3b1e53e9f20a", 399 | "sha256:cf6477a083f8a1b54893ad24bc15f94dd0684b02320c69d2a69dcf36f70e73cb", 400 | "sha256:dbb871b22acec52c1b046ef6aa3d16f83618c704772f126a49e7446a0c885278", 401 | "sha256:dbece43299705eca217808759f4322c7cab41db2ba3ad8d7261ee2b17abe6488", 402 | "sha256:dfde6624d3d99d9a67235b60ae13be1a6ffce2f1de3cd2be9900f011d5d6a6a6", 403 | "sha256:e0128c7b723984e31c1b0df5bc532715defd13bf64d8d9eddd7207d093759ae4", 404 | "sha256:e24d7bda7a32ff35d0c914a52dd920a408f73d7e4b93d6755d7c67e819a8cd8c", 405 | "sha256:e9cd5c7449f297a1b53a4803413db907a8cad1178435e2879c1b92816f2bbe56", 406 | "sha256:e9e3fa94fa1e58763a7b824b8e0015d93c9fdd8e449d0218d13d01172e3d1539", 407 | "sha256:eadf1d3841c2155b68ef49147253fd4ac1447a972d01c08248114edc4d3ba9d5", 408 | "sha256:eb3b8acb5dc33ec812d79f35b85fddc43d8f75b65c00c635ee3c0b527e11c8ea", 409 | "sha256:ebdb43e947291c5cb80ef6c7d525f64bc4ed685de43f855ba0cf2b0fd8052e3a", 410 | "sha256:ee24b94b5ae22af9148e597f512fae8383908ca07d3b7f99b349679fede4d7d3", 411 | "sha256:ef4bd725c06d6ee9e502419ceeb5dfaccb6bbe36f359fd0366b90a56b6dae647", 412 | "sha256:f05524f7cfa4f7398259a428fbb22ec4c3f0665c6a303a0d6afdd98457b19af3", 413 | "sha256:f1ddc43cceb500e4a6495250d9d34cac93e6d9e89a46f0e34fcefcc3caf66ef3", 414 | "sha256:f328d28d0a1ea43d7030e1999ced9db252ba4ef2531af3e9bfc135cca77b8324", 415 | "sha256:f355d23a420a6b39241bbef2c803839b01d52d680d89aac39460505e57b2cd03", 416 | "sha256:f81f4065ff8ccd207204129463fd587b25c9f593128176a717dbabc03af9b233", 417 | "sha256:f969214a9ebf1175a8aba863d6f1220174130188686d4ed475d138a240e60c1c", 418 | "sha256:fc21a74f337298840f59f21a12fbf6ec1de798cd69d6b331ef9ed88ac8cb18f0", 419 | "sha256:fc2c363f68bbb9fea6b8137c432c6df9d7c8c76b01549c4410c506dac9e30663", 420 | "sha256:ff4e510a9509d36359c7af4684e73489cdd53c781dd4bc9b07dc808fab56cc48", 421 | "sha256:ff6c9fdbcfb285e28fe35eaf5ba39644cbc65343aa41844217c2b5a99abbdd7e" 422 | ], 423 | "markers": "python_version >= '3.6'", 424 | "version": "==24.0.0" 425 | }, 426 | "six": { 427 | "hashes": [ 428 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", 429 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" 430 | ], 431 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 432 | "version": "==1.16.0" 433 | }, 434 | "soupsieve": { 435 | "hashes": [ 436 | "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759", 437 | "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d" 438 | ], 439 | "markers": "python_version >= '3.6'", 440 | "version": "==2.3.2.post1" 441 | }, 442 | "tinycss2": { 443 | "hashes": [ 444 | "sha256:b2e44dd8883c360c35dd0d1b5aad0b610e5156c2cb3b33434634e539ead9d8bf", 445 | "sha256:fe794ceaadfe3cf3e686b22155d0da5780dd0e273471a51846d0a02bc204fec8" 446 | ], 447 | "markers": "python_version >= '3.6'", 448 | "version": "==1.1.1" 449 | }, 450 | "tornado": { 451 | "hashes": [ 452 | "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca", 453 | "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72", 454 | "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23", 455 | "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8", 456 | "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b", 457 | "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9", 458 | "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13", 459 | "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75", 460 | "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac", 461 | "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e", 462 | "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b" 463 | ], 464 | "markers": "python_version >= '3.7'", 465 | "version": "==6.2" 466 | }, 467 | "traitlets": { 468 | "hashes": [ 469 | "sha256:3f2c4e435e271592fe4390f1746ea56836e3a080f84e7833f0f801d9613fec39", 470 | "sha256:93663cc8236093d48150e2af5e2ed30fc7904a11a6195e21bab0408af4e6d6c8" 471 | ], 472 | "markers": "python_version >= '3.7'", 473 | "version": "==5.4.0" 474 | }, 475 | "webencodings": { 476 | "hashes": [ 477 | "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", 478 | "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923" 479 | ], 480 | "version": "==0.5.1" 481 | }, 482 | "zipp": { 483 | "hashes": [ 484 | "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", 485 | "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" 486 | ], 487 | "markers": "python_version >= '3.7'", 488 | "version": "==3.8.1" 489 | } 490 | }, 491 | "develop": { 492 | "appnope": { 493 | "hashes": [ 494 | "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24", 495 | "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e" 496 | ], 497 | "markers": "platform_system == 'Darwin'", 498 | "version": "==0.1.3" 499 | }, 500 | "asttokens": { 501 | "hashes": [ 502 | "sha256:c61e16246ecfb2cde2958406b4c8ebc043c9e6d73aaa83c941673b35e5d3a76b", 503 | "sha256:e3305297c744ae53ffa032c45dc347286165e4ffce6875dc662b205db0623d86" 504 | ], 505 | "version": "==2.0.8" 506 | }, 507 | "backcall": { 508 | "hashes": [ 509 | "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e", 510 | "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255" 511 | ], 512 | "version": "==0.2.0" 513 | }, 514 | "debugpy": { 515 | "hashes": [ 516 | "sha256:34d2cdd3a7c87302ba5322b86e79c32c2115be396f3f09ca13306d8a04fe0f16", 517 | "sha256:3c9f985944a30cfc9ae4306ac6a27b9c31dba72ca943214dad4a0ab3840f6161", 518 | "sha256:4e255982552b0edfe3a6264438dbd62d404baa6556a81a88f9420d3ed79b06ae", 519 | "sha256:5ad571a36cec137ae6ed951d0ff75b5e092e9af6683da084753231150cbc5b25", 520 | "sha256:6efc30325b68e451118b795eff6fe8488253ca3958251d5158106d9c87581bc6", 521 | "sha256:7c302095a81be0d5c19f6529b600bac971440db3e226dce85347cc27e6a61908", 522 | "sha256:84c39940a0cac410bf6aa4db00ba174f973eef521fbe9dd058e26bcabad89c4f", 523 | "sha256:86d784b72c5411c833af1cd45b83d80c252b77c3bfdb43db17c441d772f4c734", 524 | "sha256:adcfea5ea06d55d505375995e150c06445e2b20cd12885bcae566148c076636b", 525 | "sha256:b8deaeb779699350deeed835322730a3efec170b88927debc9ba07a1a38e2585", 526 | "sha256:c4b2bd5c245eeb49824bf7e539f95fb17f9a756186e51c3e513e32999d8846f3", 527 | "sha256:c4cd6f37e3c168080d61d698390dfe2cd9e74ebf80b448069822a15dadcda57d", 528 | "sha256:cca23cb6161ac89698d629d892520327dd1be9321c0960e610bbcb807232b45d", 529 | "sha256:d5c814596a170a0a58fa6fad74947e30bfd7e192a5d2d7bd6a12156c2899e13a", 530 | "sha256:daadab4403427abd090eccb38d8901afd8b393e01fd243048fab3f1d7132abb4", 531 | "sha256:dda8652520eae3945833e061cbe2993ad94a0b545aebd62e4e6b80ee616c76b2", 532 | "sha256:e8922090514a890eec99cfb991bab872dd2e353ebb793164d5f01c362b9a40bf", 533 | "sha256:fc233a0160f3b117b20216f1169e7211b83235e3cd6749bcdd8dbb72177030c7" 534 | ], 535 | "markers": "python_version >= '3.7'", 536 | "version": "==1.6.3" 537 | }, 538 | "decorator": { 539 | "hashes": [ 540 | "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", 541 | "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" 542 | ], 543 | "markers": "python_version >= '3.5'", 544 | "version": "==5.1.1" 545 | }, 546 | "entrypoints": { 547 | "hashes": [ 548 | "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4", 549 | "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f" 550 | ], 551 | "markers": "python_version >= '3.6'", 552 | "version": "==0.4" 553 | }, 554 | "executing": { 555 | "hashes": [ 556 | "sha256:550d581b497228b572235e633599133eeee67073c65914ca346100ad56775349", 557 | "sha256:98daefa9d1916a4f0d944880d5aeaf079e05585689bebd9ff9b32e31dd5e1017" 558 | ], 559 | "version": "==1.0.0" 560 | }, 561 | "ipykernel": { 562 | "hashes": [ 563 | "sha256:b81d57b0e171670844bf29cdc11562b1010d3da87115c4513e0ee660a8368765", 564 | "sha256:befe3736944b21afec8e832725e9a45f254c8bd9afc40b61d6661c97e45aff5a" 565 | ], 566 | "index": "pypi", 567 | "version": "==6.15.3" 568 | }, 569 | "ipython": { 570 | "hashes": [ 571 | "sha256:097bdf5cd87576fd066179c9f7f208004f7a6864ee1b20f37d346c0bcb099f84", 572 | "sha256:6f090e29ab8ef8643e521763a4f1f39dc3914db643122b1e9d3328ff2e43ada2" 573 | ], 574 | "markers": "python_version >= '3.8'", 575 | "version": "==8.5.0" 576 | }, 577 | "jedi": { 578 | "hashes": [ 579 | "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d", 580 | "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab" 581 | ], 582 | "markers": "python_version >= '3.6'", 583 | "version": "==0.18.1" 584 | }, 585 | "jupyter-client": { 586 | "hashes": [ 587 | "sha256:3c58466a1b8d55dba0bf3ce0834e4f5b7760baf98d1d73db0add6f19de9ecd1d", 588 | "sha256:b33222bdc9dd1714228bd286af006533a0abe2bbc093e8f3d29dc0b91bdc2be4" 589 | ], 590 | "index": "pypi", 591 | "version": "==7.3.5" 592 | }, 593 | "jupyter-core": { 594 | "hashes": [ 595 | "sha256:2e5f244d44894c4154d06aeae3419dd7f1b0ef4494dc5584929b398c61cfd314", 596 | "sha256:715e22bb6cc7db3718fddfac1f69f1c7e899ca00e42bdfd4bf3705452b9fd84a" 597 | ], 598 | "markers": "python_version >= '3.7'", 599 | "version": "==4.11.1" 600 | }, 601 | "matplotlib-inline": { 602 | "hashes": [ 603 | "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311", 604 | "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304" 605 | ], 606 | "markers": "python_version >= '3.5'", 607 | "version": "==0.1.6" 608 | }, 609 | "nest-asyncio": { 610 | "hashes": [ 611 | "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2", 612 | "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65" 613 | ], 614 | "markers": "python_version >= '3.5'", 615 | "version": "==1.5.5" 616 | }, 617 | "nose": { 618 | "hashes": [ 619 | "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", 620 | "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a", 621 | "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" 622 | ], 623 | "index": "pypi", 624 | "version": "==1.3.7" 625 | }, 626 | "packaging": { 627 | "hashes": [ 628 | "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb", 629 | "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522" 630 | ], 631 | "markers": "python_version >= '3.6'", 632 | "version": "==21.3" 633 | }, 634 | "parso": { 635 | "hashes": [ 636 | "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", 637 | "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" 638 | ], 639 | "markers": "python_version >= '3.6'", 640 | "version": "==0.8.3" 641 | }, 642 | "pexpect": { 643 | "hashes": [ 644 | "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937", 645 | "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c" 646 | ], 647 | "markers": "sys_platform != 'win32'", 648 | "version": "==4.8.0" 649 | }, 650 | "pickleshare": { 651 | "hashes": [ 652 | "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", 653 | "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" 654 | ], 655 | "version": "==0.7.5" 656 | }, 657 | "prompt-toolkit": { 658 | "hashes": [ 659 | "sha256:9696f386133df0fc8ca5af4895afe5d78f5fcfe5258111c2a79a1c3e41ffa96d", 660 | "sha256:9ada952c9d1787f52ff6d5f3484d0b4df8952787c087edf6a1f7c2cb1ea88148" 661 | ], 662 | "markers": "python_full_version >= '3.6.2'", 663 | "version": "==3.0.31" 664 | }, 665 | "psutil": { 666 | "hashes": [ 667 | "sha256:14b29f581b5edab1f133563272a6011925401804d52d603c5c606936b49c8b97", 668 | "sha256:256098b4f6ffea6441eb54ab3eb64db9ecef18f6a80d7ba91549195d55420f84", 669 | "sha256:39ec06dc6c934fb53df10c1672e299145ce609ff0611b569e75a88f313634969", 670 | "sha256:404f4816c16a2fcc4eaa36d7eb49a66df2d083e829d3e39ee8759a411dbc9ecf", 671 | "sha256:42638876b7f5ef43cef8dcf640d3401b27a51ee3fa137cb2aa2e72e188414c32", 672 | "sha256:4642fd93785a29353d6917a23e2ac6177308ef5e8be5cc17008d885cb9f70f12", 673 | "sha256:4fb54941aac044a61db9d8eb56fc5bee207db3bc58645d657249030e15ba3727", 674 | "sha256:561dec454853846d1dd0247b44c2e66a0a0c490f937086930ec4b8f83bf44f06", 675 | "sha256:5d39e3a2d5c40efa977c9a8dd4f679763c43c6c255b1340a56489955dbca767c", 676 | "sha256:614337922702e9be37a39954d67fdb9e855981624d8011a9927b8f2d3c9625d9", 677 | "sha256:67b33f27fc0427483b61563a16c90d9f3b547eeb7af0ef1b9fe024cdc9b3a6ea", 678 | "sha256:68b35cbff92d1f7103d8f1db77c977e72f49fcefae3d3d2b91c76b0e7aef48b8", 679 | "sha256:7cbb795dcd8ed8fd238bc9e9f64ab188f3f4096d2e811b5a82da53d164b84c3f", 680 | "sha256:8f024fbb26c8daf5d70287bb3edfafa22283c255287cf523c5d81721e8e5d82c", 681 | "sha256:91aa0dac0c64688667b4285fa29354acfb3e834e1fd98b535b9986c883c2ce1d", 682 | "sha256:94e621c6a4ddb2573d4d30cba074f6d1aa0186645917df42c811c473dd22b339", 683 | "sha256:9770c1d25aee91417eba7869139d629d6328a9422ce1cdd112bd56377ca98444", 684 | "sha256:b1928b9bf478d31fdffdb57101d18f9b70ed4e9b0e41af751851813547b2a9ab", 685 | "sha256:b2f248ffc346f4f4f0d747ee1947963613216b06688be0be2e393986fe20dbbb", 686 | "sha256:b315febaebae813326296872fdb4be92ad3ce10d1d742a6b0c49fb619481ed0b", 687 | "sha256:b3591616fa07b15050b2f87e1cdefd06a554382e72866fcc0ab2be9d116486c8", 688 | "sha256:b4018d5f9b6651f9896c7a7c2c9f4652e4eea53f10751c4e7d08a9093ab587ec", 689 | "sha256:d75291912b945a7351d45df682f9644540d564d62115d4a20d45fa17dc2d48f8", 690 | "sha256:dc9bda7d5ced744622f157cc8d8bdd51735dafcecff807e928ff26bdb0ff097d", 691 | "sha256:e3ac2c0375ef498e74b9b4ec56df3c88be43fe56cac465627572dbfb21c4be34", 692 | "sha256:e4c4a7636ffc47b7141864f1c5e7d649f42c54e49da2dd3cceb1c5f5d29bfc85", 693 | "sha256:ed29ea0b9a372c5188cdb2ad39f937900a10fb5478dc077283bf86eeac678ef1", 694 | "sha256:f40ba362fefc11d6bea4403f070078d60053ed422255bd838cd86a40674364c9", 695 | "sha256:f4cb67215c10d4657e320037109939b1c1d2fd70ca3d76301992f89fe2edb1f1", 696 | "sha256:f7929a516125f62399d6e8e026129c8835f6c5a3aab88c3fff1a05ee8feb840d", 697 | "sha256:fd331866628d18223a4265371fd255774affd86244fc307ef66eaf00de0633d5", 698 | "sha256:feb861a10b6c3bb00701063b37e4afc754f8217f0f09c42280586bd6ac712b5c" 699 | ], 700 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 701 | "version": "==5.9.2" 702 | }, 703 | "ptyprocess": { 704 | "hashes": [ 705 | "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", 706 | "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" 707 | ], 708 | "version": "==0.7.0" 709 | }, 710 | "pure-eval": { 711 | "hashes": [ 712 | "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", 713 | "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3" 714 | ], 715 | "version": "==0.2.2" 716 | }, 717 | "pygments": { 718 | "hashes": [ 719 | "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1", 720 | "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42" 721 | ], 722 | "markers": "python_version >= '3.6'", 723 | "version": "==2.13.0" 724 | }, 725 | "pyparsing": { 726 | "hashes": [ 727 | "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb", 728 | "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc" 729 | ], 730 | "markers": "python_full_version >= '3.6.8'", 731 | "version": "==3.0.9" 732 | }, 733 | "python-dateutil": { 734 | "hashes": [ 735 | "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", 736 | "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" 737 | ], 738 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 739 | "version": "==2.8.2" 740 | }, 741 | "pyzmq": { 742 | "hashes": [ 743 | "sha256:00a8a4f83259b91b238244c999a33e0a77c0427d496902fb75fdf1601e4c9d3d", 744 | "sha256:025a0815d36ccd54cf002feb9cbe0e37c2253eca305ee4dc72ccdb4a814eefb4", 745 | "sha256:0584420cbd2dac77f81bdc4b9da2635a54300563d4632433b08cb1f505341ef0", 746 | "sha256:0775b65e79cccfca2b017e80ffe6dbd224b035a47245c4140b08e93996425942", 747 | "sha256:0a07fb73ae006a5b565d19232e5a6592fd7c93e57e67c2e592bf0b21f1676767", 748 | "sha256:13b008bd142c9f6079ad75a30504eef2291502e9eac90e722b16fcf9ce856147", 749 | "sha256:1a53c6030c4f45859af9a75cfc0d8b551b8924f9b2503397c69d0fa2f62d2370", 750 | "sha256:1b978e1318311eb69523ed60f084b752f52f27ffea4ce2f60deab4d8a4cca6de", 751 | "sha256:1bdec8988cad1f9a8453b4d00fd11598a91604cd9b205640e98b2f22e0435921", 752 | "sha256:1c23568e1581f637b1a1e1fd15dcd5e9165332c94bf8101c562e7c50640d673e", 753 | "sha256:1f200cdca2fc842749a3f263ccf9e4b50e732ad14f53b60faf68ef656b75c32a", 754 | "sha256:201e4d5733cecfd469d9ceee57500a0f365f85d6f14dd524105e2a0be8cd93c1", 755 | "sha256:2e5a398955b1cfdd85dd699f2390661b7bbe9edcbadd70a444c79c69e6c31c91", 756 | "sha256:3823e5e613a61948b2e6b85fd91f872772717d24cd1df871836665d4c56d6b34", 757 | "sha256:38e9ff2918d50a588e56aa80dae0373ef9f67512fc5691f95db2f59edabc083e", 758 | "sha256:3b5107313c7f28b0e074da7a9d8c0132cb8dc32fdd3b5a4c6a224d30e50d6324", 759 | "sha256:3e66d3237a7e8a11cdb8b470c77a6fb43f49fe9407936a2c9ac468ba2ba0982e", 760 | "sha256:40cdb50e82393253d340b6a357474588eb01cfd90b06231d5bfbc14490490b1b", 761 | "sha256:44c1dc858b76d2ab28f5ea040dd5e816a71624a8cf38d4ca3208006fd2a9375e", 762 | "sha256:452c3d5bfbaf96f32ef20673e6ba238355891884009f0c87e0f97a985293ef42", 763 | "sha256:460f0ff945d4b46c2d568941be33cf08954fca1e3239cf6a6ee03b1371de8f64", 764 | "sha256:4985a82958d67eafd3f8c9c215c3da8f633592024f771420477f22f011846235", 765 | "sha256:4ec8847ab93200a94fd3e88e2824a6bba9a46d28161f1bf0be24f2237c40c291", 766 | "sha256:52d881c33f8db5ffcb0aabc14cc71098453f4700511195cebca846000b44b080", 767 | "sha256:534d13940b2476e4bacb54558c7b9b62fb275c2839e06267597a3e4b2f291196", 768 | "sha256:5439bef77fd3818c20e1bf5657836e105e4e48e1a7996e24ebb55402a681934e", 769 | "sha256:5c1c2d7ebe991d8e36365ccd6b47297b6b96393ad453cad990901c21924add30", 770 | "sha256:62ee069fe338d0b057b81e752dad2b9b6b206ba8570a878dbbe8b93b7b99ebb1", 771 | "sha256:65b532c95a4cde95bb4787b5545321ed5624fa8d7391bce17c4e2a0717b97bb7", 772 | "sha256:6814a6add1b7cb76e3fdfd961ce4c48c1f0a29e82bdb3d060a669b85bc6db454", 773 | "sha256:761016baa6ca720677ce01d453801e41db2d0e53cf052ed00ba8c2e6cae4d2cd", 774 | "sha256:8361c90701fc6ff5f16c81c969563c6915402fbecb2ddc9c5063fec0238e5e52", 775 | "sha256:844040d44cc4320cdffb258fe03768ff0b37e710d56a70dd1f6c2902738f1e28", 776 | "sha256:8698db54fd49af74333190fb154448dcfc67a382aa2b2d784ffe981b7cf421ec", 777 | "sha256:8988209d5efae9b5c9297fb48d153e2528384c1afe2c9fd8eeb474cd6e765199", 778 | "sha256:8a43105683a66de78489b30037b97c9ce5f821f57035f6944f633bbd4baadd15", 779 | "sha256:8a93abd67a46c6b91f28a7513b9f8b9a5432fd573c3d6444c083e07209bf96e4", 780 | "sha256:8ea1861512c7f32d0c585119a2caea6665eec6df429abf5810826b0df9587de1", 781 | "sha256:99bb8cff279f7d1f516919d82b35ed0796c53ce7da7dca191fabfa4c53f47740", 782 | "sha256:9ed10f5a942a2903a722d63806b7a9d2e0a966c038100dc763483d8fbe8ea074", 783 | "sha256:a5b9471e5e507f51f4c0acabec60a7ae2ea218ac6134a8e5ec5674845347a63a", 784 | "sha256:a5cdbede23aae133e50f786adc4a2cacf60bddde649e3dc122c32368daa2c007", 785 | "sha256:aa6d0dfa94ce89d050dca0104389e10c537715bf10e5b0bfe5ece79f17f1719e", 786 | "sha256:adbf2bb11a616210735d6a112186d378f7934be3f2935e6d9dd760c110840c3a", 787 | "sha256:ae33cb195304ac16996184b115f9e27eb9f0b14062e97fbd1d446e3e4a594ff0", 788 | "sha256:b1ef471c62c3d0681cfbaa8bbaf96f22e20cafd391ecad8a43317f6b1598478e", 789 | "sha256:b94a3453a18bb914b2cac1ac38c09f980a3c86a8cd0bb744dd6bd03ab8ff958a", 790 | "sha256:be67e7f48fce8dbefd602f779c7382c874a1a1a3d08f375366c4d28baaa0bfd4", 791 | "sha256:c37c0046d04c0fdd99a9a31d6a9ce7d703cca3b7fdde5738603503dfba58a25f", 792 | "sha256:c6736703c7581d18e3959c1d786035c620def2f096e762aefaf08cfa39844d1e", 793 | "sha256:ce8c61297a751c67062d11e44352e9379da03a90d95aa352395d3b1e53e9f20a", 794 | "sha256:cf6477a083f8a1b54893ad24bc15f94dd0684b02320c69d2a69dcf36f70e73cb", 795 | "sha256:dbb871b22acec52c1b046ef6aa3d16f83618c704772f126a49e7446a0c885278", 796 | "sha256:dbece43299705eca217808759f4322c7cab41db2ba3ad8d7261ee2b17abe6488", 797 | "sha256:dfde6624d3d99d9a67235b60ae13be1a6ffce2f1de3cd2be9900f011d5d6a6a6", 798 | "sha256:e0128c7b723984e31c1b0df5bc532715defd13bf64d8d9eddd7207d093759ae4", 799 | "sha256:e24d7bda7a32ff35d0c914a52dd920a408f73d7e4b93d6755d7c67e819a8cd8c", 800 | "sha256:e9cd5c7449f297a1b53a4803413db907a8cad1178435e2879c1b92816f2bbe56", 801 | "sha256:e9e3fa94fa1e58763a7b824b8e0015d93c9fdd8e449d0218d13d01172e3d1539", 802 | "sha256:eadf1d3841c2155b68ef49147253fd4ac1447a972d01c08248114edc4d3ba9d5", 803 | "sha256:eb3b8acb5dc33ec812d79f35b85fddc43d8f75b65c00c635ee3c0b527e11c8ea", 804 | "sha256:ebdb43e947291c5cb80ef6c7d525f64bc4ed685de43f855ba0cf2b0fd8052e3a", 805 | "sha256:ee24b94b5ae22af9148e597f512fae8383908ca07d3b7f99b349679fede4d7d3", 806 | "sha256:ef4bd725c06d6ee9e502419ceeb5dfaccb6bbe36f359fd0366b90a56b6dae647", 807 | "sha256:f05524f7cfa4f7398259a428fbb22ec4c3f0665c6a303a0d6afdd98457b19af3", 808 | "sha256:f1ddc43cceb500e4a6495250d9d34cac93e6d9e89a46f0e34fcefcc3caf66ef3", 809 | "sha256:f328d28d0a1ea43d7030e1999ced9db252ba4ef2531af3e9bfc135cca77b8324", 810 | "sha256:f355d23a420a6b39241bbef2c803839b01d52d680d89aac39460505e57b2cd03", 811 | "sha256:f81f4065ff8ccd207204129463fd587b25c9f593128176a717dbabc03af9b233", 812 | "sha256:f969214a9ebf1175a8aba863d6f1220174130188686d4ed475d138a240e60c1c", 813 | "sha256:fc21a74f337298840f59f21a12fbf6ec1de798cd69d6b331ef9ed88ac8cb18f0", 814 | "sha256:fc2c363f68bbb9fea6b8137c432c6df9d7c8c76b01549c4410c506dac9e30663", 815 | "sha256:ff4e510a9509d36359c7af4684e73489cdd53c781dd4bc9b07dc808fab56cc48", 816 | "sha256:ff6c9fdbcfb285e28fe35eaf5ba39644cbc65343aa41844217c2b5a99abbdd7e" 817 | ], 818 | "markers": "python_version >= '3.6'", 819 | "version": "==24.0.0" 820 | }, 821 | "six": { 822 | "hashes": [ 823 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", 824 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" 825 | ], 826 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 827 | "version": "==1.16.0" 828 | }, 829 | "stack-data": { 830 | "hashes": [ 831 | "sha256:66d2ebd3d7f29047612ead465b6cae5371006a71f45037c7e2507d01367bce3b", 832 | "sha256:715c8855fbf5c43587b141e46cc9d9339cc0d1f8d6e0f98ed0d01c6cb974e29f" 833 | ], 834 | "version": "==0.5.0" 835 | }, 836 | "tornado": { 837 | "hashes": [ 838 | "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca", 839 | "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72", 840 | "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23", 841 | "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8", 842 | "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b", 843 | "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9", 844 | "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13", 845 | "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75", 846 | "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac", 847 | "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e", 848 | "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b" 849 | ], 850 | "markers": "python_version >= '3.7'", 851 | "version": "==6.2" 852 | }, 853 | "traitlets": { 854 | "hashes": [ 855 | "sha256:3f2c4e435e271592fe4390f1746ea56836e3a080f84e7833f0f801d9613fec39", 856 | "sha256:93663cc8236093d48150e2af5e2ed30fc7904a11a6195e21bab0408af4e6d6c8" 857 | ], 858 | "markers": "python_version >= '3.7'", 859 | "version": "==5.4.0" 860 | }, 861 | "wcwidth": { 862 | "hashes": [ 863 | "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784", 864 | "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83" 865 | ], 866 | "version": "==0.2.5" 867 | } 868 | } 869 | } 870 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Version](https://img.shields.io/pypi/v/nbexec.svg)](https://pypi.python.org/pypi/nbexec) [![Support Python versions](https://img.shields.io/pypi/pyversions/nbexec.svg)](https://pypi.python.org/pypi/nbexec) 2 | 3 | # nbexec 4 | 5 | `nbexec` is a dead-simple tool for executing Jupyter notebooks from the command line. It can run single notebooks, multiple notebooks, and/or an entire directory of notebooks in __one short command__. 6 | 7 | `nbexec` runs your notebook using [Jupyter's (browserless) `nbconvert` execution API](http://nbconvert.readthedocs.io/en/latest/execute_api.html). Then, if the notebook ran without errors, `nbexec` resaves the notebook in place. 8 | 9 | __Note:__ `nbexec` is in the early stages of development. Features may change/break in the future. Pinning your package installation to the current version is advised. 10 | 11 | ## Installation 12 | 13 | ```sh 14 | pip install nbexec 15 | ``` 16 | 17 | ## Basic usage 18 | 19 | To run one notebook: 20 | 21 | ``` sh 22 | nbexec path/to/my/notebook.ipynb 23 | ``` 24 | 25 | To run multiple notebooks: 26 | 27 | ``` sh 28 | nbexec nb-one.ipynb foo/nb-two.ipynb 29 | ``` 30 | 31 | To run all notebooks in the first level of a directory: 32 | 33 | ``` sh 34 | nbexec path/to/directory-of-notebooks 35 | ``` 36 | 37 | To run all notebooks in the first three levels of a directory: 38 | 39 | ``` sh 40 | nbexec --max-depth 3 path/to/directory-of-notebooks 41 | ``` 42 | 43 | ## Command-line options 44 | 45 | ``` 46 | usage: nbexec [-h] [--max-depth MAX_DEPTH] [--timeout TIMEOUT] 47 | [--allow-iopub-timeout] [--record-timing] 48 | [--kernel-name KERNEL_NAME] [--quiet] [--stdout] 49 | notebooks [notebooks ...] 50 | 51 | Execute Jupyter notebooks on the command line. 52 | 53 | positional arguments: 54 | notebooks One or more notebooks, or directories containing 55 | notebooks. 56 | 57 | optional arguments: 58 | -h, --help show this help message and exit 59 | --max-depth MAX_DEPTH 60 | The number of directory levels to scan for notebooks. 61 | (default: 1) 62 | --timeout TIMEOUT How long to wait, in seconds, for any given notebook 63 | cell to before raising an exception. (default: None) 64 | --allow-iopub-timeout 65 | Don't raise an error on IOPub timeouts. (default: 66 | False) 67 | --record-timing Store the execution timings in each cell's metadata. 68 | (default: False) 69 | --kernel-name KERNEL_NAME 70 | The name of the kernel to use, e.g., 'python3'. If 71 | None, nbexec uses the kernel specified in the 72 | notebook. (default: None) 73 | --quiet Don't print notifications, other than errors. 74 | (default: False) 75 | --stdout Instead of saving the notebook in place, pipe the 76 | executed notebook to stdout. This option is not 77 | available if you are executing multiple notebooks at 78 | once. (default: False) 79 | 80 | Note: nbexec uses Jupyter's nbconvert module. See 81 | https://nbconvert.readthedocs.io/en/latest/execute_api.html for context. 82 | ``` 83 | 84 | ## Changelog 85 | 86 | ### v0.2.0 87 | 88 | - By default, do not record cell execution timings. (Use `--record-timing` to record them.) 89 | 90 | ### v0.1.0 91 | 92 | - By default, raise errors on IOPub timeouts. (Use `--allow-iopub-timeout` to prevent raising those errors.) 93 | 94 | ## Possible future features / improvements 95 | 96 | - [ ] Full test coverage 97 | - [ ] [Your idea here] 98 | -------------------------------------------------------------------------------- /nbexec/__init__.py: -------------------------------------------------------------------------------- 1 | from .__version__ import __version__ 2 | -------------------------------------------------------------------------------- /nbexec/__version__.py: -------------------------------------------------------------------------------- 1 | VERSION_TUPLE = (0, 2, 0) 2 | __version__ = ".".join(map(str, VERSION_TUPLE)) 3 | -------------------------------------------------------------------------------- /nbexec/cli.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import sys 3 | import os 4 | import logging 5 | from .core import ( 6 | DEFAULTS, 7 | is_notebook, 8 | exec_nb, 9 | exec_dir, 10 | logger 11 | ) 12 | 13 | def parse_args(args): 14 | parser = argparse.ArgumentParser( 15 | "nbexec", 16 | description = "Execute Jupyter notebooks on the command line.", 17 | epilog = "Note: nbexec uses Jupyter's nbconvert module. See https://nbconvert.readthedocs.io/en/latest/execute_api.html for context.", 18 | formatter_class = argparse.ArgumentDefaultsHelpFormatter, 19 | ) 20 | 21 | parser.add_argument( 22 | "notebooks", 23 | nargs = "+", 24 | help = "One or more notebooks, or directories containing notebooks." 25 | ) 26 | 27 | parser.add_argument( 28 | "--max-depth", 29 | type = int, 30 | default = 1, 31 | help = "The number of directory levels to scan for notebooks." 32 | ) 33 | 34 | parser.add_argument( 35 | "--timeout", 36 | type = int, 37 | default = DEFAULTS["timeout"], 38 | help = "How long to wait, in seconds, for any given notebook cell to before raising an exception." 39 | ) 40 | 41 | parser.add_argument( 42 | "--allow-iopub-timeout", 43 | action = "store_true", 44 | help = "Don't raise an error on IOPub timeouts." 45 | ) 46 | 47 | parser.add_argument( 48 | "--record-timing", 49 | action = "store_true", 50 | help = "Store the execution timings in each cell's metadata." 51 | ) 52 | 53 | parser.add_argument( 54 | "--kernel-name", 55 | default = DEFAULTS["kernel_name"], 56 | help = "The name of the kernel to use, e.g., 'python3'. If None, nbexec uses the kernel specified in the notebook." 57 | ) 58 | 59 | parser.add_argument( 60 | "--quiet", 61 | action = "store_true", 62 | help = "Don't print notifications, other than errors." 63 | ) 64 | 65 | parser.add_argument( 66 | "--stdout", 67 | action = "store_true", 68 | help = "Instead of saving the notebook in place, pipe the executed notebook to stdout. This option is not available if you are executing multiple notebooks at once." 69 | ) 70 | 71 | parsed = parser.parse_args(args) 72 | 73 | if parsed.stdout: 74 | if len(parsed.notebooks) > 1 or not is_notebook(parsed.notebooks[0]): 75 | raise Exception("--stdout argument can only be used when executing a single notebook") 76 | 77 | return parsed 78 | 79 | def run(args_raw): 80 | args = parse_args(args_raw) 81 | 82 | if args.quiet: 83 | logger.setLevel(logging.ERROR) 84 | 85 | for nb_path in args.notebooks: 86 | if is_notebook(nb_path): 87 | exec_nb(nb_path, **vars(args)) 88 | elif os.path.isdir(nb_path): 89 | exec_dir(nb_path, vars(args), args.max_depth, 1) 90 | else: 91 | logger.info("Pathspec '{}' does not appear to be a Jupyter notebook or directory. Skipping.".format(nb_path)) 92 | logger.info("Done.") 93 | 94 | def main(): 95 | run(sys.argv[1:]) 96 | 97 | if __name__ == "__main__": 98 | main() 99 | -------------------------------------------------------------------------------- /nbexec/core.py: -------------------------------------------------------------------------------- 1 | import nbformat 2 | from nbconvert.preprocessors import ExecutePreprocessor 3 | import os 4 | import sys 5 | import json 6 | import logging 7 | 8 | logging.basicConfig( 9 | format = "[%(asctime)s] %(message)s", 10 | datefmt = "%Y-%m-%d %H:%M:%S" 11 | ) 12 | 13 | logger = logging.getLogger("nbexec") 14 | logger.setLevel(logging.INFO) 15 | 16 | DEFAULTS = { 17 | "timeout": None, 18 | "kernel_name": None, 19 | "stdout": False, 20 | "allow_iopub_timeout": True, 21 | "record_timing": False, 22 | } 23 | 24 | class NBExecError(Exception): 25 | pass 26 | 27 | def exec_nb(path, **kwargs): 28 | """ 29 | Take a notebook and run it, using the 30 | command-line arguments (when supplied). 31 | """ 32 | 33 | settings = dict(DEFAULTS) 34 | settings.update(kwargs) 35 | 36 | logger.info("Executing {} ...".format(path)) 37 | with open(path) as f: 38 | nb = nbformat.read(f, nbformat.NO_CONVERT) 39 | 40 | if "kernelspec" not in nb.metadata and settings["kernel_name"] is None: 41 | raise NBExecError("Kernel is neither specified in notebook {} nor supplied via --kernel-name.".format(path)) 42 | 43 | kernel_name = settings["kernel_name"] or nb.metadata.kernelspec.name 44 | 45 | ep = ExecutePreprocessor( 46 | timeout = settings["timeout"], 47 | raise_on_iopub_timeout = not settings["allow_iopub_timeout"], 48 | record_timing = settings["record_timing"], 49 | kernel_name = kernel_name 50 | ) 51 | 52 | ep.preprocess(nb, { 53 | "metadata": { 54 | "path": os.path.dirname(path) 55 | } 56 | }) 57 | 58 | if settings["stdout"]: 59 | json.dump(nb, sys.stdout, indent = 2) 60 | else: 61 | with open(path, "w") as f: 62 | nbformat.write(nb, f) 63 | 64 | def is_notebook(path): 65 | """ 66 | Test (naively) whether a given path represents a Jupyter notebook. 67 | """ 68 | return os.path.isfile(path) and path.split(".")[-1] == "ipynb" 69 | 70 | def exec_dir(path, nb_kwargs, max_depth, current_depth): 71 | """ 72 | Execute all notebooks in a directory, keeping track of how deep 73 | into the initially-specified directory we are. 74 | """ 75 | if max_depth is not None and current_depth > max_depth: 76 | return 77 | 78 | for item in sorted(os.listdir(path)): 79 | full_path = os.path.join(path, item) 80 | if os.path.isdir(full_path): 81 | exec_dir(full_path, nb_kwargs, max_depth, current_depth + 1) 82 | elif is_notebook(full_path): 83 | exec_nb(full_path, **nb_kwargs) 84 | else: 85 | pass 86 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | import os 3 | 4 | NAME = "nbexec" 5 | HERE = os.path.abspath(os.path.dirname(__file__)) 6 | 7 | version_ns = {} 8 | with open(os.path.join(HERE, NAME, '__version__.py')) as f: 9 | exec(f.read(), {}, version_ns) 10 | 11 | setup( 12 | name = NAME, 13 | version = version_ns['__version__'], 14 | description = "A dead-simple tool for executing Jupyter notebooks from the command line.", 15 | url = "http://github.com/jsvine/nbexec", 16 | author = "Jeremy Singer-Vine", 17 | author_email = "jsvine@gmail.com", 18 | license = "MIT", 19 | keywords = "jupyter", 20 | packages = [ 21 | NAME 22 | ], 23 | install_requires = [ 24 | "jupyter_client", 25 | "nbformat", 26 | "nbconvert" 27 | ], 28 | entry_points = { 29 | "console_scripts": [ 30 | "nbexec = nbexec.cli:main" 31 | ] 32 | }, 33 | classifiers = [ 34 | "License :: OSI Approved :: MIT License", 35 | "Operating System :: OS Independent", 36 | "Programming Language :: Python :: 3", 37 | "Intended Audience :: Developers", 38 | "Topic :: Scientific/Engineering :: Information Analysis", 39 | ], 40 | ) 41 | -------------------------------------------------------------------------------- /test/notebooks/simple-with-kernelspec.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# A very simple example" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false, 15 | "execution": { 16 | "iopub.execute_input": "2022-08-04T15:01:43.842682Z", 17 | "iopub.status.busy": "2022-08-04T15:01:43.842193Z", 18 | "iopub.status.idle": "2022-08-04T15:01:43.852832Z", 19 | "shell.execute_reply": "2022-08-04T15:01:43.852207Z" 20 | } 21 | }, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "1\n" 28 | ] 29 | } 30 | ], 31 | "source": [ 32 | "print(1)" 33 | ] 34 | } 35 | ], 36 | "metadata": { 37 | "kernelspec": { 38 | "display_name": "Python 3", 39 | "language": "python", 40 | "name": "python3" 41 | }, 42 | "language_info": { 43 | "codemirror_mode": { 44 | "name": "ipython", 45 | "version": 3 46 | }, 47 | "file_extension": ".py", 48 | "mimetype": "text/x-python", 49 | "name": "python", 50 | "nbconvert_exporter": "python", 51 | "pygments_lexer": "ipython3", 52 | "version": "3.9.13" 53 | } 54 | }, 55 | "nbformat": 4, 56 | "nbformat_minor": 1 57 | } 58 | -------------------------------------------------------------------------------- /test/notebooks/simple-without-kernelspec.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# A very simple example" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": 1, 13 | "metadata": { 14 | "collapsed": false, 15 | "execution": { 16 | "iopub.execute_input": "2022-08-04T15:01:45.414642Z", 17 | "iopub.status.busy": "2022-08-04T15:01:45.414183Z", 18 | "iopub.status.idle": "2022-08-04T15:01:45.424494Z", 19 | "shell.execute_reply": "2022-08-04T15:01:45.423949Z" 20 | } 21 | }, 22 | "outputs": [ 23 | { 24 | "name": "stdout", 25 | "output_type": "stream", 26 | "text": [ 27 | "1\n" 28 | ] 29 | } 30 | ], 31 | "source": [ 32 | "print(1)" 33 | ] 34 | } 35 | ], 36 | "metadata": { 37 | "language_info": { 38 | "codemirror_mode": { 39 | "name": "ipython", 40 | "version": 3 41 | }, 42 | "file_extension": ".py", 43 | "mimetype": "text/x-python", 44 | "name": "python", 45 | "nbconvert_exporter": "python", 46 | "pygments_lexer": "ipython3", 47 | "version": "3.9.13" 48 | } 49 | }, 50 | "nbformat": 4, 51 | "nbformat_minor": 0 52 | } 53 | -------------------------------------------------------------------------------- /test/test_basics.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import nbexec 3 | from nbexec.core import NBExecError 4 | from nbexec.cli import parse_args, run 5 | import sys 6 | import os 7 | 8 | HERE = os.path.dirname(os.path.abspath(__file__)) 9 | 10 | NBPATHS = [ 11 | "simple-with-kernelspec.ipynb", 12 | "simple-without-kernelspec.ipynb" 13 | ] 14 | 15 | notbook_dir = os.path.join(HERE, "notebooks") 16 | 17 | notebooks = [ os.path.join(HERE, "notebooks", path) 18 | for path in NBPATHS ] 19 | 20 | class NBExecTest(unittest.TestCase): 21 | 22 | def test_version(self): 23 | nbexec.__version__ 24 | 25 | def test_basic(self): 26 | run([ notebooks[0] ]) 27 | 28 | def test_kernelspec_error(self): 29 | with self.assertRaises(NBExecError) as context: 30 | run([ notebooks[1] ]) 31 | run([ notebooks[1], "--kernel-name", "python3" ]) 32 | 33 | def test_dir(self): 34 | run([ notbook_dir, "--kernel-name", "python3" ]) 35 | 36 | if __name__ == '__main__': 37 | unittest.main() 38 | --------------------------------------------------------------------------------