CKAN 2.2 documentation » Writing CKAN extensions »

Plugin interfaces reference

ckan.plugins contains a few core classes and functions for plugins to use:

ckan.plugins

class ckan.plugins.SingletonPlugin(**kwargs)

Base class for plugins which are singletons (ie most of them)

One singleton instance of this class will be created when the plugin is loaded. Subsequent calls to the class constructor will always return the same singleton instance.

class ckan.plugins.Plugin(**kwargs)

Base class for plugins which require multiple instances.

Unless you need multiple instances of your plugin object you should probably use SingletonPlugin.

ckan.plugins.implements(interface, namespace=None, inherit=False, service=True)

Can be used in the class definition of Plugin subclasses to declare the extension points that are implemented by this interface class.

If the inherits option is True, then this Plugin class inherits from the interface class.

ckan.plugins.interfaces

A collection of interfaces that CKAN plugins can implement to customize and extend CKAN.

class ckan.plugins.interfaces.IMiddleware

Hook into Pylons middleware stack

make_middleware(app, config)

Return an app configured with this middleware

class ckan.plugins.interfaces.IGenshiStreamFilter

Hook into template rendering. See ckan.lib.base.py:render

filter(stream)

Return a filtered Genshi stream. Called when any page is rendered.

Parameters:stream – Genshi stream of the current output document
Returns:filtered Genshi stream
class ckan.plugins.interfaces.IRoutes

Plugin into the setup of the routes map creation.

before_map(map)

Called before the routes map is generated. before_map is before any other mappings are created so can override all other mappings.

Parameters:map – Routes map object
Returns:Modified version of the map object
after_map(map)

Called after routes map is set up. after_map can be used to add fall-back handlers.

Parameters:map – Routes map object
Returns:Modified version of the map object
class ckan.plugins.interfaces.IMapper

A subset of the SQLAlchemy mapper extension hooks. See http://www.sqlalchemy.org/docs/05/reference/orm/interfaces.html#sqlalchemy.orm.interfaces.MapperExtension

Example:

>>> class MyPlugin(SingletonPlugin):
...
...     implements(IMapper)
...
...     def after_update(self, mapper, connection, instance):
...         log("Updated: %r", instance)
before_insert(mapper, connection, instance)

Receive an object instance before that instance is INSERTed into its table.

before_update(mapper, connection, instance)

Receive an object instance before that instance is UPDATEed.

before_delete(mapper, connection, instance)

Receive an object instance before that instance is DELETEed.

after_insert(mapper, connection, instance)

Receive an object instance after that instance is INSERTed.

after_update(mapper, connection, instance)

Receive an object instance after that instance is UPDATEed.

after_delete(mapper, connection, instance)

Receive an object instance after that instance is DELETEed.

class ckan.plugins.interfaces.ISession

A subset of the SQLAlchemy session extension hooks.

after_begin(session, transaction, connection)

Execute after a transaction is begun on a connection

before_flush(session, flush_context, instances)

Execute before flush process has started.

after_flush(session, flush_context)

Execute after flush has completed, but before commit has been called.

before_commit(session)

Execute right before commit is called.

after_commit(session)

Execute after a commit has occured.

after_rollback(session)

Execute after a rollback has occured.

class ckan.plugins.interfaces.IDomainObjectModification

Receives notification of new, changed and deleted datesets.

class ckan.plugins.interfaces.IResourceUrlChange

Receives notification of changed urls.

class ckan.plugins.interfaces.IResourcePreview

Add custom data previews for resource file-types.

can_preview(data_dict)

Return info on whether the plugin can preview the resource.

This can be done in two ways:

  1. The old way is to just return True or False.

  2. The new way is to return a dict with three keys:

    'can_preview' (boolean)

    True if the extension can preview the resource.

    'fixable' (string)

    A string explaining how preview for the resource could be enabled, for example if the resource_proxy plugin was enabled.

    'quality' (int)

    How good the preview is: 1 (poor), 2 (average) or 3 (good). When multiple preview extensions can preview the same resource, this is used to determine which extension will be used.

