Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value of different types (e.g., str, list) #564

Open
thanasissdr opened this issue Sep 23, 2023 · 2 comments
Open

Value of different types (e.g., str, list) #564

thanasissdr opened this issue Sep 23, 2023 · 2 comments
Labels
question Further information is requested

Comments

@thanasissdr
Copy link

thanasissdr commented Sep 23, 2023

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:

functional

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

@thanasissdr thanasissdr added the question Further information is requested label Sep 23, 2023
@peter-doggart
Copy link
Contributor

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.

@thanasissdr
Copy link
Author

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants