flask-smorest
                                
                                
                                
                                    flask-smorest copied to clipboard
                            
                            
                            
                        Schema with dict field in query [OAS3]
Hi,
I've not been able to figure out if there is a supported way to control the style for an argument.
Example schema usage
class Example (Schema):
  f = fields.Dict()
@blp.route("/")
class Demo (MethodView):
  @blp.arguments(Example, location='query')
  def get(self, args):
    return 'ok'
which yields this spec fragment:
      - name: "f"
        in: "query"
        schema:
          type: "object"
But, as objects passed as query args, have a default style of form with explode true, the f part is not included in the request query when using swagger UI.
At the very least, explode needs to be set to false in order to reveal the f argument name in the query. Or, a style of deepObject should also work. Frankly, I don't really care which way, as long as it is parsed properly by webargs.
      - name: "attrs"
        in: "query"
        style: deepObject  # this
        explode: false     # or this
        schema:
          type: "object"
Right now, I get a
{
  "code": 422,
  "errors": {
    "query": {
      "moo": [
        "Unknown field."
      ]
    }
  },
  "status": "Unprocessable Entity"
}
for a request where f is provided as {"moo":"data"} in swagger ui.
Hi.
You could do
class Example (Schema):
  moo = fields.String()  # Or whatever type
@blp.route("/")
class Demo (MethodView):
  @blp.arguments(Example, location='query')
  def get(self, args):
    return 'ok'
but I guess you're using Dict because you don't know the query args names in advance and you want everything passed.
To achieve this in webargs, you could pass an empty schema with unknown set as INCLUDE.
I don't know how this should be documented in OAS, though.
There's been discussion in apispec about style/explode being hardcoded and allowing users to override stuff: https://github.com/marshmallow-code/apispec/issues/500. No one had the time to do it yet, but it's on the roadmap.
@lafrech thanks. Yes, it is a dict, as the data at that point is arbitrary, but at the root level, it is not, so must work at a nested level. Will follow the linked issue for progress, thank you :)
@kaos were you able to solve the issue faced? I'm also stuck with the same issue while using a Nested schema instead of dict() With latest update 4.x it does not throw error but totally ignores deserializing it into the schema.
No, I would very much appreciate this to work, soon-ish ;) haven't looked at if I can get it to work with some surgical monkey patching, though..
To show some context, from my use case, this is what the swagger ui part for it looks like, atm

and this results in the following data in the marshmallow load() method on the schema:
ImmutableMultiDict([
('order_by', '-status.created'), 
('kind', 'fff'), 
('apiVersion', '23'), 
('annotations[additionalProp1]', 'string'), 
('annotations[additionalProp2]', 'string'), 
('annotations[additionalProp3]', 'string'), 
('description', ''), 
('tags', 'string'), 
('uid', '3fa85f64-5717-4562-b3fc-2c963f66afa6'), 
('name', 'string'), 
('namespace', 'string'), 
('labels[additionalProp1]', 'string'), 
('labels[additionalProp2]', 'string'), 
('labels[additionalProp3]', 'string'), 
('type', 'string'), 
('page', '1'), 
('page_size', '10')
])
as is evident here, is that we've lost a level of detail for the nested data, as it doesn't provide information about if the fields are for the root object, or nested under metadata or spec.
Exactly... since the first level is lost (no 'metadata'), on the server a nested class/dict (with name 'metadata') fails to get populated...