Plugins toolkit reference

As well as using the variables made available to them by implementing plugin interfaces, plugins will likely want to be able to use parts of the CKAN core library. To allow this, CKAN provides a stable set of classes and functions that plugins can use safe in the knowledge that this interface will remain stable, backward-compatible and with clear deprecation guidelines when new versions of CKAN are released. This interface is available in CKAN’s plugins toolkit.

class ckan.plugins.toolkit.BaseController

Base class for CKAN controller classes to inherit from.

class ckan.plugins.toolkit.CkanCommand

Base class for classes that implement CKAN paster commands to inherit.

class ckan.plugins.toolkit.CkanVersionException

Exception raised by requires_ckan_version() if the required CKAN version is not available.

class ckan.plugins.toolkit.DefaultDatasetForm

The default implementation of IDatasetForm.

This class serves two purposes:

  1. It provides a base class for plugin classes that implement IDatasetForm to inherit from, so they can inherit the default behavior and just modify the bits they need to.
  2. It is used as the default fallback plugin when no registered IDatasetForm plugin handles the given dataset type and no other plugin has registered itself as the fallback plugin.


DefaultDatasetForm doesn’t call implements(), because we don’t want it being registered.

class ckan.plugins.toolkit.DefaultGroupForm

Provides a default implementation of the pluggable Group controller behaviour.

This class has 2 purposes:

  • it provides a base class for IGroupForm implementations to use if only a subset of the method hooks need to be customised.
  • it provides the fallback behaviour if no plugin is setup to provide the fallback behaviour.
Note - this isn’t a plugin implementation. This is deliberate, as we
don’t want this being registered.
class ckan.plugins.toolkit.DefaultOrganizationForm
class ckan.plugins.toolkit.HelperError

Raised if an attempt to access an undefined helper is made.

Normally, this would be a subclass of AttributeError, but Jinja2 will catch and ignore them. We want this to be an explicit failure re #2908.

class ckan.plugins.toolkit.Invalid

Exception raised by some validator, converter and dictization functions when the given value is invalid.

class ckan.plugins.toolkit.NotAuthorized

Exception raised when the user is not authorized to call the action.

For example package_create() raises NotAuthorized if the user is not authorized to create packages.

class ckan.plugins.toolkit.ObjectNotFound

Exception raised by logic functions when a given object is not found.

For example package_show() raises ObjectNotFound if no package with the given id exists.

class ckan.plugins.toolkit.StopOnError

error to stop validations for a particualar key

class ckan.plugins.toolkit.UnknownValidator

Exception raised when a requested validator function cannot be found.

class ckan.plugins.toolkit.ValidationError

Exception raised by action functions when validating their given data_dict fails.

ckan.plugins.toolkit._(*args, **kwargs)

Translates a string to the current locale.

The _() function is a reference to the ugettext() function. Everywhere in your code where you want strings to be internationalized (made available for translation into different languages), wrap them in the _() function, eg.:

msg = toolkit._("Hello")

Returns the localized unicode string.

ckan.plugins.toolkit.abort(status_code=None, detail='', headers=None, comment=None)

Abort the current request immediately by returning an HTTP exception.

This is a wrapper for pylons.controllers.util.abort() that adds some CKAN custom behavior, including allowing IAuthenticator plugins to alter the abort response, and showing flash messages in the web interface.

ckan.plugins.toolkit.add_ckan_admin_tab(cls, config, route_name, tab_label, config_var='ckan.admin_tabs')

Update ‘ckan.admin_tabs’ dict the passed config dict.

ckan.plugins.toolkit.add_public_directory(cls, config, relative_path)

Add a path to the extra_public_paths config setting.

The path is relative to the file calling this function.

ckan.plugins.toolkit.add_resource(cls, path, name)

Add a Fanstatic resource library to CKAN.

Fanstatic libraries are directories containing static resource files (e.g. CSS, JavaScript or image files) that can be accessed from CKAN.

See Theming guide for more details.

ckan.plugins.toolkit.add_template_directory(cls, config, relative_path)

Add a path to the extra_template_paths config setting.

The path is relative to the file calling this function.


Convert a string (e.g. 1, true, True) from the config file into a boolean.

For example: if toolkit.asbool(config.get('ckan.legacy_templates', False)):


Convert a string from the config file into an int.

For example: bar = toolkit.asint(config.get('', 0))

ckan.plugins.toolkit.aslist(obj, sep=None, strip=True)

Convert a space-separated string from the config file into a list.

