How do I serialize a response as JSON+LD using Flask-Arrest?

271 Views Asked by At

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
0

There are 0 best solutions below