Sunday 26 December 2021

Flask-Restx not converting enum field type to JSON

I need help with Enum field type as it is not accepted by Swagger and I am getting error message **TypeError: Object or Type eGameLevel is not JSON serializable**. Below is the complete set of code for table. Complete set of code with DB table and sqlalchemy settings is provided. I already tried it with Marshmallow-Enum Flask package and it didn't worked. Looking for kind help with some explanation about the solution so I can learn it well. :-)

My Model:

import enum
from app import db
from typing import List


class eGameLevel(enum.Enum):
    BEGINNER    =   'Beginner'
    ADVANCED    =   'Advanced'


class Game(Base):
    __tablename__ = 'game_stage'

    id                              = db.Column(db.Integer(), primary_key=True)
    game_level= db.Column(db.Enum(eGameLevel), 
             default=eGameLevel.BEGINNER, nullable=False)
    user_id = db.Column(db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE'), nullable=False)
    user = db.relationship('User', backref='game__level_submissions', lazy=True)

def __init__(self, game_level, user_id):
    self.game_level = game_level
    self.user_id = user_id

def __repr__(self):
    return 'Game(game_level%s, ' \
           'user_id%s'%(self.game_level,
                        self.user_id)
def json(self):
    return {'game_level':self.game_level,
            'user_id':self.user_id}

@classmethod
def by_game_id(cls, _id):
    return cls.query.filter_by(id=_id)

@classmethod
def find_by_game_level(cls, game_level):
    return cls.query.filter_by(game_level=game_level)

@classmethod
def by_user_id(cls, _user_id):
    return cls.query.filter_by(user_id=_user_id)

@classmethod
def find_all(cls) -> List["Game"]:
    return cls.query.all()

def save_to_db(self) -> None:
    db.session.add(self)
    db.session.commit()

def delete_from_db(self) -> None:
    db.session.delete(self)
    db.session.commit()

My Schema

from app import ma
from app.models import Gode

class GameSchema(ma.SQLAlchemyAutoSchema):
    game = ma.Nested('GameSchema', many=True)
    class Meta:
        model =  Game
        load_instance = True
        include_fk= True

My Resources:

from flask_restx import Resource, fields, Namespace
from app.models import Game
from app import db
from app.schemas import GameSchema

GAME_REQUEST_NOT_FOUND = "Game request not found."
GAME_REQUEST_ALREADY_EXSISTS = "Game request '{}' Already exists."

game_ns = Namespace('Game', description='Available Game Requests')
games_ns = Namespace('Game Requests', description='All Games Requests')


game_schema = GameSchema()
games_list_schema = GameSchema(many=True)


gamerequest = game_ns.model('Game', {
    'game_level': fields.String('Game Level: Must be one of: BEGINNER, ADVANCED.'),
    'user_id': fields.Integer,

})


class GameRequestsListAPI(Resource):
    @games_ns.doc('Get all Game requests.')
    def get(self):
        return games_list_schema.dump(Game.find_all()), 200
    @games_ns.expect(gamerequest)
    @games_ns.doc("Create a Game request.")
    def post(self):
        game_json = request.get_json()
        game_data = game_schema.load(game_json)
        game_data.save_to_db()

        return game_schema.dump(game_data), 201


from Flask-Restx not converting enum field type to JSON

No comments:

Post a Comment