Package: ckanext-iiif
ckanext-iiifIIIF for CKANOverviewThis extension enables IIIF functionality for CKAN by implementing the Presentation API.
Currently, this includes a single manifest builder for records, but through theIIIIFinterface you can extend the builders to include other IIIF resources.InstallationPath variables used below:$INSTALL_FOLDER(i.e. where CKAN is installed), e.g./usr/lib/ckan/default$CONFIG_FILE, e.g./etc/ckan/default/development.iniInstalling from PyPIpipinstallckanext-iiifInstalling from sourceClone the repository into thesrcfolder:cd$INSTALL_FOLDER/src
gitclonehttps://github.com/NaturalHistoryMuseum/ckanext-iiif.gitActivate the virtual env:.$INSTALL_FOLDER/bin/activateInstall via pip:pipinstall$INSTALL_FOLDER/src/ckanext-iiifInstalling in editable modeInstalling from apyproject.tomlin editable mode (i.e.pip install -e) requiressetuptools>=64; however, CKAN 2.9 requiressetuptools==44.1.0. Seeour CKAN forkfor a version of v2.9 that uses an updated setuptools if this functionality is something you need.Post-install setupAdd 'iiif' to the list of plugins in your$CONFIG_FILE:ckan.plugins=... iiifConfigurationThere are no configuration options for this extension.UsageThis extension's main function is provide a standard endpoint and action to create IIIF
resources.
These IIIF resources could be based on whatever you like - a record, a resource, a whole
dataset etc.Presentation API IIIF resources can be accessed via either the/iiif/<identifier>endpoint or thebuild_iiif_resourceaction where the identifier is passed in the data
dict in the key"identifier".
When this occurs the identifier is matched against any of the registered IIIF resource
builders and if a match is found, the resource is returned.
Identifiers can be built if the builder ID is known along with the necessary parameters
by using thebuild_iiif_identifieraction.Record Manifest BuilderBy default, the only IIIF resource this extension can build is record manifests.
This requires therecord_showaction to be available from theckanext-nhmextension
(there is
anopen issueto move
this action to a different extension, most likelyckanext-versioned-datastore)
.To build a record manifest you must provide the appropriate identifier, which must be of
the formatresource/<resource_id>/record/<record_id>, for example:resource/afea211d-1b3d-49ad-9d15-17f0de368967/record/429.
This example identifies the record with ID429from the resource with IDafea211d-1b3d-49ad-9d15-17f0de368967.
If the record and the resource can be found, and images can be found on the record, then
a manifest is returned.
If any of these conditions fail, the action returnsNoneand the endpoint returns 404.The images are detected in the record by looking for the_image_fieldextra on the
resource.
This should define the field name in the record where images can be found.
The value associated with this image field in the record can be:a string (should be a URL)a list of strings (each element should be a URL)a string containing several URLs separated by a delimiter (this should be defined on
the resource using the_image_delimiterextra)a list of dicts (the URL is extracted by looking for anidentifierfield within
each dict)To fill out the values in the manifest, the builder pulls out fields as specified by
more resource level extras or by falling back to a default value.
These are:"label"- attempts to use_title_fieldextra but falls back to record ID"rights"- attempts to use_image_licenceextra but falls back
tocc-byThe"metadata"field in the manifest is populated using the fields and values in the
record data itself.Adding a Custom BuilderTo add a custom builder all you have to do is implement theIIIIFinterface in your
extension plugin.
For example:importckan.pluginsaspluginsfromtypingimportOptional,CallablefromtypingimportOrderedDictfromckanext.iiif.builders.abcimportIIIFResourceBuilderfromckanext.iiif.interfacesimportIIIIFclassMyBuilder(IIIFResourceBuilder):defmatch_and_build(self,identifier:str)->Optional[dict]:...defbuild_identifier(self,*args,**kwargs)->str:...classMyExtension(plugins.SingletonPlugin):plugins.implements(IIIIF)defregister_iiif_builders(self,builders:OrderedDict[str,IIIFResourceBuilder]):builders["my_builder"]:MyBuilder()When a request is made to build a IIIF resource, each of the registered builders is
called in turn with the identifier.
This means that the builders need to both match the identifier to confirm it matches its
pattern or meets its criteria, and generate the manifest.The builders should:ReturnNoneif the identifier doesn't match the builders requirements. When this
happens, the logic continues and tries the next registered builder function.Raise ackanext.iiif.builders.utils.IIIFBuildErrorif the identifier matched but the
manifest couldn't be generated for any reason. This will stop the logic from checking
any other builders for matches and returnNoneto the caller.Raise any other type ofExceptionif an unexpected error occurred during matching or
processing. This will be propagated to the caller.TestingThere is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in thedocker/folder.To run the tests against ckan 2.9.x on Python3:Build the required images:docker-composebuildThen run the tests.
The root of the repository is mounted into the ckan container as a volume by the Docker compose
configuration, so you should only need to rebuild the ckan image if you change the extension's
dependencies.docker-composerunckan