[FIX] the data must be JSON-encoded when we call the document/upload endpoint. Need to build the body instead of data and files params

This commit is contained in:
Guewen Baconnier @ Camptocamp
2012-11-23 12:15:00 +01:00
parent 8bb9c3bb77
commit b88f5c556a
2 changed files with 33 additions and 12 deletions

View File

@@ -22,6 +22,9 @@
import requests
import logging
import urlparse
import json
from requests.packages.urllib3.filepost import encode_multipart_formdata
_logger = logging.getLogger(__name__)
@@ -95,10 +98,11 @@ class Pingen(object):
return response
def push_document(self, document, send=None, speed=None, color=None):
def push_document(self, filename, filestream, send=None, speed=None, color=None):
""" Upload a document to pingen.com and eventually ask to send it
:param tuple document: (filename, file stream) to push
:param str filename: name of the file to push
:param StringIO filestream: file to push
:param boolean send: if True, the document will be sent by pingen.com
:param int/str speed: sending speed of the document if it is send
1 = Priority, 2 = Economy
@@ -108,24 +112,37 @@ class Pingen(object):
2. post_id on pingen.com if it has been sent or None
3. dict of the created item on pingen (details)
"""
document = {'file': document}
data = {
'send': send,
'speed': speed,
'color': color,
}
# we cannot use the `files` param alongside
# with the `datas`param when data is a
# JSON-encoded data. We have to construct
# the entire body and send it to `data`
# https://github.com/kennethreitz/requests/issues/950
formdata = {
'file': (filename, filestream.read()),
'data': json.dumps(data),
}
multipart, content_type = encode_multipart_formdata(formdata)
response = self._send(
requests.post,
'document/upload',
data=data,
files=document)
headers={'Content-Type': content_type},
data=multipart)
json = response.json
rjson = response.json
document_id = json['id']
document_id = rjson['id']
if rjson.get('send'):
# confusing name but send_id is the posted id
posted_id = json.get('send', {}).get('send_id')
item = json['item']
posted_id = rjson['send'][0]['send_id']
item = rjson['item']
return document_id, posted_id, item

View File

@@ -91,10 +91,14 @@ class pingen_task(orm.Model):
success = False
# parameterize
pingen = Pingen(TOKEN, staging=True)
doc = (task.datas_fname, StringIO(decoded_document))
doc = (task.datas_fname, )
try:
doc_id, post_id, __ = pingen.push_document(
doc, task.pingen_send, task.pingen_speed, task.pingen_color)
task.datas_fname,
StringIO(decoded_document),
task.pingen_send,
task.pingen_speed,
task.pingen_color)
except ConnectionError as e:
# we can continue and it will be retried the next time
_logger.exception('Connection Error when pushing Pingen Task %s to %s.' %