human
Complete this python program:
def get_action(action):
assistant
#Here is the Python program you requested.

    """Return the named :py:mod:`ckan.logic.action` function.
    For example ``get_action(\package_create\)`` will normally return the
    :py:func:`ckan.logic.action.create.package_create()` function.
    For documentation of the available action functions, see
    :ref:`api-reference`.
    You should always use ``get_action()`` instead of importing an action
    function directly, because :py:class:`~ckan.plugins.interfaces.IActions`
    plugins can override action functions, causing ``get_action()`` to return a
    plugin-provided function instead of the default one.
    Usage::
    import ckan.plugins.toolkit as toolkit
    # Call the package_create action function:
    toolkit.get_action(\package_create\)(context, data_dict)
    As the context parameter passed to an action function is commonly::
    context = {\model\: ckan.model, \session\: ckan.model.Session,
    \user\: pylons.c.user}
    an action function returned by ``get_action()`` will automatically add
    these parameters to the context if they are not defined.  This is
    especially useful for plugins as they should not really be importing parts
    of ckan eg :py:mod:`ckan.model` and as such do not have access to ``model``
    or ``model.Session``.
    If a ``context`` of ``None`` is passed to the action function then the
    default context dict will be created.
    .. note::
    Many action functions modify the context dict. It can therefore
    not be reused for multiple calls of the same or different action
    functions.
    :param action: name of the action function to return,
    eg. ``\package_create\``
    :type action: string
    :returns: the named action function
    :rtype: callable
    """
    if _actions:
        if (action not in _actions):
            raise KeyError(("Action    '%s'    not    found" % action))
        return _actions.get(action)
    for action_module_name in ['get', 'create', 'update', 'delete', 'patch']:
        module_path = ('ckan.logic.action.' + action_module_name)
        module = __import__(module_path)
        for part in module_path.split('.')[1:]:
            module = getattr(module, part)
        for (k, v) in module.__dict__.items():
            if (not k.startswith('_')):
                if (hasattr(v, '__call__') and ((v.__module__ == module_path) or hasattr(v, '__replaced'))):
                    _actions[k] = v
                    if ((action_module_name == 'get') and (not hasattr(v, 'side_effect_free'))):
                        v.side_effect_free = True
    resolved_action_plugins = {}
    fetched_actions = {}
    chained_actions = defaultdict(list)
    for plugin in p.PluginImplementations(p.IActions):
        for (name, auth_function) in plugin.get_actions().items():
            if _is_chained_action(auth_function):
                chained_actions[name].append(auth_function)
            elif (name in resolved_action_plugins):
                raise NameConflict(('The    action    %r    is    already    implemented    in    %r' % (name, resolved_action_plugins[name])))
            else:
                resolved_action_plugins[name] = plugin.name
                auth_function.auth_audit_exempt = True
                fetched_actions[name] = auth_function
    for (name, func_list) in chained_actions.iteritems():
        if (name not in fetched_actions):
            raise NotFound(('The    action    %r    is    not    found    for    chained    action' % name))
        for func in reversed(func_list):
            prev_func = fetched_actions[name]
            fetched_actions[name] = functools.partial(func, prev_func)
    _actions.update(fetched_actions)
    for (action_name, _action) in _actions.items():
        def make_wrapped(_action, action_name):
          ...