This post refers to the ezid_api repository.
The previous tutorial showed how to wire a canonical DOI to multiple versions; start there if you need versioning rather than parts: single DOI basics and hierarchical versioned DOIs. This follow-up creates a container DOI for a data release and two product DOIs that declare they belong to that release. The pattern mirrors a collection landing page (container) that links to specific datasets (products) using DataCite’s HasPart and IsPartOf relations.
What the container/product pattern does
The new create_container_doi.py script mints three identifiers under the EZID test shoulder doi:10.5072/FK2:
- Release container (
SIMONSOBS-RELEASE-2025) – represents the 2025 Simons Observatory release and lists each product DOI withHasPart. - Product 1 (
SIMONSOBS-RELEASE-2025-P1) – a sample data product that points back to the container DOI withIsPartOf. - Product 2 (
SIMONSOBS-RELEASE-2025-P2) – another product that also usesIsPartOfto reference the same container DOI.
Because we stay on the EZID test shoulder, you can try the flow without touching production identifiers.
Running the scripts
From the ezid_api repository root:
# Mint the release DOI plus two product DOIs
uv run python create_container_doi.py
# Inspect the three identifiers and highlight relation fields
uv run python check_container_doi.pyBoth scripts reuse the .env credentials described in the earlier posts (EZID_USERNAME and EZID_PASSWORD). The creation step prints each EZID response along with the resolver URLs (https://doi.org/10.5072/FK2/...).
Relationship fields you should see
check_container_doi.py prints the ANVL metadata returned by EZID and highlights the relationship fields. A shortened sample looks like:
_target: https://example.org/data-releases/simonsobs-2025
datacite.relatedidentifier.1: 10.5072/FK2/SIMONSOBS-RELEASE-2025-P1
datacite.relatedidentifiertype.1: DOI
datacite.relationtype.1: HasPart
datacite.relatedidentifier.2: 10.5072/FK2/SIMONSOBS-RELEASE-2025-P2
datacite.relatedidentifiertype.2: DOI
datacite.relationtype.2: HasPart
_target: https://example.org/data-releases/simonsobs-2025/product-1
datacite.relatedidentifier.1: 10.5072/FK2/SIMONSOBS-RELEASE-2025
datacite.relatedidentifiertype.1: DOI
datacite.relationtype.1: IsPartOf
The container DOI lists both products with HasPart, while each product DOI declares IsPartOf to connect back to the release landing page. Swap in your own URLs, creators, and titles before running against a production shoulder.