Wildcard field contains an extra nested level in docs
This might be related to the recent wildcard field changes, e.g. #24.
When using a wildcard field with nested models, the resulting documentation contains three levels: *, <*>, and the nested model, where I would expect just two: The key <*> and the nested model. Example values in the doc also contains an extra nested level.
Please note, the actual output of the marshaled model in get is correct, only the swagger doc is wrong.
Code
from flask import Flask
from flask_restx import Resource, Api, fields
app = Flask(__name__)
api = Api(app)
nested_model = api.model('Nested model', {'nested_string': fields.String()})
wild = fields.Wildcard(fields.Nested(nested_model))
wildcard_model = api.model('Wildcard model', {'*': wild})
@api.route('/hello')
class HelloWorld(Resource):
@api.marshal_with(wildcard_model)
def get(self):
return {
'foo': {
'nested_string': 'foo'
},
'bar': {
'nested_string': 'bar'
}
}
if __name__ == '__main__':
app.run(debug=True)
Repro Steps (if applicable)
- Run example above
- View documentation at http://localhost:5000
Actual model doc

Expected model doc
Only one level of *, not two.
Actual example value doc
{
"*": {
"additionalProp1": {
"nested_string": "string"
},
"additionalProp2": {
"nested_string": "string"
},
"additionalProp3": {
"nested_string": "string"
}
}
}
Expected example value doc
{
"additionalProp1": {
"nested_string": "string"
},
"additionalProp2": {
"nested_string": "string"
},
"additionalProp3": {
"nested_string": "string"
}
}
or
{
"*": {
"nested_string": "string"
}
}
Actual output of get (correct)
{
"bar": {
"nested_string": "bar"
},
"foo": {
"nested_string": "foo"
}
}
Environment
- Python 3.7
- Flask 1.1.1
- Flask-RESTX 0.1.1
Hello,
I'm not sure this is related to #24. The "double-nested" level is kind of expected (or at least it's how Wildcard fields have been initially implemented).
Here is the initial PR that introduced this feature: https://github.com/noirbizarre/flask-restplus/pull/255#issuecomment-392480891
As you can see, I already questioned about the resulting swagger, but at that time, nobody reacted to this limitation.
@SteadBytes, @j5awry do you think we could improve the Wildcard representation in the swagger?
Hello @ziirish , When you said "kind of expected", I'm not sure if you mean that wildcards weren't meant for @anthiras' usecase or not. I have the same issue where I'd like to have:
{
"field1": "value1",
"nested_and_dynamic_keys": {
"wildcard_field1": {
"foo": "bar",
"alice": "bob"
},
"wildcard_field2": {
"foo": "rba",
"alice": "bbo"
}
}
}
But I got this instead:
{
"field1": "value1",
"nested_and_dynamic_keys": {
"*": {
"wildcard_field1": {
"foo": "bar",
"alice": "bob"
},
"wildcard_field2": {
"foo": "rba",
"alice": "bbo"
}
}
}
}
Is there a way to get the first result or is it really a bugfix/new feature?
I also wanted this. I could get it to display how I wanted by taking out the Nested model, and having the wildcard field being referenced directly - but this functionally was wrong. So I ended up just being okay with the display looking looking a little off. Nevertheless if this is resolved that would be cool! :)
for me, model definition:
from flask import Flask
from flask_restx import Resource, Api, fields
app = Flask(__name__)
api = Api(app)
wild = {"*": fields.Wildcard(fields.String())}
final_model = api.model(
'Final model', {"field1": fields.String(), "nested_and_dynamic_keys": fields.Nested(wild)}
)
@api.route('/hello')
class HelloWorld(Resource):
@api.marshal_with(final_model)
def get(self):
return {
'foo': {
'nested_string': 'foo'
},
'bar': {
'nested_string': 'bar'
}
}
if __name__ == '__main__':
app.run(debug=True)
desired output:
{
"field1": "value1",
"nested_and_dynamic_keys": {
"wildcard_field1": "foo"
"wildcard_field2": "bar"
}
}
actual output:
{
"field1": "value1",
"nested_and_dynamic_keys": {
"*": {
"wildcard_field1": "foo"
"wildcard_field2": "bar"
}
}
}
When you said "kind of expected", I'm not sure if you mean that wildcards weren't meant for @anthiras' usecase or not.
Actually, I didn't find yet a swagger definition that matches a model with wildcard fields. That's the reason why the generated schema may look strange.
I would expect a wildcard to be a pattern. https://swagger.io/specification/#schemaObject In the yaml style:
username:
type: string
pattern: "[a-z0-9]{8,64}"
minLength: 8
maxLength: 64
So a wildcard in a nested field would be:
{
"field1": "value1",
"nested_and_dynamic_keys": {
"variable_name": {
"pattern": "regex",
},
"variable_name": {
"pattern": "regex"
}
}
}
I don't have access to some of the examples I made in the past at the moment...and sadly won't for roughly a month. I'll try and mock this up
@ziirish Here is an example of swagger definition for wildcard :
swagger: '2.0'
paths:
'/ipam/{subnet}-{mask}':
get:
responses:
'200':
description: OK
schema:
$ref: '#/definitions/document%20download%20response'
'400':
description: Failed. Bad post data.
'401':
description: Unauthorized
'403':
description: Forbidden
description: Request the number of available IPv4 by subnet/mask
operationId: get_add
parameters:
- name: subnet
in: path
required: true
type: string
description: 'IP Network address ex: 192.168.10.0'
- name: mask
in: path
required: true
type: string
description: 'Mask bits ex: 24'
tags:
- ipam
info:
title: Network and Security REST API
version: v0.7.3
description: Network and Security REST API
contact:
name: Florian Lacommare
produces:
- application/json
consumes:
- application/json
definitions:
document download response:
properties:
free_ip_number:
type: string
description: Number of IPv4 available in a subnet.
free_ip_percent:
type: string
description: Percentage of IP addresses available in a subnet.
ip_list:
description: Dictionary with ips as key and properties of the ip as value.
type: object
additionalProperties:
$ref: '#/definitions/IP'
example:
ip1:
dns_name: test
alias: test
type: test
requester: test
description: test
environment: test
ip2:
dns_name: test
alias: test
type: test
requester: test
description: test
environment: test
type: object
IP:
properties:
dns_name:
type: string
description: Domain name
example: frsvp.com
alias:
type: string
description: alias
example: test1.com
type:
type: string
description: Type of equipment
requester:
type: string
description: The firstname_lastname of the requester
description:
type: string
description: 'The description of your IP (server name, project, etc)'
environment:
type: string
description: Environment type
type: object
The example output show in Swagger :
{
"free_ip_number": "string",
"free_ip_percent": "string",
"ip_list": {
"ip1": {
"dns_name": "test",
"alias": "test",
"type": "test",
"requester": "test",
"description": "test",
"environment": "test"
},
"ip2": {
"dns_name": "test",
"alias": "test",
"type": "test",
"requester": "test",
"description": "test",
"environment": "test"
}
}
}

It seems like wildcards can't live in the root level of the object with api.model()... Wish it would be added soon...
@ziirish I suffer from this behavior as well and in my opinion this is clearly a bug as @FloLaco showed. Shall I make a PR which "fixes" this? Maybe with a new default pre-set parameter like nested=True for backwards compatibility reasons? Or is this intended behavior and a "feature" and no "fix" is welcomed?
Is there some solution / workaround for this issue?