flask-restx
flask-restx copied to clipboard
Value of different types (e.g., str, list)
It seems swagger cannot properly handle the JSON payload and I've been wondering if it's my implementation or there's something wrong. I have attached a MWE to demonstrate part of the issue I have been facing and it is mainly associated with the fact that a value of a key could be of different types, e.g. str
or list
(that's why in the following example I have used fields.Raw
)
from flask_restx import Api, fields, Resource
from flask import Flask, request, jsonify
app = Flask(__name__)
api = Api(app, doc="/swagger")
@app.route("/hello_world", methods=["POST"])
def hello_world():
payload = request.get_json()
return jsonify(payload)
filter_component = api.model(
"FilterComponent",
{
"variable": fields.String(required=True),
"operator": fields.String(required=True),
"value": fields.Raw(required=True),
},
)
hello_world_payload = api.model(
"HelloWorldPayload",
{
"filters": fields.List(
fields.Nested(filter_component, required=True), required=True
)
},
)
@api.route("/hello_world")
class HelloWorldResource(Resource):
@api.expect(hello_world_payload)
def post(self):
pass
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
If I go to swagger and try out the endpoint with the following endpoint:
{
"filters": [
{
"variable": "name",
"operator": "eq",
"value": ["Bob"]
}
]
}
everything seems to work as expected and get the expected output:
However, if I use the following payload:
{
"filters": [
{
"variable": "name",
"operator": "eq",
"value": "Bob"
}
]
}
when I hit the execute button, I don't seem to get anything back.
Expected output:
{
"filters": [
{
"operator": "eq",
"value": "Bob",
"variable": "name"
}
]
}
I'm not sure if this is a bug or no, so I have set this as a question. Please feel free to ask if anything else is needed.
python version: 3.11.5 flask version: 2.3.3 flask-restx version: 1.1.0
Having a look at the swagger.json
that gets generated by your example, the error is caused by the fact that when using fields.Raw
the default data type is object
and in example two, you are passing a string which is not an object
as far as swagger is concerned.
I don't think there is any neat way to allow flask-restx
/ Swagger 2.0 to allow you to have multiple data types. My suggestion would be to always pass a list of strings, even if you only have one value, so you have a fixed data type, and then use fields.String
instead.
@peter-doggart Thanks for the insight! This is what I have seen, as well, however I am not sure If I can apply your suggestion as is, since there might be objects of different types, i.e., floats, integers, strings. I was hoping flask-restx could support multiple data types.