Tengo un comportamiento extraño para uno de mis puntos finales en mi aplicación Flask que acepta parámetros de consulta booleanos. No importa lo que le pase, como asfsdfd o true o false , se considera verdadero. Sólo dejándolo vacío se vuelve falso.
full_info = request.args.get("fullInfo", default=False, type=bool) if full_info: # do stuffParece ser que cualquier entrada se considera verdadera. ¿Hay alguna forma de hacer que esto funcione con la forma prevista de Flask de definir el tipo, o necesito aceptar una cadena y compararla?
El parámetro de type de request.args.get es un poco engañoso, ya que no es para especificar el tipo de valor, sino para especificar un invocable :
- type : un invocable que se usa para convertir el valor en MultiDict . Si este invocable genera un ValueError , se devuelve el valor predeterminado.
Acepta un invocable (por ejemplo, una función), aplica ese invocable al valor del parámetro de consulta y devuelve el resultado. Entonces el código
request.args.get("fullInfo", default=False, type=bool) llama a bool(value) donde value es el valor del parámetro de consulta. Sin embargo, en Flask, los valores de los parámetros de consulta siempre se almacenan como cadenas. Y desafortunadamente, llamar a bool() en una cadena no vacía siempre será True :
In [10]: bool('true') Out[10]: True In [11]: bool('false') Out[11]: True In [12]: bool('any non-empty will be true') Out[12]: True In [13]: bool('') Out[13]: False En lugar de bool , puede pasar una función que verifica explícitamente si la cadena es igual a la cadena literal true (o cualquier valor que las reglas de su API consideren como verdadero):
full_info = request.args.get('fullInfo', default=False, type=lambda v: v.lower() == 'true') return jsonify({'full_info': full_info}) $ curl -XGET http://localhost:5000/test?fullInfo=false {"full_info":false} $ curl -XGET http://localhost:5000/test?fullInfo=adasdasd {"full_info":false} $ curl -XGET http://localhost:5000/test?fullInfo=11431423 {"full_info":false} $ curl -XGET http://localhost:5000/test?fullInfo= {"full_info":false} $ curl -XGET http://localhost:5000/test?fullInfo=true {"full_info":true} $ curl -XGET http://localhost:5000/test?fullInfo=TRUE {"full_info":true} $ curl -XGET http://localhost:5000/test {"full_info":false}Un "truco" es usar json.loads como type . Actuará como una "fábrica" que construirá un bool True / False a partir de las cadenas 'true' / 'false'
Esto es de esperar ya que la cadena de consulta es una cadena real, por lo tanto, cuando obtiene una cadena sin importar lo que sea, si no está vacía, será verdadera. Como en:
>>>bool('False') TrueTendrá que hacer una comparación de cadenas si desea obtener un valor booleano.
Funcionaría correctamente si usa el tipo de matraz_restplus.inputs.boolean en lugar de bool. Está explicado aquí. https://github.com/noirbizarre/flask-restplus/issues/199#issuecomment-276645303