how to get request body text using bottle?

3z33etm picture 3z33etm · May 27, 2015 · Viewed 7.5k times · Source

I'm using bottle to receive POST webhook from bitbucket. The body of the POST contains info about what changed in the repo, etc. I am able to do this fine with @post('/myroute'), however I'm having trouble getting to the actual POST body data text.

here is an image that shows what I'm doing end to end http://i.imgur.com/rWc7Hry.png

When printed to consolerequest.body yields:

StringIO.StringIO instance at 0x7fa13341c4d0

and request.body.dir() yields:

AttributeError: StringIO instance has no attribute 'dir'

I'm wondering how do I get to the actual text of the request body (or inspect the object somehow to find the same)?

the POST request body will look something like this:

http://pastebin.com/SWjLrHig

I've also tried request.json (no luck)

any advice?

EDIT: i ended up using this:

from bottle import get, post, request, run
import urllib
import json

@post('/bitbucket')
def postToJSON():
    body = request.body.read()
    body = body.replace("+","").replace("payload=","")
    parsedBody = urllib.unquote(body).decode('utf8')
    print parsedBody
    jsonObj = json.loads(parsedBody)
    print jsonObj 

interesting now, parsedBody looks good:

{"repository":{"website":null,"fork":false,"name":"test","scm":"git","owner":"
testName","absolute_url":"/testNameTest/test/","slug":"test","is_private":true},"trunc
ated":false,"commits":[{"node":"04554d6980dd","files":[{"type":"modified","file"
:"stacker.py"}],"raw_author":"TestName<[email protected]>","utctimestamp":"
2015-05-2815:30:03+00:00","author":"testName","timestamp":"2015-05-2817:30:03","
raw_node":"04554d6980dd3c5fe4c3712d95b49fcf9b8da4f4","parents":["7f98b4e7532e"],
"branch":"master","message":"foo\n","revision":null,"size":-1}],"canon_url":"htt
ps://bitbucket.org","user":"testName"}

but jsonObj is not so good:

{u'commits': [{u'node': u'7f98b4e7532e', u'files': [{u'type': u'modified', u'fil
e': u'stacker.py'}], u'branch': u'master', u'utctimestamp': u'2015-05-2815:24:50
+00:00', u'author': u'TestName', u'timestamp': u'2015-05-2817:24:50', u'raw_node
': u'7f98b4e7532e02d53d83a29ec2073c5a5eac58c8', u'parents': [u'019e77d2e0d3'], u
'raw_author': u'TestNamer<[email protected]>', u'message': u'foo\n', u'size'
: -1, u'revision': None}], u'user': u'TestName', u'canon_url': u'https://bitbuck
et.org', u'repository': {u'website': None, u'fork': False, u'name': u'test', u's
cm': u'git', u'absolute_url': u'/ericTest/test/', u'owner': u'TestName', u'slug'
: u'test', u'is_private': True}, u'truncated': False}

however, when I do something like

print jsonObj['repository']['name']

it works as expected (just prints the name 'test')

Answer

deets picture deets · May 27, 2015

As the bottle documentation states, the request data is "a file like object". http://bottlepy.org/docs/dev/tutorial.html#the-raw-request-body

So you access the raw body using read().

Also, dir is not a method of objects, it's a freestanding function which you call passing an object.

dir(request.body)

And googling for StringIO should have brought you here: https://docs.python.org/2/library/stringio.html