Publishing protected data to a personal Dataverse (FUTURE)¶
Public datasets are NOT published here. This catalog never re-hosts open data — a public dataset is only ever linked to its origin (the Zenodo / data-Dataverse / vendor archive that published it), and
get()fetches it from there. Publishing is a future capability reserved for protected data — theprivateandanonymizedtiers — on a personal Dataverse, used as a token-gated fallback for data whose origin cannot be linked (no automatable source) or whose origin has rotted. The orchestration and CLI below exist (covered by unit tests with a mocked client) but the live end-to-end path is not exercised yet; rehearse on the sandbox first when it is enabled.
This is the end-to-end walkthrough for putting protected datasets on a personal Dataverse
(Recherche Data Gouv / CIRAD) with nirs4all-datasets, and for reading them back with a token. The
production steps are identical to the sandbox; only the instance + collection differ.
Sandbox (rehearse here) |
Production |
|
|---|---|---|
Instance |
|
|
Use for |
testing the full flow, throw-away datasets |
the real, citable datasets |
The CLI does the upload for you (create dataset → upload files tabIngest=false → publish → mint DOI).
You never touch the web upload form.
0. One-time: get a token and point the tools at the sandbox¶
Create an account on the sandbox, then copy your API token from your account page (it is per-user — it authenticates “as you”, so treat it like a password).
Make it available to the CLI (resolution order: explicit arg → env →
~/.config/nirs4all-datasets/config.toml→ project.env):
export NIRS4ALL_DATAVERSE_INSTANCE="https://demo.recherche.data.gouv.fr"
export NIRS4ALL_DATAVERSE_TOKEN="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
# (or: ~/.config/nirs4all-datasets/config.toml with [dataverse] instance=... token=... ; chmod 600)
Have a collection alias to publish into (create one in the sandbox UI, or ask for one). The alias is the short name in the collection’s URL, e.g.
nirs4all.
You can also pass --instance https://demo.recherche.data.gouv.fr on each command instead of the env var.
The token travels only in the X-Dataverse-key header, is never logged, and is never sent on a redirect
to signed object storage.
1. Pick a protected dataset and set its tier¶
The descriptor (catalog/datasets/<id>.yaml) decides access via its tier. Publishing here is for the
protected tiers only:
tier: private # public | private | anonymized
governance:
license: LicenseRef-not-cleared # protected data need not carry an open license
owner_steward: "..."
redistribution_rights: "Private use only; redistribution not cleared."
consent_ethics_status: "..."
anonymization_status: "..."
private→ everything is shown in the catalog/site, but files are uploaded access-restricted; only Dataverse accounts you grant access to can download them (with their own token). Metadata stays visible.anonymized→ likeprivate, plus the served data masks variable names and z-scores numeric targets (so you can publish metrics without revealing real values/identities).publicis not published here — leave it linked to its origin. The governance gate (publication_blockers()) only checks thepublictier, so a public descriptor must carry an open license + open origins; aprivate/anonymizeddescriptor is publishable to your personal Dataverse without those open-data requirements.
2. Validate before any network call¶
python catalog/scripts/validate.py --check-publish # schema + publishability of public-tier datasets
3. First publication¶
n4a-datasets publish <id> --collection nirs4all --contact-email you@cirad.fr
This creates the dataset, uploads datasets/<id>/canonical/ (+ raw/) with tabIngest=false (so
bytes stay pristine and SHA-256-verifiable), restricts the files because tier != public, publishes the
version, and mints a DOI. On success it automatically:
writes the DOI + version back into
catalog/datasets/<id>.yaml(dataverse.doi,dataverse.dataset_version),records the Dataverse file ids + native checksums in
datasets/<id>/manifest.json(this is what makes token-gated download work), andrebuilds the card / Croissant / catalog.
Commit those updated files afterwards (catalog/datasets/<id>.yaml,
datasets/<id>/{card.json,card.md,croissant.json,manifest.json}).
4. Verify on the sandbox¶
Open the dataset’s DOI landing page in the sandbox UI. Check the files, the metadata, and that the files show as restricted.
5. Read it back (this is the payoff)¶
import nirs4all_datasets as n4ad
ds = n4ad.get("<id>", token="...") # private/anonymized: Dataverse access API with a permitted token
# the token is also auto-resolved from settings if you omit it for a non-public dataset
or from the shell: n4a-datasets get <id> [--token ...]. If the canonical data is still present locally,
get uses it directly (no download). Downloading only succeeds if the token belongs to an account you
granted access to (next section); without access, Dataverse refuses the restricted files.
A
publicdataset never reaches this path —get("<public-id>")fetches its bytes from the origin DOI/URL through the native acquisition core, with no token and no personal Dataverse.
6. Manage access (protected datasets)¶
n4a-datasets grant <id> --to @collaborator --role fileDownloader # let a user download
n4a-datasets grant <id> --to "&my-group" # or a Dataverse group
n4a-datasets revoke <id> --to @collaborator # remove access
n4a-datasets restrict <id> # make all files restricted (then republishes a minor version)
n4a-datasets restrict <id> --off # make them downloadable again
Roles and restriction can be changed at any time after publication.
7. Update the data (new version)¶
Re-build the changed dataset (so datasets/<id>/canonical reflects the new bytes), then run the same
publish command — it auto-detects the existing DOI and publishes a new version (the DOI stays
stable; the version increments). The manifest’s checksums + dataset_version are refreshed so get
keeps verifying the right bytes.
n4a-datasets build-all --source-tree <src> --only <id> --force # refresh canonical from source
n4a-datasets publish <id> # -> new version, same DOI
8. Clean up a botched sandbox attempt¶
If a publish failed mid-way and left a draft, delete the draft from the sandbox UI (or via the API) and retry. Sandbox datasets are disposable.
Going to production¶
Repeat with the production instance + a real collection:
export NIRS4ALL_DATAVERSE_INSTANCE="https://entrepot.recherche.data.gouv.fr"
n4a-datasets publish <id> --collection <prod-alias> --contact-email you@cirad.fr
Then commit the descriptor/card/manifest changes and push — the catalog site shows the DOI + version.
Notes & current limits¶
This is a future path: the Dataverse write methods (publish/update/grant/restrict) are covered by unit tests with a mocked client; the sandbox run is the first real end-to-end test — do it before production once the personal Dataverse is enabled.
Only protected (
private/anonymized) datasets are published here. Public data is linked to its origin and never re-hosted.One collection can hold several restricted datasets (access is per dataset/file).
A token authenticates a user; “private” = restricted files + access granted to specific accounts.