2
votes

I am fairly new to Python and in my application I am using Neomodel to load and retrieve graph data from Neo4j database.

In one of my routes I have the following function:

@api_mod.route('/users')                                                            
def get_users():                                                                                                                                                        
     users = User.nodes #Returns a NodeSet                                                                                                                              
     list_of_users = list(users) #Converts the NodeSet object to a list                                                                                                                                                                                                                                                                    
     return json.dumps(dict(users = [user for user in list_of_users]))    

My User class is defined as following:

class User(StructuredNode):
    user_id = StringProperty(unique_index=True, required=True)
    logged_in = RelationshipTo('Environment', 'LOGGED_IN', model=LoginAction)
    launched = RelationshipTo('Application', 'LAUNCHED', model=LaunchedAction)
    entered = RelationshipTo('Application', 'ENTERED', model=EnteredAction)
    accessed = RelationshipTo('Application', 'ACCESSED', model=AccessedAction)
    exited = RelationshipTo('Application', 'EXITED', model=ExitedAction)
    logged_out = RelationshipTo('Environment', 'LOGGED_OUT', model=LogoutAction)
    timed_out = RelationshipTo('Environment', 'TIME_OUT', model=TimeoutAction)

    def toJSON(self):
        return dict(user_id = self.user_id)

My expectation is that my /users route will return a JSON object with all the users in the database. I understand that NodeSet object can't be serializable to a JSON object, hence my attempt to convert it to a list. But now when I run I get the following error: "TypeError: Object of type 'User' is not JSON serializable"

and here is the whole stack trace: Traceback (most recent call last): File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1997, in call return self.wsgi_app(environ, start_response) File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app response = self.handle_exception(e) File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception reraise(exc_type, exc_value, tb) File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise raise value File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app response = self.full_dispatch_request() File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise raise value File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request rv = self.dispatch_request() File "/Users/mdebarros/.virtualenvs/useractivitylogs/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request return self.view_functionsrule.endpoint File "/Users/mdebarros/PycharmProjects/useractivitylogs/app/api/routes.py", line 16, in get_users return json.dumps(dict(users = [user for user in list_of_users])) File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/init.py", line 231, in dumps return _default_encoder.encode(obj) File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode chunks = self.iterencode(o, _one_shot=True) File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode return _iterencode(o, 0) File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 180, in default o.class.name) TypeError: Object of type 'User' is not JSON serializable

Any help or suggestions on how I can handle this and return a proper JSON object ?

Thank you in advance for any assistance.

--MD

1

1 Answers

1
votes

as you know, it is necessary is that the user class Model has a method to perform the process of translation of data structures (serialization), to solve, a solution is to add a method that does this:

class User(StructuredNode):
    user_id = StringProperty(unique_index=True, required=True)
    logged_in = RelationshipTo('Environment', 'LOGGED_IN', model=LoginAction)
    launched = RelationshipTo('Application', 'LAUNCHED', model=LaunchedAction)
    entered = RelationshipTo('Application', 'ENTERED', model=EnteredAction)
    accessed = RelationshipTo('Application', 'ACCESSED', model=AccessedAction)
    exited = RelationshipTo('Application', 'EXITED', model=ExitedAction)
    logged_out = RelationshipTo('Environment', 'LOGGED_OUT', model=LogoutAction)
    timed_out = RelationshipTo('Environment', 'TIME_OUT', model=TimeoutAction)

@property
def serialize(self):
    return {
        'user_id': self.user_id,
        'logged_in': self.logged_in,
        'launched': self.launched,
        'entered': self.entered,
        'accessed': self.accessed,
        'exited': self.exited,
        'logged_out': self.logged_out,
        'timed_out'  : self.timed_out
   }

Now, as the method has been added as property can be called as attribute:

@api_mod.route('/users')                                                            
def get_users():                                                                                                                                                        
    users = User.nodes                                                                                                                            
    list_of_users = list(users)
    return json.dumps(dict(json_users = [user.serialize for user in list_of_users]))