Parameters:data_dict (dictionary) – the resource to be previewed and the dataset that it belongs to.

Make sure to check the on_same_domain value of the resource or the url if your preview requires the resource to be on the same domain because of the same-origin policy. To find out how to preview resources that are on a different domain, read Viewing remote resources: the resource proxy.

setup_template_variables(context, data_dict)

Add variables to c just prior to the template being rendered. The data_dict contains the resource and the package.

Change the url to a proxied domain if necessary.

preview_template(context, data_dict)

Returns a string representing the location of the template to be rendered for the read page. The data_dict contains the resource and the package.

class ckan.plugins.interfaces.ITagController

Hook into the Tag controller. These will usually be called just before committing or returning the respective object, i.e. all validation, synchronization and authorization setup are complete.

before_view(tag_dict)

Extensions will recieve this before the tag gets displayed. The dictionary passed will be the one that gets sent to the template.

class ckan.plugins.interfaces.IGroupController

Hook into the Group controller. These will usually be called just before committing or returning the respective object, i.e. all validation, synchronization and authorization setup are complete.

before_view(pkg_dict)

Extensions will recieve this before the group gets displayed. The dictionary passed will be the one that gets sent to the template.

class ckan.plugins.interfaces.IOrganizationController

Hook into the Organization controller. These will usually be called just before committing or returning the respective object, i.e. all validation, synchronization and authorization setup are complete.

before_view(pkg_dict)

Extensions will recieve this before the organization gets displayed. The dictionary passed will be the one that gets sent to the template.

class ckan.plugins.interfaces.IPackageController

Hook into the package controller. (see IGroupController)

after_create(context, pkg_dict)

Extensions will receive the validated data dict after the package has been created (Note that the create method will return a package domain object, which may not include all fields). Also the newly created package id will be added to the dict.

after_update(context, pkg_dict)

Extensions will receive the validated data dict after the package has been updated (Note that the edit method will return a package domain object, which may not include all fields).

after_delete(context, pkg_dict)

Extensions will receive the data dict (tipically containing just the package id) after the package has been deleted.

after_show(context, pkg_dict)

Extensions will receive the validated data dict after the package is ready for display (Note that the read method will return a package domain object, which may not include all fields).

Extensions will receive a dictionary with the query parameters, and should return a modified (or not) version of it.

search_params will include an extras dictionary with all values from fields starting with ext_, so extensions can receive user input from specific fields.

Extensions will receive the search results, as well as the search parameters, and should return a modified (or not) object with the same structure:

{‘count’: ‘’, ‘results’: ‘’, ‘facets’: ‘’}

Note that count and facets may need to be adjusted if the extension changed the results for some reason.

search_params will include an extras dictionary with all values from fields starting with ext_, so extensions can receive user input from specific fields.

before_index(pkg_dict)

Extensions will receive what will be given to the solr for indexing. This is essentially a flattened dict (except for multli-valued fields such as tags) of all the terms sent to the indexer. The extension can modify this by returning an altered version.

before_view(pkg_dict)

Extensions will recieve this before the dataset gets displayed. The dictionary passed will be the one that gets sent to the template.

class ckan.plugins.interfaces.IResourceController

Hook into the resource controller.

before_show(resource_dict)

Extensions will receive the validated data dict before the resource is ready for display.

class ckan.plugins.interfaces.IPluginObserver

Plugin to the plugin loading mechanism

before_load(plugin)

Called before a plugin is loaded This method is passed the plugin class.

after_load(service)

Called after a plugin has been loaded. This method is passed the instantiated service object.

before_unload(plugin)

Called before a plugin is loaded This method is passed the plugin class.

after_unload(service)

Called after a plugin has been unloaded. This method is passed the instantiated service object.

class ckan.plugins.interfaces.IConfigurable

