Package | Version |
---|---|
Python | 3.9.7 |
Flask | 2.0.2 |
Flask-UUID | 0.2 |
pip | 21.3.1 |
setuptools | 57.4.0 |
Werkzeug | 2.0.1 |
Hi there, although being familiar with other similar concepts in other languages, this leaves me quite stunned .. .. I am writing a little petstore to get familiar with python - more specific flask - and stumble from error to error. The 'normal way to learn I guess ^.^
Nevermind, the code is primarily from here (https://programminghistorian.org/en/lessons/creating-apis-with-python-and-flask#creating-the-api) and works fine ..
import flask
from flask import request, jsonify
app = flask.Flask(__name__)
app.config["DEBUG"] = True
# Create some test data for our catalog in the form of a list of dictionaries.
books = [
{'id': 0,
'title': 'A Fire Upon the Deep'},
{'id': 1,
'title': 'The Ones Who Walk Away From Omelas'},
{'id': 2,
'title': 'Dhalgren'}
]
@app.route('/', methods=['GET'])
def home():
return '''<h1>Distant Reading Archive</h1>
<p>A prototype API for distant reading of science fiction novels.</p>'''
# A route to return all of the available entries in our catalog.
@app.route('/api/v1/resources/books/all', methods=['GET'])
def api_all():
return jsonify(books)
app.run()
.. but .. instead of a prewritten array I'd like to paste some objects before switching to an sqlite-persisence-solution (or likewise).
As far as possible I want to raise the complexity slowly to grasp the program completely.
Hence, using a customized pet class:
import flask
from flask import request, jsonify
import uuid
app = flask.Flask(__name__)
app.config["DEBUG"] = True
class Pet:
def __init__(self,id, name, dateOfBirth):
self.id = id.hex
self.name = name
self.dateOfBirth = dateOfBirth
# def to_json(obj):
# return json.dumps(obj, default=lambda obj: obj.__dict__)
# Create some test data for our catalog in the form of a list of dictionaries.
pets = [ Pet(uuid.uuid4(),'Hamster', '02.12.2019' )]
pets.append( Pet(uuid.uuid4(),'Fish', '07.03.1985' ))
pets.append( Pet(uuid.uuid4(),'Dog', '26.11.2000' ))
pets.append( Pet(uuid.uuid4(),'Cat', '17.05.2021' ))
@app.route('/', methods=['GET'])
def home():
return "<h1>Petshop Archive</h1><p>This site is a prototype API for the petshop archive.</p>"
# A route to return all of the available entries in our catalog.
@app.route('/api/v1/resources/pets/all', methods=['GET'])
def api_all():
return jsonify(pets)
if __name__ == '__main__':
app.run(host='0.0.0.0')
.. You see, the changes are marginal. Now, requesting the API ( http://localhost:5000/api/v1/resources/pets/all ) fails giving a "TypeError: Object of type Pet is not JSON serializable" from the line ..
return jsonify(pets)
.. fair enough. Of course I googled and found fitting solutions, such as ..
.. and ..
.. for the serializable problem (generally) and added the appropriate function
def to_json(obj):
return json.dumps(obj, default=lambda obj: obj.__dict__)
Still I missed the link between the function (serializing the pet-class) and the array (recognizing the pet class to be serializabe).
My approach to write a new array to prevent any class having to be serialized by returning 'pets[pet]' ..
def api_all():
allpets = [pet.toJson for pet in pets]
return jsonify(allpets)
.. fails as well.
Hence the -> TypeError: Object of type Pet is not JSON serializable <- still exists.
Is there 'fancy way' to solve this issue? I can't imagine that this issue has not been raised, yet. Maybe I just looked at it from a wrong angle ;-)
Thanks everyone who made it this far :)