from typing import Iterable
from typing import Dict
from typing import Any
from typing import List
from typing import Tuple


def sort_widgets(widgets: Iterable[Dict[str, Any]]) -> List[Dict[str, Any]]:
    """
    Sort raw widget data (as returned from the API) according to the position
    of the widgets in the dashboard (top to bottom, left to right)
    Redash does not return widgets in order of their position,
    so we do this to ensure that we look at widgets in a sensible order.
    """

    def row_and_col(widget: Dict[str, Any]) -> Tuple[Any, Any]:
        # these entities usually but not always have explicit rows and cols
        pos = widget['options'].get('position', {})
        return (pos.get('row', 0), pos.get('col', 0))

    return sorted(widgets, key=row_and_col)