Search code examples
pythonbottle

how to get request body text using bottle?


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 https://i.sstatic.net/iAt1p.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')


Solution

  • 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