I am working on a simple Flask app that has a single route that allows GET requests.
If the incoming request header specifies application/json+ld in the request header, I want to return JSON-LD.
As of right now I am trying to do this using Flask-arrest
As in flask-arrest's documentation, I have added application/json+ld as a supported mimetype with:
api.content_renderer.renders('application/json+ld')
My route currently looks like:
@app.route('/api/gtc', methods=['GET', 'POST'])
def get_meetings():
start_date, end_date = get_dates()
tags = request.args.get('tags', None)
with open('all_meetings.json') as json_data:
events_json = json.load(json_data)
print(request.content_type)
if request.content_type == "application/json+ld":
return serialize_response(events_json, content_type='application/json+ld', status=200, renderer=render_json_ld)
events = filter_events_by_date(start_date_str=start_date, end_date_str=end_date, events=events_json)
events = filter_events_by_tag(events, tags)
# Sort events by time
events_json.sort(key=lambda s: s['time'])
return jsonify(events)
The documentation for serialize_response() can be found here.
I've defined a renderer, that takes the default JSON output and reformats it for JSON+LD.
My error:
Traceback (most recent call last):
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
raise value
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/admin/code/upstate_tech_cal_service/app.py", line 213, in get_meetings
return serialize_response(events_json, content_type='application/json+ld', status=200, renderer=render_json_ld)
File "/Users/admin/miniconda3/envs/cal_service/lib/python3.6/site-packages/flask_arrest/helpers.py", line 63, in serialize_response
return renderer.render_response(response_data, content_type, status)
AttributeError: 'function' object has no attribute 'render_response'
I do not understand the error that I'm getting, but I think the 'function' the AttributeError refers to is my renderer render_json_ld.
So why is this expecting my function to have an attribute, render_response and how can I go about fixing this error?
....
EDIT:
My render_json_ld method looks like this:
@api.content_renderer.renders('application/json+ld')
def render_json_ld(events_json):
# function reformats all_meetings.json to ld+json
data_feed_elements = []
for event in events_json:
if event['venue'] is not None:
element = {
"@type": "DataFeedItem",
"dateCreated": event.get("created_at"),
"dateModified": event.get('data_as_of'),
"item": {
"@type": "Event",
"description": event.get('description'),
"name": event.get('event_name'),
"organizer": {
"@type": "Organization",
"name": event.get('group_name')
},
"nid": event.get('nid'),
"rsvp_count": event.get('rsvp_count'),
"tags": event.get('tags'),
"startDate": event.get('time'),
"url": event.get('url'),
"identifier": f"urn:uuid:{event.get('uuid')}",
"location":
{
"@type": "Place",
"name": event.get('venue').get('name'),
"address": {
"streetAddress": event.get('venue').get('address'),
"addressLocality": event.get('venue').get('city'),
"addressRegion": event.get('venue').get('state'),
"addressCountry": event.get('venue').get('country'),
"postalCode": event.get('venue').get('zip')
},
"geo": {
"@type": "GeoCoordinates",
"latitude": event.get('venue').get('lat'),
"longitude": event.get('venue').get('lon'),
}
}
}
}
else:
element = {
"@type": "DataFeedItem",
"dateCreated": event.get("created_at"),
"dateModified": event.get('data_as_of'),
"item": {
"@type": "Event",
"description": event.get('description'),
"name": event.get('event_name'),
"organizer": {
"@type": "Organization",
"name": event.get('group_name')
},
"nid": event.get('nid'),
"rsvp_count": event.get('rsvp_count'),
"tags": event.get('tags'),
"startDate": event.get('time'),
"url": event.get('url'),
"identifier": f"urn:uuid:{event.get('uuid')}",
"location":
{
"@type": "Place",
"name": event['venue'],
"address": {
"streetAddress": None,
"addressLocality": None,
"addressRegion": None,
"addressCountry": None,
"postalCode": None
},
"geo": {
"@type": "GeoCoordinates",
"latitude": None,
"longitude": None,
}
}
}
}
data_feed_elements.append(element)
ld_json = {
"@context": [
"http://schema.org/",
{"nid": None, "rsvp_count": None, "tags": None, "uuid": None}
],
"@type": "DataFeed",
"dataFeedElement": data_feed_elements
}
return ld_json