ckanext-iiif
IIIF for CKAN
Overview
This extension enables IIIF functionality for CKAN by implementing the Presentation API.
Currently, this includes a single manifest builder for records, but through the IIIIF
interface you can extend the builders to include other IIIF resources.
Installation
Path 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.ini
Installing from PyPI
pip install ckanext-iiif
Installing from source
-
Clone the repository into the
srcfolder:cd $INSTALL_FOLDER/src git clone https://github.com/NaturalHistoryMuseum/ckanext-iiif.git
-
Activate the virtual env:
. $INSTALL_FOLDER/bin/activate
-
Install via pip:
pip install $INSTALL_FOLDER/src/ckanext-iiif
Installing in editable mode
Installing from a pyproject.toml in editable mode (i.e. pip install -e) requires setuptools>=64; however, CKAN 2.9 requires setuptools==44.1.0. See our CKAN fork for a version of v2.9 that uses an updated setuptools if this functionality is something you need.
Post-install setup
- Add 'iiif' to the list of plugins in your
$CONFIG_FILE:ckan.plugins = ... iiif
Configuration
There are no configuration options for this extension.
Usage
This 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 the build_iiif_resource action 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 the build_iiif_identifier action.
Record Manifest Builder
By default, the only IIIF resource this extension can build is record manifests.
This requires the record_show action to be available from the ckanext-nhm extension
(there is
an open issue to move
this action to a different extension, most likely
ckanext-versioned-datastore)
.
To build a record manifest you must provide the appropriate identifier, which must be of
the format resource/<resource_id>/record/<record_id>, for example:
resource/afea211d-1b3d-49ad-9d15-17f0de368967/record/429.
This example identifies the record with ID 429 from the resource with ID
afea211d-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 returns None and the endpoint returns 404.
The images are detected in the record by looking for the _image_field extra 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 an
identifierfield 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 to cc-by
The "metadata" field in the manifest is populated using the fields and values in the
record data itself.
Adding a Custom Builder
To add a custom builder all you have to do is implement the IIIIF interface in your
extension plugin.
For example:
import ckan.plugins as plugins
from typing import Optional, Callable
from typing import OrderedDict
from ckanext.iiif.builders.abc import IIIFResourceBuilder
from ckanext.iiif.interfaces import IIIIF
class MyBuilder(IIIFResourceBuilder):
def match_and_build(self, identifier: str) -> Optional[dict]: ...
def build_identifier(self, *args, **kwargs) -> str: ...
class MyExtension(plugins.SingletonPlugin):
plugins.implements(IIIIF)
def register_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:
- Return
Noneif the identifier doesn't match the builders requirements. When this happens, the logic continues and tries the next registered builder function. - Raise a
ckanext.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 of
Exceptionif an unexpected error occurred during matching or processing. This will be propagated to the caller.
Testing
There is a Docker compose configuration available in this repository to make it easier to run tests. The ckan image uses the Dockerfile in the docker/ folder.
To run the tests against ckan 2.9.x on Python3:
-
Build the required images:
docker compose build
-
Then 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 compose run ckan
Metadata
Release files for ckanext-iiif 4.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| ckanext_iiif-4.0.2.tar.gz | 32.5 kB | Without provenance | Details for ckanext_iiif-4.0.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| ckanext_iiif-4.0.2-py3-none-any.whl | Python 3 | none | any | Details for ckanext_iiif-4.0.2-py3-none-any.whl |
Total release size: 68.2 kB
Release files / ckanext_iiif-4.0.2.tar.gz
| Download URL | ckanext_iiif-4.0.2.tar.gz |
|---|---|
| Size | 32.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
deeb2635706ce31af9d52e9dc424903f1c9eaa7c48b0eb31018292f7d07cb211
|
|
BLAKE2b-256 checksum How to use checksums |
214b72115fcc4ef32d5d3a965912a6543cbd5a08fbf11bd8e6a826a389992c35
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / ckanext_iiif-4.0.2-py3-none-any.whl
| Download URL | ckanext_iiif-4.0.2-py3-none-any.whl |
|---|---|
| Size | 35.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0cc5b6616d7616e12b54ea523e5b3a0fd1d6137d2fa21c83d1f47e2acdd78bfc
|
|
BLAKE2b-256 checksum How to use checksums |
45fbfb9abaafce5e112c41493a89d808af3620294d8d49f84397ea8935d5d32f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for ckanext-iiif 4.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.