Pass configuration to plugins and extensions

configure(config)

Called by load_environment

class ckan.plugins.interfaces.IConfigurer

Configure CKAN (pylons) environment via the pylons.config object

update_config(config)

Called by load_environment at earliest point when config is available to plugins. The config should be updated in place.

Parameters:configpylons.config object
class ckan.plugins.interfaces.IActions

Allow adding of actions to the logic layer.

get_actions()

Should return a dict, the keys being the name of the logic function and the values being the functions themselves.

By decorating a function with the ckan.logic.side_effect_free decorator, the associated action will be made available by a GET request (as well as the usual POST request) through the action API.

class ckan.plugins.interfaces.IAuthFunctions

Override CKAN’s authorization functions, or add new auth functions.

get_auth_functions()

Return the authorization functions provided by this plugin.

Return a dictionary mapping authorization function names (strings) to functions. For example:

{'user_create': my_custom_user_create_function,
 'group_create': my_custom_group_create}

When a user tries to carry out an action via the CKAN API or web interface and CKAN or a CKAN plugin calls check_access('some_action') as a result, an authorization function named 'some_action' will be searched for in the authorization functions registered by plugins and in CKAN’s core authorization functions (found in ckan/logic/auth/).

For example when a user tries to create a package, a 'package_create' authorization function is searched for.

If an extension registers an authorization function with the same name as one of CKAN’s default authorization functions (as with 'user_create' and 'group_create' above), the extension’s function will override the default one.

Each authorization function should take two parameters context and data_dict, and should return a dictionary {'success': True} to authorize the action or {'success': False} to deny it, for example:

def user_create(context, data_dict=None):
    if (some condition):
        return {'success': True}
    else:
        return {'success': False, 'msg': 'Not allowed to register'}

The context object will contain a model that can be used to query the database, a user containing the name of the user doing the request (or their IP if it is an anonymous web request) and an auth_user_obj containing the actual model.User object (or None if it is an anonymous request).

See ckan/logic/auth/ for more examples.

Note that by default, all auth functions provided by extensions are assumed to require a validated user or API key, otherwise a ckan.logic.NotAuthorized: exception will be raised. This check will be performed before calling the actual auth function. If you want to allow anonymous access to one of your actions, its auth function must be decorated with the auth_allow_anonymous_access decorator, available on the plugins toolkit.

For example:

import ckan.plugins as p

@p.toolkit.auth_allow_anonymous_access
def my_search_action(context, data_dict):
    # Note that you can still return {'success': False} if for some
    # reason access is denied.

def my_create_action(context, data_dict):
    # Unless there is a logged in user or a valid API key provided
    # NotAuthorized will be raised before reaching this function.
class ckan.plugins.interfaces.ITemplateHelpers

Add custom template helper functions.

By implementing this plugin interface plugins can provide their own template helper functions, which custom templates can then access via the h variable.

See ckanext/example_itemplatehelpers for an example plugin.

get_helpers()

Return a dict mapping names to helper functions.

The keys of the dict should be the names with which the helper functions will be made available to templates, and the values should be the functions themselves. For example, a dict like: {'example_helper': example_helper} allows templates to access the example_helper function via h.example_helper().

Function names should start with the name of the extension providing the function, to prevent name clashes between extensions.

class ckan.plugins.interfaces.IDatasetForm

Customize CKAN’s dataset (package) schemas and forms.

By implementing this interface plugins can customise CKAN’s dataset schema, for example to add new custom fields to datasets.

Multiple IDatasetForm plugins can be used at once, each plugin associating itself with different package types using the package_types() and is_fallback() methods below, and then providing different schemas and templates for different types of dataset. When a package controller action is invoked, the type field of the package will determine which IDatasetForm plugin (if any) gets delegated to.

When implementing IDatasetForm, you can inherit from ckan.plugins.toolkit.DefaultDatasetForm, which provides default implementations for each of the methods defined in this interface.

