Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask jsonify a list of objects

I have a list of objects that I need to jsonify. I've looked at the flask jsonify docs, but I'm just not getting it.

My class has several inst-vars, each of which is a string: gene_id, gene_symbol, p_value. What do I need to do to make this serializable as JSON?

My naive code:

jsonify(eqtls = my_list_of_eqtls) 

Results in:

TypeError: <__main__.EqtlByGene object at 0x1073ff790> is not JSON serializable 

Presumably I have to tell jsonify how to serialize an EqtlByGene, but I can't find an example that shows how to serialize an instance of a class.

I've been trying to follow some of the suggestions show below to create my own JSONEncoder subclass. My code is now:

class EqtlByGene(Resource):      def __init__(self, gene_id, gene_symbol, p_value):         self.gene_id = gene_id         self.gene_symbol = gene_symbol         self.p_value = p_value  class EqtlJSONEncoder(JSONEncoder):     def default(self, obj):         if isinstance(obj, EqtlByGene):             return {                    'gene_id'     : obj.gene_id,                    'gene_symbol' : obj.gene_symbol,                    'p_value'     : obj.p_value             }         return super(EqtlJSONEncoder, self).default(obj)  class EqtlByGeneList(Resource):     def get(self):         eqtl1 = EqtlByGene(1, 'EGFR', 0.1)         eqtl2 = EqtlByGene(2, 'PTEN', 0.2)         eqtls = [eqtl1, eqtl2]         return jsonify(eqtls_by_gene = eqtls)  api.add_resource(EqtlByGeneList, '/eqtl/eqtlsbygene') app.json_encoder(EqtlJSONEncoder) if __name__ == '__main__':     app.run(debug=True) 

When I try to reach it via curl, I get:

TypeError(repr(o) + " is not JSON serializable") 
like image 235
Jared Nedzel Avatar asked Jan 28 '14 16:01

Jared Nedzel


People also ask

How do you Jsonify a list in Flask?

To jsonify a list of objects with Python Flask, we add a method in our object's class to return the object's contents as a dictionary. to create the Gene class that has the serialize method that returns the instance properties in a dictionary.

How do you serialize a list of objects in Python?

Steps to perform serialization in PythonOpen the file in which you want to save the object in binary write mode. Call pickle 's dump() method and pass object as a first argument and the above-created file object as a second argument. Repeat step 3 until all of the objects are saved to a file.

How do you Jsonify an object?

Flask jsonify is defined as a functionality within Python's capability to convert a json (JavaScript Object Notation) output into a response object with application/json mimetype by wrapping up a dumps( ) function for adding the enhancements.

What does Jsonify do in Flask?

jsonify() is a helper method provided by Flask to properly return JSON data. jsonify() returns a Response object with the application/json mimetype set, whereas json. dumps() simply returns a string of JSON data.

What is flask jsonify?

Introduction to Flask jsonify Flask jsonify is defined as a functionality within Python’s capability to convert a json (JavaScript Object Notation) output into a response object with application/json mimetype by wrapping up a dumps () function for adding the enhancements.

How to return a JSON list in a flask variable?

A list in a flask can be easily jsonify using jsonify like: If you are searching literally the way to return a JSON list in flask and you are completly sure that your variable is a list then the easy way is (where bin is a list of 1's and 0's):

How to serialize top-level arrays in flask?

Flask's jsonify () method now serializes top-level arrays as of this commit, available in Flask 0.11 onwards. For convenience, you can either pass in a Python list: jsonify ( [1,2,3]) Or pass in a series of args: jsonify (1,2,3) Show activity on this post. Solved, no fuss.

How does flask know if a method is available?

methods: If methods are not provided when the URL rule is added, Flask will look on the view function object itself if a methodsattribute exists. If it does, it will pull the information for the methods from there.


1 Answers

Give your EqltByGene an extra method that returns a dictionary:

class EqltByGene(object):     #      def serialize(self):         return {             'gene_id': self.gene_id,              'gene_symbol': self.gene_symbol,             'p_value': self.p_value,         } 

then use a list comprehension to turn your list of objects into a list of serializable values:

jsonify(eqtls=[e.serialize() for e in my_list_of_eqtls]) 

The alternative would be to write a hook function for the json.dumps() function, but since your structure is rather simple, the list comprehension and custom method approach is simpler.

You can also be really adventurous and subclass flask.json.JSONEncoder; give it a default() method that turns your EqltByGene() instances into a serializable value:

from flask.json import JSONEncoder  class MyJSONEncoder(JSONEncoder):     def default(self, obj):         if isinstance(obj, EqltByGene):             return {                 'gene_id': obj.gene_id,                  'gene_symbol': obj.gene_symbol,                 'p_value': obj.p_value,             }         return super(MyJSONEncoder, self).default(obj) 

and assign this to the app.json_encoder attribute:

app = Flask(__name__) app.json_encoder = MyJSONEncoder 

and just pass in your list directly to jsonify():

return jsonify(my_list_of_eqtls) 

You could also look at the Marshmallow project for a more full-fledged and flexible project for serializing and de-serializing objects to Python primitives that easily fit JSON and other such formats; e.g.:

from marshmallow import Schema, fields  class EqltByGeneSchema(Schema):     gene_id = fields.Integer()     gene_symbol = fields.String()     p_value = fields.Float() 

and then use

jsonify(eqlts=EqltByGeneSchema().dump(my_list_of_eqtls, many=True) 

to produce JSON output. The same schema can be used to validate incoming JSON data and (with the appropriate extra methods), used to produce EqltByGene instances again.

like image 192
Martijn Pieters Avatar answered Sep 22 '22 21:09

Martijn Pieters