wscall: allow extra data on POST (#6622)
This commit is contained in:
parent
d24711a7f0
commit
fd9526cd80
|
@ -15,7 +15,7 @@
|
|||
|
||||
<p>
|
||||
Cette action permet d'appeler un système tiers et d'éventuellement lui
|
||||
transmettre les données du formulaire en cours.
|
||||
transmettre des données, dont celles du formulaire en cours.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
@ -36,6 +36,51 @@ format JSON, comme décrit dans cette <link xref="api-get#pull">page sur
|
|||
l'API</link>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Le tableau « Données à envoyer en POST » permet de décrire des données qui
|
||||
seront transmises sous la forme d'un dictionnaire clé-valeur au format JSON.
|
||||
Sur chaque ligne, la colonne de gauche est le nom de la clé, celle de droite la
|
||||
valeur. La valeur peut être une expression Python, pour cela elle doit
|
||||
commencer par le signe « = ».
|
||||
</p>
|
||||
|
||||
<example>
|
||||
|
||||
<p>Ce tableau de valeurs :</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td><p><code>code_appel</code></p></td>
|
||||
<td><p><code>w.c.s.</code></p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><p><code>form_number</code></p></td>
|
||||
<td><p><code>=form_number</code></p></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>formera ce JSON :</p>
|
||||
<code>
|
||||
{
|
||||
"code_appel": "w.c.s.",
|
||||
"form_number": "4"
|
||||
}
|
||||
</code>
|
||||
</example>
|
||||
|
||||
<note>
|
||||
<list>
|
||||
<item><p>
|
||||
Si la case « Envoyer le formulaire (POST, en JSON) » est cochée et que des
|
||||
« Données à envoyer en POST » sont indiquées, alors ces dernières sont ajoutées
|
||||
dans le JSON du formulaire, dans une clé « extra ».
|
||||
</p></item>
|
||||
<item><p>
|
||||
Si aucune donnée n'est indiquée et que le formulaire ne doit pas être transmis,
|
||||
alors la requête HTTP effectuée est un GET sur l'URL.
|
||||
</p></item>
|
||||
</list>
|
||||
</note>
|
||||
|
||||
<p>
|
||||
Le paramètre « Nom de variable » permet d'enregistrer le résultat retourné
|
||||
par le webservice, le retour HTTP de celui-ci sera enregistré dans
|
||||
|
|
|
@ -400,6 +400,9 @@ def test_webservice_call(pub):
|
|||
item.perform(formdata)
|
||||
assert http_requests.get_last('url') == 'http://remote.example.net'
|
||||
assert http_requests.get_last('method') == 'POST'
|
||||
payload = json.loads(http_requests.get_last('body'))
|
||||
assert payload['url'].startswith('http://example.net/baz-')
|
||||
assert int(payload['display_id']) == 1
|
||||
|
||||
item = WebserviceCallStatusItem()
|
||||
item.url = 'http://remote.example.net'
|
||||
|
@ -408,6 +411,31 @@ def test_webservice_call(pub):
|
|||
assert http_requests.get_last('url') == 'http://remote.example.net'
|
||||
assert http_requests.get_last('method') == 'GET'
|
||||
|
||||
item = WebserviceCallStatusItem()
|
||||
item.url = 'http://remote.example.net'
|
||||
item.post = False
|
||||
item.post_data = {'str': 'abcd', 'one': '=1',
|
||||
'evalme': '=form_number', 'error':'=1=3'}
|
||||
pub.substitutions.feed(formdata)
|
||||
item.perform(formdata)
|
||||
assert http_requests.get_last('url') == 'http://remote.example.net'
|
||||
assert http_requests.get_last('method') == 'POST'
|
||||
payload = json.loads(http_requests.get_last('body'))
|
||||
assert payload == {'one': 1, 'str': 'abcd', 'evalme': formdata.id}
|
||||
|
||||
item = WebserviceCallStatusItem()
|
||||
item.url = 'http://remote.example.net'
|
||||
item.post_data = {'str': 'abcd', 'one': '=1',
|
||||
'evalme': '=form_number', 'error':'=1=3'}
|
||||
pub.substitutions.feed(formdata)
|
||||
item.perform(formdata)
|
||||
assert http_requests.get_last('url') == 'http://remote.example.net'
|
||||
assert http_requests.get_last('method') == 'POST'
|
||||
payload = json.loads(http_requests.get_last('body'))
|
||||
assert payload['extra'] == {'one': 1, 'str': 'abcd', 'evalme': formdata.id}
|
||||
assert payload['url'].startswith('http://example.net/baz-')
|
||||
assert int(payload['display_id']) == 1
|
||||
|
||||
item = WebserviceCallStatusItem()
|
||||
item.url = 'http://remote.example.net'
|
||||
item.post = False
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import json
|
||||
import sys
|
||||
|
||||
from qommon.form import *
|
||||
from qommon.misc import http_get_page, http_post_request, get_variadic_url
|
||||
from qommon.misc import http_get_page, http_post_request, get_variadic_url, JSONEncoder
|
||||
from wcs.workflows import WorkflowStatusItem, register_item_class, template_on_formdata
|
||||
from wcs.api import sign_url
|
||||
|
||||
|
@ -32,9 +33,10 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
varname = None
|
||||
post = True
|
||||
request_signature_key = None
|
||||
post_data = None
|
||||
|
||||
def get_parameters(self):
|
||||
return ('url', 'post', 'varname', 'request_signature_key')
|
||||
return ('url', 'post', 'varname', 'request_signature_key', 'post_data')
|
||||
|
||||
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
|
||||
if 'url' in parameters:
|
||||
|
@ -45,10 +47,14 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
form.add(CheckboxWidget, '%spost' % prefix,
|
||||
title=_('Post formdata (JSON)'),
|
||||
value=self.post)
|
||||
if 'post_data' in parameters:
|
||||
form.add(WidgetDict, '%spost_data' % prefix,
|
||||
title=_('Post data'),
|
||||
value=self.post_data or {})
|
||||
if 'varname' in parameters:
|
||||
form.add(VarnameWidget, '%svarname' % prefix,
|
||||
title=_('Variable Name'), value=self.varname)
|
||||
if 'request_signature_key':
|
||||
if 'request_signature_key' in parameters:
|
||||
form.add(StringWidget, '%srequest_signature_key' % prefix,
|
||||
title=_('Request Signature Key'),
|
||||
value=self.request_signature_key)
|
||||
|
@ -69,13 +75,34 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
|
||||
headers = {'Content-type': 'application/json',
|
||||
'Accept': 'application/json'}
|
||||
post_data = None # payload
|
||||
|
||||
# if self.post_data exists, post_data is a dict built from it
|
||||
if self.post_data:
|
||||
post_data = {}
|
||||
for (key, value) in self.post_data.items():
|
||||
try:
|
||||
post_data[key] = self.compute(value, raises=True)
|
||||
except:
|
||||
get_publisher().notify_of_exception(sys.exc_info())
|
||||
|
||||
# if formdata has to be sent, it's the payload. If post_data exists,
|
||||
# it's added in formdata['extra']
|
||||
if self.post:
|
||||
formdata_as_json = formdata.export_to_json()
|
||||
response, status, data, auth_header = http_post_request(
|
||||
url, formdata_as_json, headers=headers, timeout=TIMEOUT)
|
||||
formdata_dict = formdata.get_json_export_dict()
|
||||
if post_data is not None:
|
||||
formdata_dict['extra'] = post_data
|
||||
post_data = formdata_dict
|
||||
|
||||
if post_data is not None:
|
||||
post_data = json.dumps(post_data, cls=JSONEncoder,
|
||||
encoding=get_publisher().site_charset)
|
||||
response, status, data, authheader = http_post_request(
|
||||
url, post_data, headers=headers, timeout=TIMEOUT)
|
||||
else:
|
||||
response, status, data, auth_header = http_get_page(
|
||||
url, headers=headers, timeout=TIMEOUT)
|
||||
|
||||
if self.varname:
|
||||
workflow_data = {'%s_status' % self.varname: status}
|
||||
if status == 200:
|
||||
|
|
|
@ -836,7 +836,7 @@ class WorkflowStatusItem(object):
|
|||
value = getattr(self, '%s_parse' % f)(value)
|
||||
setattr(self, f, value)
|
||||
|
||||
def compute(self, var):
|
||||
def compute(self, var, raises=False):
|
||||
if not isinstance(var, basestring):
|
||||
return var
|
||||
if not var.startswith('='):
|
||||
|
@ -845,6 +845,8 @@ class WorkflowStatusItem(object):
|
|||
try:
|
||||
return eval(var[1:], get_publisher().get_global_eval_dict(), vars)
|
||||
except:
|
||||
if raises:
|
||||
raise
|
||||
return var
|
||||
|
||||
def get_substitution_variables(self, formdata):
|
||||
|
|
Loading…
Reference in New Issue