See ckanext/example_idatasetform for an example plugin.

package_types()

Return an iterable of package types that this plugin handles.

If a request involving a package of one of the returned types is made, then this plugin instance will be delegated to.

There cannot be two IDatasetForm plugins that return the same package type, if this happens then CKAN will raise an exception at startup.

Return type:iterable of strings
is_fallback()

Return True if this plugin is the fallback plugin.

When no IDatasetForm plugin’s package_types() match the type of the package being processed, the fallback plugin is delegated to instead.

There cannot be more than one IDatasetForm plugin whose is_fallback() method returns True, if this happens CKAN will raise an exception at startup.

If no IDatasetForm plugin’s is_fallback() method returns True, CKAN will use DefaultDatasetForm as the fallback.

Return type:boolean
create_package_schema()

Return the schema for validating new dataset dicts.

CKAN will use the returned schema to validate and convert data coming from users (via the dataset form or API) when creating new datasets, before entering that data into the database.

If it inherits from ckan.plugins.toolkit.DefaultDatasetForm, a plugin can call DefaultDatasetForm‘s create_package_schema() method to get the default schema and then modify and return it.

CKAN’s convert_to_tags() or convert_to_extras() functions can be used to convert custom fields into dataset tags or extras for storing in the database.

See ckanext/example_idatasetform for examples.

Returns:a dictionary mapping dataset dict keys to lists of validator and converter functions to be applied to those keys
Return type:dictionary
update_package_schema()

Return the schema for validating updated dataset dicts.

CKAN will use the returned schema to validate and convert data coming from users (via the dataset form or API) when updating datasets, before entering that data into the database.

If it inherits from ckan.plugins.toolkit.DefaultDatasetForm, a plugin can call DefaultDatasetForm‘s update_package_schema() method to get the default schema and then modify and return it.

CKAN’s convert_to_tags() or convert_to_extras() functions can be used to convert custom fields into dataset tags or extras for storing in the database.

See ckanext/example_idatasetform for examples.

Returns:a dictionary mapping dataset dict keys to lists of validator and converter functions to be applied to those keys
Return type:dictionary
show_package_schema()

Return a schema to validate datasets before they’re shown to the user.

CKAN will use the returned schema to validate and convert data coming from the database before it is returned to the user via the API or passed to a template for rendering.

If it inherits from ckan.plugins.toolkit.DefaultDatasetForm, a plugin can call DefaultDatasetForm‘s show_package_schema() method to get the default schema and then modify and return it.

If you have used convert_to_tags() or convert_to_extras() in your create_package_schema() and update_package_schema() then you should use convert_from_tags() or convert_from_extras() in your show_package_schema() to convert the tags or extras in the database back into your custom dataset fields.

See ckanext/example_idatasetform for examples.

Returns:a dictionary mapping dataset dict keys to lists of validator and converter functions to be applied to those keys
Return type:dictionary
setup_template_variables(context, data_dict)

Add variables to the template context for use in templates.

This function is called before a dataset template is rendered. If you have custom dataset templates that require some additional variables, you can add them to the template context ckan.plugins.toolkit.c here and they will be available in your templates. See ckanext/example_idatasetform for an example.

new_template()

Return the path to the template for the new dataset page.

The path should be relative to the plugin’s templates dir, e.g. 'package/new.html'.

Return type:string
read_template()

Return the path to the template for the dataset read page.

The path should be relative to the plugin’s templates dir, e.g. 'package/read.html'.

If the user requests the dataset in a format other than HTML (CKAN supports returning datasets in RDF or N3 format by appending .rdf or .n3 to the dataset read URL, see Linked Data and RDF) then CKAN will try to render a template file with the same path as returned by this function, but a different filename extension, e.g. 'package/read.rdf'. If your extension doesn’t have this RDF version of the template file, the user will get a 404 error.

Return type:string
edit_template()

Return the path to the template for the dataset edit page.

The path should be relative to the plugin’s templates dir, e.g. 'package/edit.html'.

