update OAProc content models (#735)
This commit is contained in:
@@ -65,11 +65,11 @@ Processing examples
|
||||
- show all jobs for the ``hello-world`` process
|
||||
- http://localhost:5000/processes/hello-world/jobs
|
||||
- execute a job for the ``hello-world`` process
|
||||
- ``curl -X POST "http://localhost:5000/processes/hello-world/jobs" -H "Content-Type: application/json" -d "{\"inputs\":[{\"id\":\"name\",\"type\":\"text/plain\",\"value\":\"hi there2\"}]}"``
|
||||
- ``curl -X POST "http://localhost:5000/processes/hello-world/execution" -H "Content-Type: application/json" -d "{\"inputs\":{\"name\": \"hi there2\"}}"``
|
||||
- execute a job for the ``hello-world`` process with a raw response
|
||||
- ``curl -X POST "http://localhost:5000/processes/hello-world/jobs?response=raw" -H "Content-Type: application/json" -d "{\"inputs\":[{\"id\":\"name\",\"type\":\"text/plain\",\"value\":\"hi there2\"}]}"``
|
||||
- ``curl -X POST "http://localhost:5000/processes/hello-world/execution?response=raw" -H "Content-Type: application/json" -d "{\"inputs\":{\"name\": \"hi there2\"}}"``
|
||||
- execute a job for the ``hello-world`` process in asynchronous mode
|
||||
- ``curl -X POST "http://localhost:5000/processes/hello-world/jobs" -H "Content-Type: application/json" -d "{\"mode\": \"async\", \"inputs\":[{\"id\":\"name\",\"type\":\"text/plain\",\"value\":\"hi there2\"}]}"``
|
||||
- ``curl -X POST "http://localhost:5000/processes/hello-world/execution" -H "Content-Type: application/json" -d "{\"mode\": \"async\", \"inputs\":{\"name\": \"hi there2\"}}"``
|
||||
|
||||
.. todo:: add more examples once OAProc implementation is complete
|
||||
|
||||
|
||||
+10
-8
@@ -2642,15 +2642,13 @@ class API:
|
||||
|
||||
try:
|
||||
data_dict = {}
|
||||
for input_ in data.get('inputs', []):
|
||||
id_ = input_['id']
|
||||
value = input_['value']
|
||||
if id_ not in data_dict:
|
||||
data_dict[id_] = value
|
||||
elif id_ in data_dict and isinstance(data_dict[id_], list):
|
||||
data_dict[id_].append(value)
|
||||
for key, value in data.get('inputs', {}).items():
|
||||
if key not in data_dict:
|
||||
data_dict[key] = value
|
||||
elif key in data_dict and isinstance(data_dict[key], list):
|
||||
data_dict[key].append(value)
|
||||
else:
|
||||
data_dict[id_] = [data_dict[id_], value]
|
||||
data_dict[key] = [data_dict[key], value]
|
||||
except KeyError:
|
||||
# Return 4XX client error for missing 'id' or 'value' in an input
|
||||
msg = 'invalid request data'
|
||||
@@ -2669,6 +2667,10 @@ class API:
|
||||
if is_async:
|
||||
LOGGER.debug('Asynchronous request mode detected')
|
||||
|
||||
if is_async and not self.manager.is_async:
|
||||
LOGGER.debug('async manager not configured/enabled')
|
||||
is_async = False
|
||||
|
||||
try:
|
||||
LOGGER.debug('Executing process')
|
||||
mime_type, outputs, status = self.manager.execute_process(
|
||||
|
||||
@@ -58,61 +58,47 @@ PROCESS_METADATA = {
|
||||
'href': 'https://example.org/process',
|
||||
'hreflang': 'en-US'
|
||||
}],
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'title': 'Name',
|
||||
'abstract': 'The name of the person or entity that you wish to be'
|
||||
'echoed back as an output',
|
||||
'input': {
|
||||
'literalDataDomain': {
|
||||
'dataType': 'string',
|
||||
'valueDefinition': {
|
||||
'anyValue': True
|
||||
}
|
||||
}
|
||||
'inputs': {
|
||||
'name': {
|
||||
'title': 'Name',
|
||||
'description': 'The name of the person or entity that you wish to'
|
||||
'be echoed back as an output',
|
||||
'schema': {
|
||||
'type': 'string'
|
||||
},
|
||||
'minOccurs': 1,
|
||||
'maxOccurs': 1,
|
||||
'metadata': None, # TODO how to use?
|
||||
'keywords': ['full name', 'personal']
|
||||
},
|
||||
'minOccurs': 1,
|
||||
'maxOccurs': 1,
|
||||
'metadata': None, # TODO how to use?
|
||||
'keywords': ['full name', 'personal']
|
||||
}, {
|
||||
'id': 'message',
|
||||
'title': 'Message',
|
||||
'abstract': 'An optional message to echo as well',
|
||||
'input': {
|
||||
'literalDataDomain': {
|
||||
'dataType': 'string',
|
||||
'valueDefinition': {
|
||||
'anyValue': True
|
||||
}
|
||||
}
|
||||
},
|
||||
'minOccurs': 0,
|
||||
'maxOccurs': 1,
|
||||
'metadata': None,
|
||||
'keywords': ['message']
|
||||
}],
|
||||
'outputs': [{
|
||||
'id': 'echo',
|
||||
'title': 'Hello, world',
|
||||
'description': 'A "hello world" echo with the name and (optional)'
|
||||
'message submitted for processing',
|
||||
'output': {
|
||||
'formats': [{
|
||||
'mimeType': 'application/json'
|
||||
}]
|
||||
'message': {
|
||||
'title': 'Message',
|
||||
'description': 'An optional message to echo as well',
|
||||
'schema': {
|
||||
'type': 'string'
|
||||
},
|
||||
'minOccurs': 0,
|
||||
'maxOccurs': 1,
|
||||
'metadata': None,
|
||||
'keywords': ['message']
|
||||
}
|
||||
}],
|
||||
},
|
||||
'outputs': {
|
||||
'echo': {
|
||||
'title': 'Hello, world',
|
||||
'description': 'A "hello world" echo with the name and (optional)'
|
||||
' message submitted for processing',
|
||||
'schema': {
|
||||
'type': 'object',
|
||||
'contentMediaType': 'application/json'
|
||||
}
|
||||
}
|
||||
},
|
||||
'example': {
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'value': 'World',
|
||||
'type': 'text/plain'
|
||||
}, {
|
||||
'id': 'message',
|
||||
'value': 'An optional message.',
|
||||
'type': 'text/plain'
|
||||
}]
|
||||
'inputs': {
|
||||
'name': 'World',
|
||||
'messsage': 'An optional message.',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,27 +27,19 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for input_ in data['inputs'] %}
|
||||
{% for key, value in data['inputs'].items() %}
|
||||
<tr itemprop="parameter" itemscope>
|
||||
<td itemprop="id" data-label="ID">
|
||||
{{ input_.id }}
|
||||
{{ key }}
|
||||
</td>
|
||||
<td itemprop="name" data-label="Title">
|
||||
{{ input_.title|striptags|truncate }}
|
||||
{{ value.title|striptags|truncate }}
|
||||
</td>
|
||||
<td itemprop="name" data-label="Title">
|
||||
{% with literalDataDomain = input_.input.literalDataDomain %}
|
||||
{% if literalDataDomain %}
|
||||
{{ literalDataDomain.dataType }}
|
||||
{% else %}
|
||||
{% for format in input_.input.formats %}
|
||||
{{ format.mimeType }}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
<td itemprop="name" data-label="Data Type">
|
||||
{{ value.schema.type }}
|
||||
</td>
|
||||
<td itemprop="description" data-label="Description">
|
||||
{{ input_.abstract }}
|
||||
{{ value.description }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
@@ -65,12 +57,12 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for output_ in data['outputs'] %}
|
||||
{% for key, value in data['outputs'].items() %}
|
||||
<tr itemprop="parameter" itemscope>
|
||||
<td itemprop="id" data-label="ID">{{ output_['id'] }}</td>
|
||||
<td itemprop="name" data-label="Title">{{ output_['title'] }}</td>
|
||||
<td itemprop="id" data-label="ID">{{ key }}</td>
|
||||
<td itemprop="name" data-label="Title">{{ value.title }}</td>
|
||||
<td itemprop="description" data-label="Description">
|
||||
{{ output_['description'] | striptags | truncate }}
|
||||
{{ value.description | striptags | truncate }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
+23
-60
@@ -1047,50 +1047,33 @@ def test_describe_processes(config, api_):
|
||||
|
||||
def test_execute_process(config, api_):
|
||||
req_body = {
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'value': 'Test'
|
||||
}]
|
||||
'inputs': {
|
||||
'name': 'Test'
|
||||
}
|
||||
}
|
||||
req_body_2 = {
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'value': 'Tést'
|
||||
}]
|
||||
'inputs': {
|
||||
'name': 'Tést'
|
||||
}
|
||||
}
|
||||
req_body_3 = {
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'value': 'Tést'
|
||||
}, {
|
||||
'id': 'message',
|
||||
'value': 'This is a test.'
|
||||
}]
|
||||
'inputs': {
|
||||
'name': 'Tést',
|
||||
'message': 'This is a test.'
|
||||
}
|
||||
}
|
||||
req_body_4 = {
|
||||
'inputs': [{
|
||||
'id': 'foo',
|
||||
'value': 'Tést'
|
||||
}]
|
||||
'inputs': {
|
||||
'foo': 'Tést'
|
||||
}
|
||||
}
|
||||
req_body_5 = {
|
||||
'inputs': []
|
||||
'inputs': {}
|
||||
}
|
||||
req_body_6 = {
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'value': None
|
||||
}]
|
||||
}
|
||||
req_body_7 = {
|
||||
'inputs': [{
|
||||
'id': 'name'
|
||||
}]
|
||||
}
|
||||
req_body_8 = {
|
||||
'inputs': [{
|
||||
'value': 'Test'
|
||||
}]
|
||||
'inputs': {
|
||||
'name': None
|
||||
}
|
||||
}
|
||||
|
||||
cleanup_jobs = set()
|
||||
@@ -1180,24 +1163,6 @@ def test_execute_process(config, api_):
|
||||
cleanup_jobs.add(tuple(['hello-world',
|
||||
rsp_headers['Location'].split('/')[-1]]))
|
||||
|
||||
req = mock_request(data=req_body_7)
|
||||
rsp_headers, code, response = api_.execute_process(req, 'hello-world')
|
||||
|
||||
data = json.loads(response)
|
||||
assert code == 400
|
||||
assert 'Location' not in rsp_headers
|
||||
assert data['code'] == 'InvalidParameterValue'
|
||||
assert data['description'] == 'invalid request data'
|
||||
|
||||
req = mock_request(data=req_body_8)
|
||||
rsp_headers, code, response = api_.execute_process(req, 'hello-world')
|
||||
|
||||
data = json.loads(response)
|
||||
assert code == 400
|
||||
assert 'Location' not in rsp_headers
|
||||
assert data['code'] == 'InvalidParameterValue'
|
||||
assert data['description'] == 'invalid request data'
|
||||
|
||||
req = mock_request(data=req_body)
|
||||
rsp_headers, code, response = api_.execute_process(req, 'goodbye-world')
|
||||
|
||||
@@ -1241,18 +1206,16 @@ def test_delete_process_job(api_):
|
||||
assert code == 404
|
||||
|
||||
req_body_sync = {
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'value': 'Sync Test Deletion'
|
||||
}]
|
||||
'inputs': {
|
||||
'name': 'Sync Test Deletion'
|
||||
}
|
||||
}
|
||||
|
||||
req_body_async = {
|
||||
'mode': 'async',
|
||||
'inputs': [{
|
||||
'id': 'name',
|
||||
'value': 'Async Test Deletion'
|
||||
}]
|
||||
'inputs': {
|
||||
'name': 'Async Test Deletion'
|
||||
}
|
||||
}
|
||||
|
||||
req = mock_request(data=req_body_sync)
|
||||
|
||||
Reference in New Issue
Block a user