For example: bar = toolkit.aslist(config.get('', []))


Flag an auth function as not requiring a logged in user

This means that check_access won’t automatically raise a NotAuthorized exception if an authenticated user is not provided in the context. (The auth function can still return False if for some reason access is not granted).


Flag an auth function as requiring a logged in user

This means that check_access will automatically raise a NotAuthorized exception if an authenticated user is not provided in the context, without calling the actual auth function.


A decorator that prevents sysadmins from being automatically authorized to call an action function.

Normally sysadmins are allowed to call any action function (for example when they’re using the Action API or the web interface), if the user is a sysadmin the action function’s authorization function will not even be called.

If an action function is decorated with this decorator, then its authorization function will always be called, even if the user is a sysadmin.


The Pylons template context object.

This object is used to pass request-specific information to different parts of the code in a thread-safe way (so that variables from different requests being executed at the same time don’t get confused with each other).

Any attributes assigned to c are available throughout the template and application code, and are local to the current request.

ckan.plugins.toolkit.check_access(action, context, data_dict=None)

Calls the authorization function for the provided action

This is the only function that should be called to determine whether a user (or an anonymous request) is allowed to perform a particular action.

The function accepts a context object, which should contain a ‘user’ key with the name of the user performing the action, and optionally a dictionary with extra data to be passed to the authorization function.

For example:

check_access('package_update', context, data_dict)

If not already there, the function will add an auth_user_obj key to the context object with the actual User object (in case it exists in the database). This check is only performed once per context object.

Raise NotAuthorized if the user is not authorized to call the named action function.

If the user is authorized to call the action, return True.

  • action (string) – the name of the action function, eg. 'package_create'
  • context (dict) –
  • data_dict (dict) –

NotAuthorized if the user is not authorized to call the named action

ckan.plugins.toolkit.check_ckan_version(cls, min_version=None, max_version=None)

Return True if the CKAN version is greater than or equal to min_version and less than or equal to max_version, return False otherwise.

If no min_version is given, just check whether the CKAN version is less than or equal to max_version.

If no max_version is given, just check whether the CKAN version is greater than or equal to min_version.

  • min_version (string) – the minimum acceptable CKAN version, eg. '2.1'
  • max_version (string) – the maximum acceptable CKAN version, eg. '2.3'

The CKAN configuration object.

It stores the configuration values defined in the CKAN configuration file, eg:

title = toolkit.config.get("ckan.site_title")
ckan.plugins.toolkit.enqueue_job(fn, args=None, kwargs=None, title=None, queue=u'default')

Enqueue a job to be run in the background.

  • fn (function) – Function to be executed in the background
  • args (list) – List of arguments to be passed to the function. Pass an empty list if there are no arguments (default).
  • kwargs (dict) – Dict of keyword arguments to be passed to the function. Pass an empty dict if there are no keyword arguments (default).
  • title (string) – Optional human-readable title of the job.
  • queue (string) – Name of the queue. If not given then the default queue is used.

The enqueued job.

Return type:



Return the named ckan.logic.action function.

For example get_action('package_create') will normally return the ckan.logic.action.create.package_create() function.

For documentation of the available action functions, see Action API reference.

You should always use get_action() instead of importing an action function directly, because IActions plugins can override action functions, causing get_action() to return a plugin-provided function instead of the default one.


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 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.


Many action functions modify the context dict. It can therefore not be reused for multiple calls of the same or different action functions.

Parameters:action (string) – name of the action function to return, eg. 'package_create'
Returns:the named action function
Return type:callable

Return a validator function by name.

Parameters:validator (string) – the name of the validator function to return, eg. 'package_name_exists'
Raises:UnknownValidator if the named validator is not found
Returns:the named validator function
Return type:types.FunctionType
ckan.plugins.toolkit.get_or_bust(data_dict, keys)

Return the value(s) from the given data_dict for the given key(s).


single_value = get_or_bust(data_dict, 'a_key')
value_1, value_2 = get_or_bust(data_dict, ['key1', 'key2'])
  • data_dict (dictionary) – the dictionary to return the values from
  • keys (either a string or a list) – the key(s) for the value(s) to return

a single value from the dict if a single key was given, or a tuple of values if a list of keys was given


ckan.logic.ValidationError if one of the given keys is not in the given dictionary


Return a validator function by name.

Parameters:validator (string) – the name of the validator function to return, eg. 'package_name_exists'
Raises:UnknownValidator if the named validator is not found
Returns:the named validator function
Return type:types.FunctionType
class ckan.plugins.toolkit.literal

