Skip to content

Commit

Permalink
optional parameters (#193)
Browse files Browse the repository at this point in the history
  • Loading branch information
dsavchenko authored Aug 2, 2024
1 parent 14791cc commit b6d3e39
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 7 deletions.
5 changes: 5 additions & 0 deletions nb2workflow/nbadapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ def cast_parameter(x,par):
raise ValueError
except:
raise ValueError(f'Parameter {par["name"]} value "{x}" can not be interpreted as {par["python_type"].__name__}.')
if x == '\x00':
if par.get('is_optional', False):
return None
else:
raise ValueError(f'Non-optional parameter is set to None')
return par['python_type'](x)


Expand Down
12 changes: 10 additions & 2 deletions nb2workflow/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,12 @@ def __call__(self, environ, start_response):
def create_app():
app = Flask(__name__)

app.config['SWAGGER'] = {
'uiversion': 3,
"openapi": "3.0.3",
}
template = {
"swaggerUiPrefix": LazyString(lambda: request.environ.get('HTTP_X_FORWARDED_PREFIX', '')),
"swagger": "2.0",
"info": {
"title": "ODAHub API",
"description": "",
Expand Down Expand Up @@ -438,7 +441,12 @@ def setup_routes(app):
{
"name": p_name,
"in": "query",
"type": to_oapi_type(p_data['python_type']),
"schema": {
"type": to_oapi_type(p_data['python_type']),
"nullable": p_data.get('is_optional', False)
# strictly speaking, there is no way to set query parameter to null
# we define a convention in which '%00' string represents null
},
"required": False,
"default": p_data['default_value'],
"description": p_data['comment']+" "+p_data['owl_type'],
Expand Down
13 changes: 8 additions & 5 deletions tests/test_input_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ def test_dict_wrong(client):
({'inten': 20}, {'inten': 20}),
({'flag': False}, {'flag': False}),
({'flag': 0}, {'flag': False}),
({'string_param': 'contains = symbol'}, {'string_param': 'contains = symbol'})
({'string_param': 'contains = symbol'}, {'string_param': 'contains = symbol'}),
({'otheropt': '\x00'}, {'otheropt': None})
])
def test_type_casting(client, inp, outp):
r = client.get('/api/v1.0/options')
Expand All @@ -144,12 +145,14 @@ def test_type_casting(client, inp, outp):
for k, v in outp.items():
assert isinstance(r.json['output']['echo'][k], type(v))

def test_casting_invalid(client):
r = client.get('/api/v1.0/get/multiline', query_string={'inten': 20.1})
@pytest.mark.parametrize('query', [{'inten': 20.1}, {'intfloat': '\x00'}])
def test_casting_invalid(client, query):
r = client.get('/api/v1.0/get/multiline', query_string=query)
assert len(r.json['issues']) > 0

# async
r=client.get('/api/v1.0/get/multiline', query_string={'inten': 20.1,
'_async_request': 'yes'})
query.update({'_async_request': 'yes'})
r=client.get('/api/v1.0/get/multiline',
query_string=query)
assert len(r.json['data']['exceptions']) > 0

2 changes: 2 additions & 0 deletions tests/testfiles/multiline.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
" 'spam': ['ham', 'eggs']} # oda:StructuredParameter\n",
"\n",
"opt: float|None = None\n",
"otheropt = 5 # oda:optional\n",
"intfloat = 10 # oda:Float\n",
"inten: int = 45 # oda:Energy \n",
"# NOTE: won't work with dispatcher, because energy is always float there\n",
Expand All @@ -45,6 +46,7 @@
" but multiline string\"\"\"\n",
"echo = dict(mline = mline,\n",
" opt = opt,\n",
" otheropt = otheropt,\n",
" intfloat = intfloat,\n",
" inten = inten,\n",
" string_param = string_param,\n",
Expand Down

0 comments on commit b6d3e39

Please sign in to comment.