Set data
    :param key: A unique to set, best to use __name__
    :param value: dict - the value to save
    :param reset: bool - If true, it will reset the value to the current one. 
                 if False, it will just update the stored value with the current
                 one
    :param init: bool - If True, it will create the entry if it doesn't exits
                 next time invoked, it will not save anything
    :return:

def set(key, value={}, reset=False, init=False):
    """
    Set data
    :param key: A unique to set, best to use __name__
    :param value: dict - the value to save
    :param reset: bool - If true, it will reset the value to the current one. 
                 if False, it will just update the stored value with the current
                 one
    :param init: bool - If True, it will create the entry if it doesn't exits
                 next time invoked, it will not save anything
    :return: 
    """
    if not isinstance(value, dict):
        raise ValueError("App Data value must be a dict")

    k = AppData.get_by_key(key, True)
    if not k:
        AppData.create(key=make_key(key), value=value)
    else:
        if init is False:
            if reset is False:
                nv = copy.deepcopy(value)
                value = copy.deepcopy(k.value)
                value.update(nv)
            k.update(value=value)