david
david

Reputation: 1077

Flask taking status from content?

The function below

print(usaddress.tag('hwy 13 & main st.'))

generates the results below

(OrderedDict([('StreetNamePreType', u'hwy'), ('StreetName', u'13'), ('IntersectionSeparator', u'&'), ('SecondStreetName', u'main'), ('SecondStreetNamePostType', u'st.')]), 'Intersection')

I'm using the same function for a flask return like below

@app.route("/parseAddress", methods=["POST"])
def parseAddress():
  address = request.form['address']
  return usaddress.tag(address)

but for the HTTP status it's showing as "intersection" instead of "OK 200", it's taking the last section of the result and using it as a status.

What's the best way to send back the results without overriding the correct status codes?

Upvotes: 1

Views: 108

Answers (2)

Zeeshan
Zeeshan

Reputation: 1166

I couldn't replicate the error you mentioned, however, it does throw the following exception because usaddress.tag() returns a tuple that contains an OrderedDict

TypeError: 'collections.OrderedDict' object is not callable
The view function did not return a valid response. The return type must be a string, tuple, Response instance, or WSGI callable, but it was a OrderedDict.

You can fix this by using jsonify module and returning a JSON response like below:

from flask import Flask, jsonify
import usaddress

app = Flask(__name__)

@app.route("/", methods=["Get"])
def parseAddress():
    tagged_address, address_type = usaddress.tag('hwy 13 & main st.')
    return jsonify({"address_type": address_type, "tagged_address": tagged_address})

if __name__ == "__main__":
    app.run(debug=True)

It will return following JSON response

{
  "address_type": "Intersection", 
  "tagged_address": {
    "IntersectionSeparator": "&", 
    "SecondStreetName": "main", 
    "SecondStreetNamePostType": "st.", 
    "StreetName": "13", 
    "StreetNamePreType": "hwy"
  }
}

You could also do this:

@app.route("/", methods=["Get"])
def parseAddress():
    return jsonify(usaddress.tag('hwy 13 & main st.'))

but it would return an array with second element being a string

[
  {
    "IntersectionSeparator": "&", 
    "SecondStreetName": "main", 
    "SecondStreetNamePostType": "st.", 
    "StreetName": "13", 
    "StreetNamePreType": "hwy"
  }, 
  "Intersection"
]

which might not be very convenient to process on the front-end.

Hope it helps.

Upvotes: 1

R. Davidson
R. Davidson

Reputation: 439

Looks like the usaddress library is returning a tuple with two elements, an OrderedDict and a string. The problem is that Flask interprets the return value as a (response, status) pair. Trying return usaddress.tag(address), 200 might suit your needs, if flask is generous enough to convert that return value to a string for you - but in general, you need to convert your response body into a string yourself before it makes sense to pass it over HTTP. JSON is a common serialization format used for this task, so I'd suggest return flask.jsonify(usaddress.tag(address)), 200 instead.

If you really just want to get the literal string (OrderedDict([('StreetNamePreType', u'hwy'), ('StreetName', u'13'), ('IntersectionSeparator', u'&'), ('SecondStreetName', u'main'), ('SecondStreetNamePostType', u'st.')]), 'Intersection') as your output, you can go with return str(usaddress.tag(address)), 200 instead - but JSON is probably going to be more familiar to the average developer looking at your site.

Upvotes: 3

Related Questions