Return type:string
search_template()

Return the path to the template for use in the dataset search page.

This template is used to render each dataset that is listed in the search results on the dataset search page.

The path should be relative to the plugin’s templates dir, e.g. 'package/search.html'.

Return type:string
history_template()

Return the path to the template for the dataset history page.

The path should be relative to the plugin’s templates dir, e.g. 'package/history.html'.

Return type:string
package_form()

Return the path to the template for the dataset form.

The path should be relative to the plugin’s templates dir, e.g. 'package/form.html'.

Return type:string
class ckan.plugins.interfaces.IGroupForm

Allows customisation of the group controller as a plugin.

The behaviour of the plugin is determined by 5 method hooks:

  • package_form(self)
  • form_to_db_schema(self)
  • db_to_form_schema(self)
  • check_data_dict(self, data_dict)
  • setup_template_variables(self, context, data_dict)

Furthermore, there can be many implementations of this plugin registered at once. With each instance associating itself with 0 or more package type strings. When a package controller action is invoked, the package type determines which of the registered plugins to delegate to. Each implementation must implement two methods which are used to determine the package-type -> plugin mapping:

  • is_fallback(self)
  • package_types(self)

Implementations might want to consider mixing in ckan.lib.plugins.DefaultGroupForm which provides default behaviours for the 5 method hooks.

is_fallback()

Returns true iff this provides the fallback behaviour, when no other plugin instance matches a package’s type.

There must be exactly one fallback controller defined, any attempt to register more than one will throw an exception at startup. If there’s no fallback registered at startup the ckan.lib.plugins.DefaultGroupForm used as the fallback.

group_types()

Returns an iterable of group type strings.

If a request involving a package of one of those types is made, then this plugin instance will be delegated to.

There must only be one plugin registered to each group type. Any attempts to register more than one plugin instance to a given group type will raise an exception at startup.

new_template()

Returns a string representing the location of the template to be rendered for the ‘new’ page. Uses the default_group_type configuration option to determine which plugin to use the template from.

index_template()

Returns a string representing the location of the template to be rendered for the index page. Uses the default_group_type configuration option to determine which plugin to use the template from.

read_template()

Returns a string representing the location of the template to be rendered for the read page

history_template()

Returns a string representing the location of the template to be rendered for the history page

edit_template()

Returns a string representing the location of the template to be rendered for the edit page

package_form()

Returns a string representing the location of the template to be rendered. e.g. “group/new_group_form.html”.

form_to_db_schema()

Returns the schema for mapping group data from a form to a format suitable for the database.

db_to_form_schema()

Returns the schema for mapping group data from the database into a format suitable for the form (optional)

check_data_dict(data_dict)

Check if the return data is correct.

raise a DataError if not.

setup_template_variables(context, data_dict)

Add variables to c just prior to the template being rendered.

class ckan.plugins.interfaces.IFacets

Allows specify which facets are displayed and also the names used.

facet_dicts are in the form {‘facet_name’: ‘display name’, ...} to allow translatable display names use _(...) eg {‘facet_name’: _(‘display name’), ...} and ensure that this is created each time the function is called.

The dict supplied is actually an ordered dict.

dataset_facets(facets_dict, package_type)

Update the facets_dict and return it.

group_facets(facets_dict, group_type, package_type)

Update the facets_dict and return it.

organization_facets(facets_dict, organization_type, package_type)

Update the facets_dict and return it.

class ckan.plugins.interfaces.IAuthenticator

EXPERIMENTAL

Allows custom authentication methods to be integrated into CKAN. Currently it is experimental and the interface may change.

identify()

called to identify the user.

If the user is identfied then it should set c.user: The id of the user c.userobj: The actual user object (this may be removed as a requirement in a later release so that access to the model is not required)

login()

called at login.

logout()

called at logout.

abort(status_code, detail, headers, comment)

called on abort. This allows aborts due to authorization issues to be overriden