Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask restx model nested wildcard dict

I was wondering if I'm only one struggling with such problem.

Lets take dict for example:

data = {'totalSize': 3000, 'freq': 2400,
        'distribution':
            {'ram1': {'size': 200, 'status': 'OK'},
             'ram2': {'size': 100, 'status': 'OK'}
             }
        }

Please not that ram1/2 is dynamic keys that can not be known in advance

Question, how should my api.model look like ? I have:

wild = {"*": fields.Wildcard(fields.String())}
hw_memory = api.model('Memory', {
    'totalSize': fields.Integer(description='total memory size in MB',
                                example=1024),
    'freq': fields.Integer(description='Speed of ram in mhz', example=800),
    'distribution': fields.Nested(wild),
})

It is working, however it does not validate anything below "distribution", in other words, works like wildcard, anything there will be accepted. Is there a way to nest dicts in such way having wildcard dynamic key ?

like image 516
Devourer Avatar asked Dec 01 '25 03:12

Devourer


1 Answers

First of all, Wildcard type of field accepts the definition of the dict values, not the definition of the keys, i.e fields.Wildcard(fields.String()) validates that dict values can be only of string type (in your case you need to provide definition of distribution).

The second mistake is that you are defining distribution field as Nested object instead of using Wilcard.

The following code should work for validation purpose:


DISTRIBUTION_MODEL = NAMESPACE.model("Distribution", dict(
    size=fields.Integer(),
    status=fields.String(),
))

MEMORY_MODEL = NAMESPACE.model("Memory", dict(
    totalSize=fields.Integer(description='total memory size in MB',
                             example=1024),
    freq=fields.Integer(description='Speed of ram in mhz', example=800),
    distribution=fields.Wildcard(fields.Nested(DISTRIBUTION_MODEL))
))

Unfortunately, it doesn't work for marshaling. The next code should work for marshaling, but doesn't for validation input payload:


OUTPUT_MEMORY_MODEL = NAMESPACE.model("OutputMemory", dict(
    totalSize=fields.Integer(description='total memory size in MB',
                             example=1024),
    freq=fields.Integer(description='Speed of ram in mhz', example=800),
    distribution=flask_utils.fields.Nested(
        NAMESPACE.model(
            "distributions", {
                "*": fields.Wildcard(
                    # DISTRIBUTION_MODEL is taken from previous snippet
                    fields.Nested(DISTRIBUTION_MODEL)
                )
            }
        )
    )
))
like image 67
Andrey Kurilin Avatar answered Dec 02 '25 15:12

Andrey Kurilin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!