python-restx / flask-restx

Fork of Flask-RESTPlus: Fully featured framework for fast, easy and documented API development with Flask
https://flask-restx.readthedocs.io/en/latest/
Other
2.14k stars 333 forks source link

request body validation is not working #587

Closed WilliamChen-luckbob closed 8 months ago

WilliamChen-luckbob commented 8 months ago

I don't find any similar issues.

Code

here is the code copied from quick start, and I tried to add 'test' as an extra parameter into todo. The full runnable code is showing below:

from flask import Flask
from flask_restx import Api, Resource, fields

app = Flask(__name__)
api = Api(app, version='1.0', title='TodoMVC API',
    description='A simple TodoMVC API',
)

ns = api.namespace('todos', description='TODO operations')

todo = api.model('Todo', {
    'id': fields.Integer(readonly=True, description='The task unique identifier'),
    'task': fields.String(required=True, description='The task details'),
    'test': fields.String(required=True, description='The task details') # I added this row for test
})

class TodoDAO(object):
    def __init__(self):
        self.counter = 0
        self.todos = []

    def get(self, id):
        for todo in self.todos:
            if todo['id'] == id:
                return todo
        api.abort(404, "Todo {} doesn't exist".format(id))

    def create(self, data):
        todo = data
        todo['id'] = self.counter = self.counter + 1
        self.todos.append(todo)
        return todo

    def update(self, id, data):
        todo = self.get(id)
        todo.update(data)
        return todo

    def delete(self, id):
        todo = self.get(id)
        self.todos.remove(todo)

DAO = TodoDAO()
DAO.create({'task': 'Build an API'})
DAO.create({'task': '?????'})
DAO.create({'task': 'profit!'})

@ns.route('/')
class TodoList(Resource):
    '''Shows a list of all todos, and lets you POST to add new tasks'''
    @ns.doc('list_todos')
    @ns.marshal_list_with(todo)
    def get(self):
        '''List all tasks'''
        return DAO.todos

    @ns.doc('create_todo')
    @ns.expect(todo)
    @ns.marshal_with(todo, code=201)
    def post(self):
        '''Create a new task'''
        return DAO.create(api.payload), 201

@ns.route('/<int:id>')
@ns.response(404, 'Todo not found')
@ns.param('id', 'The task identifier')
class Todo(Resource):
    '''Show a single todo item and lets you delete them'''
    @ns.doc('get_todo')
    @ns.marshal_with(todo)
    def get(self, id):
        '''Fetch a given resource'''
        return DAO.get(id)

    @ns.doc('delete_todo')
    @ns.response(204, 'Todo deleted')
    def delete(self, id):
        '''Delete a task given its identifier'''
        DAO.delete(id)
        return '', 204

    @ns.expect(todo)
    @ns.marshal_with(todo)
    def put(self, id):
        '''Update a task given its identifier'''
        return DAO.update(id, api.payload)

if __name__ == '__main__':
    app.run(debug=True)

Repro Steps (if applicable)

just run it and try the put request from the swagger ui to see what happen if the required param is missing image image

the validation is not working, when test or task is missing in request body, I can still get a succeed response.

Expected Behavior

throw any exceptions like parameter is missing

Actual Behavior

just let request pass.

Error Messages/Stack Trace

Nothing happened, and no error was found, the validation just not working.

Environment

I'm new to python, for testing the validation situation, I just begin with quick start and installed flask and flask-restx only in an new and individual venv I don't know if the python version is too high to use such function and lead to some problem

peter-doggart commented 8 months ago

Validation is not enabled by default.

You either need to specify it in the expect call like @ns.expect(todo, validate=True) or set global configuration flag RESTX_VALIDATE.

Does that fix your issue?

WilliamChen-luckbob commented 8 months ago

Validation is not enabled by default.

You either need to specify it in the expect call like @ns.expect(todo, validate=True) or set global configuration flag RESTX_VALIDATE.

Does that fix your issue?

Problem solved, thanks a lot!