Metadata-Version: 2.2
Name: ckanext-fair3r-doi
Version: 3.3.19
Summary: A CKAN extension for assigning a digital object identifier (DOI) to datasets, using the DataCite DOI service.
Author-email: Natural History Museum <data@nhm.ac.uk>
License: GPL-3.0-or-later
Project-URL: repository, https://github.com/NaturalHistoryMuseum/ckanext-doi
Project-URL: changelog, https://github.com/NaturalHistoryMuseum/ckanext-doi/blob/main/CHANGELOG.md
Keywords: CKAN,data,doi
Classifier: Development Status :: 5 - Production/Stable
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: jsonschema==3.0.0
Requires-Dist: xmltodict==0.12.0
Requires-Dist: datacite==1.4.0
Requires-Dist: ckantools==0.5.0
Provides-Extra: test
Requires-Dist: mock; extra == "test"
Requires-Dist: pytest==7.4.4; extra == "test"
Requires-Dist: pytest-cov==4.1.0; extra == "test"
Requires-Dist: coveralls; extra == "test"

![CKAN](https://img.shields.io/badge/CKAN-2.12.1-orange)
![Python](https://img.shields.io/badge/python-3.12-blue)
[![PyPI](https://img.shields.io/pypi/v/ckanext-fair3r-doi)](https://pypi.org/project/ckanext-fair3r-doi/)
![License](https://img.shields.io/badge/license-GPL--3.0-blue)

# ckanext-doi

Gives every CKAN dataset a **DOI** (Digital Object Identifier) through
[DataCite](https://datacite.org/), so it can be cited in publications.

The DOI is reserved as soon as the dataset is created, and registered
with DataCite - resolvable at `https://doi.org/<prefix>/<id>` - once the
dataset is **active and public**. A draft or private dataset keeps its
DOI unregistered: you can quote it in a paper under embargo, it starts
resolving the day the dataset is published. Its metadata (title,
creators, dates, size, formats...) is sent again to DataCite whenever it
changes.

> Fork of [NaturalHistoryMuseum/ckanext-doi](https://github.com/NaturalHistoryMuseum/ckanext-doi),
> maintained by [Phen-ICS](https://github.com/Phen-ICS) (CNRS/IGBMC) for
> the [FAIR3R](https://fair3r.fr) catalogue. Published on PyPI as
> **`ckanext-fair3r-doi`**; the plugin is still called `doi`.

## What this fork changes

- **CKAN 2.12** (SQLAlchemy 2.0, Python 3.12), with upstream's Alembic
  migration for its table (`ckan db upgrade -p doi`).
- **Test mode links work**: in test mode, DOI links go to DataCite's test
  resolver (`handle.test.datacite.org`), since test DOIs don't exist on
  doi.org.
- **Cleaner metadata**: ISO 8601 dates, the size in a readable unit (and
  left out rather than "0 kb"), contributors kept apart from creators, and
  the DOI pointing at `ckanext.doi.site_url` when set.
- **Clearer errors**: a public dataset without an author is a form error
  on the author field, not a server error.
- **Only datasets get DOIs**: other package types (harvest sources,
  pages...) are left alone.
- **Organization bulk actions** (make public, private, delete) carry on
  past a dataset that fails.
- **`ckan doi update-doi`** skips private and deleted datasets and carries
  on past errors, instead of stopping at the first one.
- **French translation**, and CI that tests, builds and publishes to PyPI
  on every merge.

## Requirements

- CKAN 2.12.
- A [DataCite](https://datacite.org/) repository account: a **test**
  account (DataCite Fabrica test) for development, a **live** one to
  register real DOIs. Each has its own credentials and prefix.

## Installation

1. Install the package in CKAN's virtualenv:

   ```shell
   pip install ckanext-fair3r-doi
   ```

2. Enable the plugin in `ckan.ini`:

   ```ini
   ckan.plugins = ... doi
   ```

3. Configure your DataCite account (see [Configuration](#configuration)):

   ```ini
   ckanext.doi.account_name = ABC.DEFG
   ckanext.doi.account_password = <password>
   ckanext.doi.prefix = 10.1234
   ckanext.doi.publisher = My Institute
   ckanext.doi.test_mode = true
   ```

4. Create its table:

   ```shell
   ckan -c /path/to/ckan.ini db upgrade -p doi
   ```

5. Restart CKAN. Make a dataset public: the page shows "DataCite DOI
   created" and the DOI appears in its citation.

## Configuration

| Setting | Required | Meaning |
|---|---|---|
| `ckanext.doi.account_name` | yes | DataCite repository account, e.g. `ABC.DEFG` |
| `ckanext.doi.account_password` | yes | Its password |
| `ckanext.doi.prefix` | yes | The account's DOI prefix, e.g. `10.1234` (the test account has its own) |
| `ckanext.doi.publisher` | yes | Institution publishing the DOIs |
| `ckanext.doi.test_mode` | yes | `true`: DataCite's test system (DOIs never resolve on doi.org); `false`: live DOIs |
| `ckanext.doi.site_url` | no | Base URL the DOI points to; defaults to `ckan.site_url` |
| `ckanext.doi.site_title` | no | Site name used in the citation |

### Which fields go to DataCite

DataCite [Metadata Schema 4.5](https://schema.datacite.org/meta/kernel-4.5/)
(4.2 with an older `datacite` library). The required ones:

| DataCite | From |
|---|---|
| `title` | dataset title |
| `creator` | dataset author (one or more) |
| `publisher` | `ckanext.doi.publisher` |
| `publicationYear` | year the dataset was created (`metadata_created`) |
| `resourceType` | dataset type |

Everything else (description, dates, sizes, formats, subjects...) is
mapped in [`lib/metadata.py`](https://github.com/Phen-ICS/ckanext-doi/blob/main/ckanext/doi/lib/metadata.py). Other plugins
can add to or change it through the `IDoi` interface (below) - this is
how [ckanext-fair3r](https://github.com/Phen-ICS/ckanext-fair3r) sends its
FDF metadata (ORCID, ROR, genes, organisms...).

## Commands

| Command | Use |
|---|---|
| `ckan doi update-doi [-p <dataset id> ...]` | Send the current metadata of all (or the given) published DOIs to DataCite again, e.g. after a change in the mapping. Skips private and deleted datasets, and up-to-date ones |
| `ckan doi delete-dois` | Delete every DOI from CKAN's own table - **not** from DataCite (registered DOIs are permanent) |

## Templates

Citation snippets, for your own templates:

```html+jinja
{% snippet "doi/snippets/package_citation.html", pkg_dict=g.pkg_dict %}
{% snippet "doi/snippets/resource_citation.html", pkg_dict=g.pkg_dict, res=res %}
```

## Extending: the `IDoi` interface

A plugin implementing `ckanext.doi.interfaces.IDoi` can change the
metadata before it is sent. Both methods run after this extension's own,
in plugin order.

| Method | Use |
|---|---|
| `build_metadata_dict(pkg_dict, metadata_dict, errors)` | Fill or change `metadata_dict` from the dataset; remove from `errors` the required fields you handled. Returns `(metadata_dict, errors)`. Any required field still in `errors` afterwards stops the DOI with a `DOIMetadataException` |
| `build_xml_dict(metadata_dict, xml_dict)` | Change the dict given to the `datacite` library's schema `tostring()` / `validate()`. Returns `xml_dict` |

## Tests

```shell
docker exec -u ckan -it ckan-app pytest --ckan-ini=/plugins/ckanext-doi/test.ini /plugins/ckanext-doi/ckanext/doi/tests
```

The DataCite API is mocked: no network or account needed. Always pass
`--ckan-ini`: the fixtures empty the database they run against, and refuse
to run unless its name contains `test`.

## Credits and license

Originally written by the [Natural History Museum](https://github.com/NaturalHistoryMuseum/ckanext-doi),
London. Released under the GNU General Public License v3.0 or later - see
[`LICENSE`](https://github.com/Phen-ICS/ckanext-doi/blob/main/LICENSE).
