2

I am trying to write a Flask web app (hosted on Heroku) that will accept a datapoint POSTed to it from Xively.

The code below is meant to take the datapoint, modify it(add 2 to it), and then send it back to the xively feed:

import os
from flask import Flask
from flask import request
import xively


app = Flask(__name__)

@app.route('/', methods=['GET','POST'])
def take_xively_post_data():

    if request.method == 'POST':

        if not request.json or not 'current_value' in request.json:
            abort(400)
        else:
            key = 'f5vezDTq4VphhXyCn......'  
            feedid = '21094....'

            lev = request.json['current_value']

                    #the following code just adds 2 to the POSTed value and 
                    #sends it back to xively 

            lev = lev + 2

            client1 = xively.Client(key)  
            datastream = xively.Datastream(id="DatastreamID", current_value= lev)  

        return client1.put('/v2/feeds/'+feedid, data={'datastreams': [datastream]}

    else:
        return 'Hello'

But when Xively posts to the app's URL, nothing happens. (It should be sending the modified data back to the Xively feed.)

The Heroku logs indicate a 500 error:

2014-05-29T14:00:55.844275+00:00 heroku[router]: at=info method=POST path=/ host=....herokuapp.com request_id=... fwd="..." dyno=web.1 connect=1ms service=17ms status=500 bytes=454

I think there is a problem in the code but don't know what it is...

I have tried moving the client1.put(...) statement up and returning nothing as shown below but the same thing happens:

import os
from flask import Flask
from flask import request
import xively


app = Flask(__name__)

@app.route('/', methods=['GET','POST'])
def take_xively_post_data():

    if request.method == 'POST':

        if not request.json or not 'current_value' in request.json:
            abort(400)
        else:
            key = 'f5vezDTq4VphhXyCn......'  
            feedid = '21094....'

            lev = request.json['current_value']

            lev = lev + 2

            client1 = xively.Client(key)  
            datastream = xively.Datastream(id="DatastreamID", current_value= lev)  

                    #moved the client1.put function up and returning nothing

            client1.put('/v2/feeds/'+feedid, data={'datastreams': [datastream]}

        return
    else:
        return 'Hello'

I have tried request.form() instead of request.json() but that doesn't seem to work either.

I would really appreciate it if anyone could point out the coding error.

  • 1
    Flask logs exceptions; [configure your logging for Heroku](http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xviii-deployment-on-the-heroku-cloud) and look at the traceback. – Martijn Pieters May 29 '14 at 15:04
  • The "heroku logs --source app" don't indicate much: 2014-05-29T15:47:00.471353+00:00 app[web.1]: 2014-05-29 15:47:00 [2] [INFO] Starting gunicorn 18.0 2014-05-29T15:47:00.478047+00:00 app[web.1]: 2014-05-29 15:47:00 [2] [INFO] Listening at: http://0.0.0.0:10967 (2) 2014-05-29T15:47:00.503778+00:00 app[web.1]: 2014-05-29 15:47:00 [7] [INFO] Booting worker with pid: 7 2014-05-29T15:47:00.478056+00:00 app[web.1]: 2014-05-29 15:47:00 [2] [INFO] Using worker: sync – user3482357 May 29 '14 at 15:52
  • Add that to your question; [edit] it. – Martijn Pieters May 29 '14 at 15:52
  • 1
    I see that `xively.Client()` is just a `requests` session; `client1.put()` then returns a response object. That's not an object Flask knows how to publish, you need to return a valid [Flask response](https://flask.readthedocs.org/en/latest/quickstart/#about-responses) instead. – Martijn Pieters May 29 '14 at 15:57
  • `return None` (which is what `return` is, is not a valid response either - try `return ('', 204, {})` – Sean Vieira May 29 '14 at 16:59

1 Answers1

0

Not sure if you solved your issue but I think I can help out.

The way you are requesting your current value is most likely incorrect. This would be causing your key to not be found which would definitely through a 500.

I am assuming you are using Xively triggers to make the POST request. If that is the case, start by changing lev = request.json['current_value'] to lev = request.json['triggering_datastream']['value']['value']. This should at least give you the actual current value of the datastream which has sent the trigger.

Then of course change your return value to something like 200 with no body as other people have suggested.

See if this works and then we can try to debug the PUT you send back into Xively. That code looks pretty correct to me.

calumb
  • 1,051
  • 2
  • 10
  • 24