Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: Object of type function is not JSON serializable when using flask_jwt_extended int RESTful API

I'm building a REST API using flask. I'm using postman for testing a route that creates a new item in my database, but only if the user is logged in. The routes for registering and login are working well, the last one returns the token using flask_jwt_extended module. When I send a post request to my "/api/notes" (creates a new note in database) I get the error bellow:

" (...) raise TypeError(f'Object of type {o.class.name} '

TypeError: Object of type function is not JSON serializable"

for the request I'm using the authorization tab of postman. type: Bearer Token, and my token in the field (tried with and without quotation marks)

I had faced this error this morning, before implementing my one-many relantionship, but I got it working by replacing my VERY_LONG_TOKEN with "VERY_LONG_TOKEN" in the Barear token field. I thought that because the token includes dots, it was interpreting as a function. But after implementing the relationship, I went to test and got this error again.

my note.py file:

from flask import request, Response, jsonify
from app.models import User, Note
from flask_restful import Resource
from flask_jwt_extended import jwt_required, get_jwt_identity

class NotesApi(Resource):
    def get(self):
        notes = Note.objects().to_json()
        return Response(notes, mimetype="application/json", status=200)

    @jwt_required  
    def post(self):  # post method I'm making a request for
        print("fool")  # this doesn't get printed  ->  not reaching 
        user_id = get_jwt_identity()
        data = request.get_json(force=True)
        if data:
            user = User.objects(id=user_id) # logged in user
            note = Note(**data, user_author=user) # creates note with the author
            note.save()
            user.update(push__notes=note) # add this note to users notes
            user.save()
            id = str(note.id)
            return {'id': id}, 200
        else:
            return {'error': 'missing data'}, 400

my models.py:

from app import db  # using mongodb
from datetime import datetime
from flask_bcrypt import generate_password_hash, check_password_hash

class Note(db.Document):
    title = db.StringField(max_length=120,required=True)
    content = db.StringField(required=True)
    status = db.BooleanField(required=True, default=False)
    date_modified = db.DateTimeField(default=datetime.utcnow)
    user_author = db.ReferenceField('User')
    
class User(db.Document):
    username = db.StringField(max_length=100, required=True, unique=True)
    email = db.StringField(max_length=120, required=True, unique=True)
    password = db.StringField(required=True)
    remember_me = db.BooleanField(default=False)
    notes = db.ListField(db.ReferenceField('Note', reverse_delete_rule=db.PULL)) # one-many relationship

    def hash_password(self):
        self.password = generate_password_hash(self.password).decode('utf8')

    def check_password(self, password):
        return check_password_hash(self.password, password)


User.register_delete_rule(Note, 'user_author', db.CASCADE)

init.py:

from flask import Flask
from config import Config  # my config class to set MONGOBD_HOST and SECRET_CLASS
from flask_mongoengine import MongoEngine
from flask_restful import Api
from flask_bcrypt import Bcrypt
from flask_jwt_extended import JWTManager

app = Flask(__name__)
app.config.from_object(Config)
db = MongoEngine(app)
api = Api(app)
bcrypt = Bcrypt(app)
jwt = JWTManager(app)

from app.resources.routes import initialize_routes
initialize_routes(api) 

resources/routes.py:

from .note import NotesApi, NoteApi
from .auth import SignupApi, LoginApi

def initialize_routes(api):
    api.add_resource(NotesApi, '/api/notes')
    api.add_resource(NoteApi, '/api/note/<id>')
    api.add_resource(SignupApi, '/api/auth/signup')
    api.add_resource(LoginApi, '/api/auth/login')

folder structure:

app
  |_ resources
      |_ auth.py  # signup working well, login also working, return a token (type = String)
      |_ note.py
      |_ routes.py
  |_ __init__.py
  |_ models.py
config.py
appname.py  #just import app and do a app.run()

body of my post request:

{
   "title": "test0",
   "content": "test0"  
}

Did anyone faced it before or know how to solve it?

Edit: added more code info

like image 322
Wiliane Souza Avatar asked Feb 14 '21 21:02

Wiliane Souza


People also ask

How do I fix object of type function is not JSON serializable?

The Python "TypeError: Object of type function is not JSON serializable" occurs when we try to serialize a function to JSON. To solve the error, make sure to call the function and serialize the object that the function returns. Here is an example of how the error occurs.

How to solve the Python TypeError object of type set is not JSON?

The Python "TypeError: Object of type set is not JSON serializable" occurs when we try to convert a set object to a JSON string. To solve the error, convert the set to a list before serializing it to JSON, e.g. json.dumps (list (my_set)). Here is an example of how the error occurs.

How to make class JSON serializable in Python?

Write custom JSONEncoder to make class JSON serializable. Python json module has a JSONEncoder class. You can extend it If you want more customized output. i.e., you will have to subclass JSONEncoder so you can implement your custom JSON serialization. The json.dump() and json.dumps() method of the JSON module has a cls kwarg.

Why doesn't the built-in JSON module of Python handle Python objects?

The built-in json module of Python can only handle Python primitives types that have a direct JSON equivalent. i.e., The fundamental problem is that the JSON encoder json.dump () and json.dumps () only knows how to serialize the basic set of object types by default (e.g., dictionary, lists, strings, numbers, None, etc.).


1 Answers

Looks like flask-jwt-extended released a new version over the weekend. As part of the API changes, the @jwt_required decorator is now @jwt_required()

https://flask-jwt-extended.readthedocs.io/en/stable/v4_upgrade_guide/#api-changes

like image 129
Maylor Avatar answered Oct 27 '22 18:10

Maylor