Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

I7 parameters #14

Merged
merged 54 commits into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from 48 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
20421cb
add wps_Convolution.py
sum1lim Jul 16, 2020
b22ac3d
wps_convolution added to __init__.py
sum1lim Jul 16, 2020
fd035f7
add rvic to requirements.txt
sum1lim Jul 16, 2020
ebc4d28
add demo_convolution
sum1lim Jul 16, 2020
1d872bd
Add wps_parameters.py
Jul 17, 2020
7e6d7f5
wps_convolution takes .cfg input and produces .nc output
sum1lim Jul 17, 2020
3ca2375
use helper-functions of convolution rather than calling convolution()
sum1lim Jul 17, 2020
1d9eadc
dynamic determination of output filepath
sum1lim Jul 17, 2020
0b4a2cc
back to using convolution()
sum1lim Jul 17, 2020
e96411c
Add test_wps_parameters.py and sample parameters
Jul 17, 2020
5ed025d
modification to fit RVIC 1.1.0.post1
sum1lim Jul 20, 2020
c6efd85
fixed bug in outputting
sum1lim Jul 21, 2020
20799ad
config files in tests/data/configs
sum1lim Jul 21, 2020
de8c13d
add test_wps_convolution.py
sum1lim Jul 22, 2020
b1487e8
dynamic definition for config filepath
sum1lim Jul 22, 2020
b1764e9
run_wps_process moved to common.py
Jul 23, 2020
daab9b0
config input is a str not a file
sum1lim Jul 24, 2020
092de15
delete unnecessary test file
sum1lim Jul 24, 2020
b31f57e
test_wps_convolution marked as slow and online
sum1lim Jul 24, 2020
fd5f6a8
black applied on common.py
sum1lim Jul 24, 2020
a04add0
move demo_requirements to requirements_dev
sum1lim Jul 24, 2020
decb3a5
revert test_wps_caps.py
sum1lim Jul 24, 2020
4df6c62
delete wps_say_hello
sum1lim Jul 24, 2020
51b99c6
different pathways depending on rvic version
sum1lim Jul 24, 2020
9f874ce
pin rvic version
sum1lim Jul 24, 2020
9b3dcd8
use lower case letters for variables
sum1lim Jul 24, 2020
98102d1
logging out messages
sum1lim Jul 24, 2020
0afd3a0
set curr_dir to osprey
sum1lim Jul 24, 2020
0c35042
Add rvic and notebook requirements to requirements files
Jul 24, 2020
0f4ae91
Update imported module names in wps_parameters
Jul 24, 2020
9e2f3c9
Only use local config file in pytest
Jul 24, 2020
699f565
Add demo notebook
Jul 24, 2020
3b1006c
Replace convolution with parameters in comment
Jul 24, 2020
0bb9ef3
Format test_wps_parameters with black
Jul 24, 2020
7c8c2bf
update demo
sum1lim Jul 27, 2020
af5d035
fix typo in jupyter demo
sum1lim Jul 30, 2020
b2a2012
Merge pull request #13 from pacificclimate/i8-wrap-convolution
sum1lim Jul 31, 2020
04b87ae
Add wps_parameters.py
Jul 17, 2020
a3ea52a
Add test_wps_parameters.py and sample parameters
Jul 17, 2020
1976e9f
Update imported module names in wps_parameters
Jul 24, 2020
36f5359
Only use local config file in pytest
Jul 24, 2020
1364423
Add demo notebook
Jul 24, 2020
59d6417
Replace convolution with parameters in comment
Jul 24, 2020
73aac17
Format test_wps_parameters with black
Jul 24, 2020
22e3bb2
Merge branch 'i7-parameters' of https://github.com/pacificclimate/osp…
Aug 4, 2020
fd1e6dc
Use json.loads instead of eval and use fewer percentage steps
Aug 4, 2020
065a8a6
Update wps_parameters to use wps-tools
Aug 11, 2020
6dbed3a
Show successful parameters demo and move to demo_individual directory
Aug 11, 2020
5482670
Remove pytest from CI workflow
Aug 11, 2020
d94c5db
Format with black
Aug 11, 2020
2f04700
Add parameters to test_wps_caps
Aug 11, 2020
2a7c0ef
Comment out instead of remove pytest in CI workflow
Aug 11, 2020
52c68c2
Move version import to top of file
Aug 11, 2020
497e5a3
Use temporary config file for wps_parameters
Aug 11, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
229 changes: 229 additions & 0 deletions notebooks/demo_individual/demo_convolution.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from birdy import WPSClient\n",
"from pkg_resources import resource_filename\n",
"\n",
"import requests"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os \n",
"while os.path.basename(os.getcwd()) != \"osprey\": # Ensure current directory is always 'osprey'\n",
" os.chdir('../')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Set up wps application\n",
"url = 'http://localhost:5002/wps'\n",
"osprey = WPSClient(url=url)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mType:\u001b[0m WPSClient\n",
"\u001b[0;31mString form:\u001b[0m <birdy.client.base.WPSClient object at 0x7f83da86d390>\n",
"\u001b[0;31mFile:\u001b[0m ~/Desktop/osprey/venv/lib/python3.7/site-packages/birdy/client/base.py\n",
"\u001b[0;31mDocstring:\u001b[0m \n",
"A Web Processing Service for Climate Data Analysis.\n",
"\n",
"Processes\n",
"---------\n",
"\n",
"convolution\n",
" Aggregates the flow contribution from all upstream grid cellsat every timestep lagged according the Impuls Response Functions.\n",
"\u001b[0;31mClass docstring:\u001b[0m\n",
"Returns a class where every public method is a WPS process available at\n",
"the given url.\n",
"\n",
"Example:\n",
" >>> emu = WPSClient(url='<server url>')\n",
" >>> emu.hello('stranger')\n",
" 'Hello stranger'\n",
"\u001b[0;31mInit docstring:\u001b[0m \n",
"Args:\n",
" url (str): Link to WPS provider. config (Config): an instance\n",
" processes: Specify a subset of processes to bind. Defaults to all\n",
" processes.\n",
" converters (dict): Correspondence of {mimetype: class} to convert\n",
" this mimetype to a python object.\n",
" username (str): passed to :class:`owslib.wps.WebProcessingService`\n",
" password (str): passed to :class:`owslib.wps.WebProcessingService`\n",
" headers (str): passed to :class:`owslib.wps.WebProcessingService`\n",
" auth (requests.auth.AuthBase): requests-style auth class to authenticate,\n",
" see https://2.python-requests.org/en/master/user/authentication/\n",
" verify (bool): passed to :class:`owslib.wps.WebProcessingService`\n",
" cert (str): passed to :class:`owslib.wps.WebProcessingService`\n",
" verbose (str): passed to :class:`owslib.wps.WebProcessingService`\n",
" progress (bool): If True, enable interactive user mode.\n",
" version (str): WPS version to use.\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Check wps info\n",
"osprey?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"\u001b[0;31mSignature:\u001b[0m \u001b[0mosprey\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconvolution\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconfig\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloglevel\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'INFO'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mDocstring:\u001b[0m\n",
"Aggregates the flow contribution from all upstream grid cellsat every timestep lagged according the Impuls Response Functions.\n",
"\n",
"Parameters\n",
"----------\n",
"config : string\n",
" Path to input configuration file or input dictionary\n",
"loglevel : {'CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'}string\n",
" Logging level\n",
"\n",
"Returns\n",
"-------\n",
"output : ComplexData:mimetype:`application/x-netcdf`\n",
" Output Netcdf File\n",
"\u001b[0;31mFile:\u001b[0m ~/Desktop/osprey/</home/sangwonl/Desktop/osprey/venv/lib/python3.7/site-packages/birdy/client/base.py-1>\n",
"\u001b[0;31mType:\u001b[0m method\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Check info on `convolution` process\n",
"osprey.convolution?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/home/sangwonl/Desktop/osprey/tests/configs/convolve_opendap.cfg\n"
]
}
],
"source": [
"cfg_file = resource_filename(\"tests\", \"configs/convolve_opendap.cfg\")\n",
"print(cfg_file)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"ename": "HTTPError",
"evalue": "500 Server Error: INTERNAL SERVER ERROR for url: http://localhost:5002/wps",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mHTTPError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-18-0e0dd8b97e55>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# generate convolution\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m output = osprey.convolution(\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mconfig\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcfg_file\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m )\n",
"\u001b[0;32m</home/sangwonl/Desktop/osprey/venv/lib/python3.7/site-packages/birdy/client/base.py-1>\u001b[0m in \u001b[0;36mconvolution\u001b[0;34m(self, config, loglevel)\u001b[0m\n",
"\u001b[0;32m~/Desktop/osprey/venv/lib/python3.7/site-packages/birdy/client/base.py\u001b[0m in \u001b[0;36m_execute\u001b[0;34m(self, pid, **kwargs)\u001b[0m\n\u001b[1;32m 291\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 292\u001b[0m wps_response = self._wps.execute(\n\u001b[0;32m--> 293\u001b[0;31m \u001b[0mpid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mwps_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moutput\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mwps_outputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmode\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mmode\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 294\u001b[0m )\n\u001b[1;32m 295\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Desktop/osprey/venv/lib/python3.7/site-packages/owslib/wps.py\u001b[0m in \u001b[0;36mexecute\u001b[0;34m(self, identifier, inputs, output, mode, lineage, request, response)\u001b[0m\n\u001b[1;32m 357\u001b[0m \u001b[0;31m# submit the request to the live server\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 358\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mresponse\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 359\u001b[0;31m \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mexecution\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubmitRequest\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrequest\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 360\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 361\u001b[0m \u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0metree\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfromstring\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresponse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Desktop/osprey/venv/lib/python3.7/site-packages/owslib/wps.py\u001b[0m in \u001b[0;36msubmitRequest\u001b[0;34m(self, request)\u001b[0m\n\u001b[1;32m 910\u001b[0m \u001b[0mreader\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mWPSExecuteReader\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mverbose\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mverbose\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtimeout\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtimeout\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mauth\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauth\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 911\u001b[0m response = reader.readFromUrl(\n\u001b[0;32m--> 912\u001b[0;31m self.url, request, method='Post', headers=self.headers)\n\u001b[0m\u001b[1;32m 913\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mresponse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 914\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Desktop/osprey/venv/lib/python3.7/site-packages/owslib/wps.py\u001b[0m in \u001b[0;36mreadFromUrl\u001b[0;34m(self, url, data, method, username, password, headers, verify, cert)\u001b[0m\n\u001b[1;32m 601\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 602\u001b[0m return self._readFromUrl(url, data, self.timeout, method, username=username, password=password,\n\u001b[0;32m--> 603\u001b[0;31m headers=headers, verify=verify, cert=cert)\n\u001b[0m\u001b[1;32m 604\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 605\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Desktop/osprey/venv/lib/python3.7/site-packages/owslib/wps.py\u001b[0m in \u001b[0;36m_readFromUrl\u001b[0;34m(self, url, data, timeout, method, username, password, headers, verify, cert)\u001b[0m\n\u001b[1;32m 513\u001b[0m u = openURL(url, data, method='Post',\n\u001b[1;32m 514\u001b[0m \u001b[0musername\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauth\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0musername\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpassword\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mauth\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpassword\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 515\u001b[0;31m headers=headers, verify=self.auth.verify, cert=self.auth.cert, timeout=timeout)\n\u001b[0m\u001b[1;32m 516\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0metree\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfromstring\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mu\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 517\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Desktop/osprey/venv/lib/python3.7/site-packages/owslib/util.py\u001b[0m in \u001b[0;36mopenURL\u001b[0;34m(url_base, data, method, cookies, username, password, timeout, headers, verify, cert, auth)\u001b[0m\n\u001b[1;32m 207\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 208\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstatus_code\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m404\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m500\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m502\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m503\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m504\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# add more if needed\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 209\u001b[0;31m \u001b[0mreq\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mraise_for_status\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 210\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 211\u001b[0m \u001b[0;31m# check for service exceptions without the http header set\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m~/Desktop/osprey/venv/lib/python3.7/site-packages/requests/models.py\u001b[0m in \u001b[0;36mraise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 939\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 940\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 941\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mHTTPError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhttp_error_msg\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresponse\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 942\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 943\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mHTTPError\u001b[0m: 500 Server Error: INTERNAL SERVER ERROR for url: http://localhost:5002/wps"
]
}
],
"source": [
"# generate convolution\n",
"output = osprey.convolution(\n",
" config = cfg_file\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"convolutionResponse(\n",
" output='http://localhost:5002/outputs/005d478c-cc6b-11ea-abd3-503eaa25cee0/sample.rvic.h0a.2013-01-01.nc'\n",
")"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"output.get()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Loading