[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 requests
import logging import logging
import urlparse import urlparse
import json
from requests.packages.urllib3.filepost import encode_multipart_formdata
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -95,10 +98,11 @@ class Pingen(object):
return response 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 """ 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 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 :param int/str speed: sending speed of the document if it is send
1 = Priority, 2 = Economy 1 = Priority, 2 = Economy
@@ -108,24 +112,37 @@ class Pingen(object):
2. post_id on pingen.com if it has been sent or None 2. post_id on pingen.com if it has been sent or None
3. dict of the created item on pingen (details) 3. dict of the created item on pingen (details)
""" """
document = {'file': document}
data = { data = {
'send': send, 'send': send,
'speed': speed, 'speed': speed,
'color': color, '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( response = self._send(
requests.post, requests.post,
'document/upload', 'document/upload',
data=data, headers={'Content-Type': content_type},
files=document) 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 # confusing name but send_id is the posted id
posted_id = json.get('send', {}).get('send_id') posted_id = rjson['send'][0]['send_id']
item = json['item'] item = rjson['item']
return document_id, posted_id, item return document_id, posted_id, item

View File

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