Wednesday 27 April 2022

Build Dynamic Marshal_With in Flask (Python) based on conditions

To create a dynamic marshalling based on condition or parameter type, please follow the instruction below:

# Constants
MARSHELL_WITH_SCHEMAS = {
    "condition_1": Condition1Schema,
    "condition_2": Condition2Schema,
}


# To build dynamic marshalling based on report type
def selective_marshal_with():
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            condition_type = kwargs.get("condition_type", None)

            # Get marshalled with dynamic schema by condition type
            marshal_with_func = marshal_with(MARSHELL_WITH_SCHEMAS.get(condition_type, None))(func)

            return marshal_with_func(*args, **kwargs)

        return wrapper

    return decorator

# Actual class to connect view to URL
class MyViewClass(MethodResource, Resource):
    @doc(description="My View API", tags=["My View List"])
    @use_kwargs(MyQueryParams, location="query")
    @selective_marshal_with()
    @standard_api("My View List")
    def get(self, **kwargs):
        # you get code here....
    
The MyQueryParams can/should be in seperate schema file for e.g. rest/db/schema/my_view_schema.py

class MyQueryParams(Schema):
    """Query parameters for View List API."""

    condition_type = fields.Str(attribute="condition_type", required=True)

Hope it helps!