Represents an HTML literal.

This subclass of unicode has a .__html__() method that is detected by the escape() function.

Also, if you add another string to this string, the other string will be quoted and you will get back another literal object. Also literal(...) % obj will quote any value(s) from obj. If you do something like literal(...) + literal(...), neither string will be changed because escape(literal(...)) doesn’t change the original literal.

Changed in WebHelpers 1.2: the implementation is now now a subclass of markupsafe.Markup. This brings some new methods: .escape (class method), .unescape, and .striptags.

ckan.plugins.toolkit.load_config(config, load_site_user=True)
ckan.plugins.toolkit.navl_validate(data, schema, context=None)

Validate an unflattened nested dict against a schema.

ckan.plugins.toolkit.redirect_to(*args, **kw)

Issue a redirect: return an HTTP response with a 302 Moved header.

This is a wrapper for routes.redirect_to() that maintains the user’s selected language when redirecting.

The arguments to this function identify the route to redirect to, they’re the same arguments as ckan.plugins.toolkit.url_for() accepts, for example:

import ckan.plugins.toolkit as toolkit

# Redirect to /dataset/my_dataset.
toolkit.redirect_to(controller='package', action='read',

Or, using a named route:

toolkit.redirect_to('dataset_read', id='changed')
ckan.plugins.toolkit.render(template_name, extra_vars=None, cache_key=None, cache_type=None, cache_expire=None, cache_force=None, renderer=None)

Render a template and return the output.

This is CKAN’s main template rendering function.


Document the parameters of ckan.plugins.toolkit.render().

ckan.plugins.toolkit.render_snippet(cls, template, data=None)

Render a template snippet and return the output.

See Theming guide.


The Pylons request object.

A new request object is created for each HTTP request. It has methods and attributes for getting things like the request headers, query-string variables, request body variables, cookies, the request URL, etc.

ckan.plugins.toolkit.requires_ckan_version(cls, min_version, max_version=None)

Raise CkanVersionException if the CKAN version is not greater than or equal to min_version and less then or equal to max_version.

If no max_version is given, just check whether the CKAN version is greater than or equal to min_version.

Plugins can call this function if they require a certain CKAN version, other versions of CKAN will crash if a user tries to use the plugin with them.

  • min_version (string) – the minimum acceptable CKAN version, eg. '2.1'
  • max_version (string) – the maximum acceptable CKAN version, eg. '2.3'

The Pylons response object.

Pylons uses this object to generate the HTTP response it returns to the web browser. It has attributes like the HTTP status code, the response headers, content type, cookies, etc.


A decorator that marks the given action function as side-effect-free.

Action functions decorated with this decorator can be called with an HTTP GET request to the Action API. Action functions that don’t have this decorator must be called with a POST request.

If your CKAN extension defines its own action functions using the IActions plugin interface, you can use this decorator to make your actions available with GET requests instead of just with POST requests.


import ckan.plugins.toolkit as toolkit

def my_custom_action_function(context, data_dict):

(Then implement IActions to register your action function with CKAN.)

ckan.plugins.toolkit.ungettext(*args, **kwargs)

Translates a string with plural forms to the current locale.

Mark a string for translation that has pural forms in the format ungettext(singular, plural, n). Returns the localized unicode string of the pluralized value.

Mark a string to be localized as follows:

msg = toolkit.ungettext("Mouse", "Mice", len(mouses))
ckan.plugins.toolkit.url_for(*args, **kw)

Return the URL for an endpoint given some parameters.

This is a wrapper for flask.url_for() and routes.url_for() that adds some extra features that CKAN needs.

To build a URL for a Flask view, pass the name of the blueprint and the view function separated by a period ., plus any URL parameters:

url_for('api.action', ver=3, logic_function='status_show')
# Returns /api/3/action/status_show

For a fully qualified URL pass the _external=True parameter. This takes the ckan.site_url and ckan.root_path settings into account:

url_for('api.action', ver=3, logic_function='status_show',
# Returns

URLs built by Pylons use the Routes syntax:

url_for(controller='package', action='read', id='my_dataset')
# Returns '/dataset/my_dataset'

Or, using a named route:

url_for('dataset_read', id='changed')
# Returns '/dataset/changed'

Use qualified=True for a fully qualified URL when targeting a Pylons endpoint.

For backwards compatibility, an effort is made to support the Pylons syntax when building a Flask URL, but this support might be dropped in the future, so calls should be updated.