Catalog administration¶
Generated from the docstrings. Catalog administration
walks through rollback, embargo, the catalog's description and prune with
examples.
The description's JSON form, description_to_json and
description_from_json, is in statcatlib.bundle.
CatalogAdmin ¶
Operational changes to a catalog's Inventory: rollback, release, cancel, embargo, description and prune.
Open one with open. Every method but editions, products,
embargo and prune writes one Inventory version and returns its
number; prune writes at most one and returns a PruneReport.
Refuse construction from outside, with a TypeError naming open.
embargo
property
¶
The newest Inventory version's embargo setting; False before the first version.
open
classmethod
¶
Open the catalog at path for operational changes.
It reads catalog.json and writes nothing until a method is called.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
The catalog directory. |
required |
Returns:
| Type | Description |
|---|---|
Self
|
The operational object. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
path is not a catalog. |
A legacy layout or other files at path raise IncompatibleCatalogError.
products ¶
Every product the newest Inventory version records, in any state, sorted.
editions ¶
The product's editions in every state, as the newest Inventory version records them.
Retired editions are left out: the Inventory keeps only their tombstones.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product. |
required |
Returns:
| Type | Description |
|---|---|
list[EditionEntry]
|
The editions in id order, which is the order they were started |
list[EditionEntry]
|
in; empty for a product the Inventory does not record. |
rollback ¶
rollback(
product_id: str,
*,
to: str | None = None,
if_live: str | None = None,
reason: str,
) -> int
Withdraw the product's live edition and make a superseded one live again.
The rollback is conditional: it is refused when the live edition is
no longer if_live when the version is written, such as after a
competing release. A working copy built on the withdrawn edition then
fails its seal with NonFastForwardError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product. |
required |
to
|
str | None
|
The superseded edition to make live; the most recent
superseded one when |
None
|
if_live
|
str | None
|
The edition expected live; the live edition when the call
starts when |
None
|
reason
|
str
|
Why, recorded as the version's |
required |
Returns:
| Type | Description |
|---|---|
int
|
The Inventory version written ( |
Raises:
| Type | Description |
|---|---|
InventoryRuleError
|
The product is not recorded
( |
An edition made live that breaks a cross-product rule raises
CrossProductRuleError and writes nothing: a data edition cut from a
structure edition that is neither live nor embargoed
(rule="full-artefacts"), or a structure edition holding a full
artefact another structure product holds live
(rule="structure-home").
An empty reason raises ValueError. It acts on the live edition at
this sdmxlib's store schema; rolling back another schema's live
edition arrives in Phase 4.
release ¶
Make an embargoed edition live now, superseding the live edition it was built on.
The release time is this machine's clock (design decision P1).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product. |
required |
edition_id
|
str
|
The embargoed edition. |
required |
reason
|
str
|
Why, recorded as the version's |
required |
Returns:
| Type | Description |
|---|---|
int
|
The Inventory version written ( |
A release that breaks a cross-product rule raises
CrossProductRuleError and writes nothing: a data edition whose
partial or full artefact matches only an embargoed structure edition
(rule="publish-order"; release that one first); a stale data
edition, or one whose full artefact with no structure home differs
from another data product's live copy (rule="full-artefacts"); a
structure edition holding a full artefact another structure product
holds live (rule="structure-home").
An edition built on an edition that is no longer live raises
NonFastForwardError, whose message names both and the fix. An edition
that is not recorded (rule="unknown") or not embargoed
(rule="state") raises InventoryRuleError, so a withdrawn edition
is never released. An empty reason raises ValueError.
cancel ¶
Withdraw an embargoed edition before its release.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
product_id
|
str
|
The product. |
required |
edition_id
|
str
|
The embargoed edition. |
required |
reason
|
str
|
Why, recorded as the version's |
required |
Returns:
| Type | Description |
|---|---|
int
|
The Inventory version written ( |
An edition that is not recorded (rule="unknown") or not embargoed
(rule="state") raises InventoryRuleError, and an empty reason
raises ValueError.
set_embargo ¶
Turn the catalog's embargo on or off.
With embargo on, a seal records its edition embargoed, and only
release makes it live. A seal that computed its record with embargo
off and lost the race to this version re-reads the head, and records
its edition embargoed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
on
|
bool
|
The new setting, keyword-only: |
required |
reason
|
str
|
Why, recorded as the version's |
required |
Returns:
| Type | Description |
|---|---|
int
|
The Inventory version written ( |
Setting the embargo it already has raises ValueError naming the
current state and writes no version; the check runs against the head
the version would land on, and the embargo is off before the first
version. An empty reason raises ValueError too.
describe ¶
Record the catalog's description in the Inventory root's extensions.statcat.
The section becomes {"format_version": "3", "description": ...},
with the catalog-level fields statcatlib.bundle.description_to_json
writes; any other key a later statcatlib put there is kept. Every
later version carries the description unchanged, and
Catalog.description reads it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
description
|
CatalogDescription
|
The description. |
required |
reason
|
str
|
Why, recorded as the version's |
required |
Returns:
| Type | Description |
|---|---|
int
|
The Inventory version written ( |
An empty reason raises ValueError.
prune ¶
Retire old editions and delete the files no edition needs (design decision P7).
It takes one window, older_than, and runs three steps:
- It retires the
supersededandwithdrawneditions whosestate_changed_atis older than the window, in one Inventory version (event.kindretire), re-applied to the new head after a lost race. - It deletes the directory of each edition tombstoned for longer than the window.
- It deletes a file under a product's
data/when nomanifest.jsonon disk under the product lists it and its mtime is older than the window.
A product with a working copy or a seal journal entry is skipped in
all three steps and reported in PruneReport.skipped_products, and
so is one with an edition whose manifest cannot be read. Prune
deletes no Inventory root or leaf, never expires a tombstone, and
never deletes an edition the Inventory does not tombstone, so a
live, embargoed or unrecorded edition stays. It never retires a
structure edition that a live or embargoed data edition's
partial_of cites (specification ยง11.4); when a manifest that
decision needs cannot be read, it retires no structure edition. An
edition retired in
step 1 keeps its directory until a run after its tombstone has aged
past the window.
With dry_run=True, the default, it retires and deletes nothing
and reports what a real run would do. A real run logs every deleted
path at INFO. A deletion that fails is recorded in
PruneReport.failed, logged at WARNING, and the run continues; the
path is tried again on the next run.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
older_than
|
timedelta
|
The window, a positive |
required |
reason
|
str
|
Why, recorded as the |
required |
dry_run
|
bool
|
Report only, the default; |
True
|
Returns:
| Type | Description |
|---|---|
PruneReport
|
The report. |
Raises:
| Type | Description |
|---|---|
ValueError
|
older_than is not positive, or reason is blank. |
A retirement sdmxlib's rule refuses raises InventoryRuleError, and
InventoryContentionError follows MAX_RACES lost races; neither
deletes anything.
EditionEntry ¶
One edition as the newest Inventory version records it, in any state.
Attributes:
| Name | Type | Description |
|---|---|---|
edition_id |
str
|
The edition's id, a UUIDv7. |
product_id |
str
|
Its product. |
previous |
str | None
|
The edition it was built on, or |
state |
State
|
|
manifest_sha256 |
str
|
The SHA-256 of its |
schema_version |
str
|
The sdmxlib store schema it was written at. |
state_changed_at |
datetime
|
When it entered state. |
release_at |
datetime | None
|
For an embargoed edition, when it may be released. |
PruneReport ¶
What CatalogAdmin.prune retired and deleted, or would have in a dry run.
Every path is /-separated, from the catalog directory.
Attributes:
| Name | Type | Description |
|---|---|---|
retired |
tuple[str, ...]
|
Each edition retired, as |
deleted_dirs |
tuple[str, ...]
|
Each tombstoned edition's directory deleted, as
|
deleted_files |
tuple[str, ...]
|
Each |
skipped_products |
dict[str, str]
|
Each product left untouched, with the reason: a working copy, a seal journal entry, or a manifest that cannot be read. |
failed |
dict[str, str]
|
Each path whose deletion failed, with the error. The next run tries it again. |
root |
Path
|
The catalog directory. |
dry_run |
bool
|
Whether this is a dry run, which retired and deleted nothing. |
seq |
int | None
|
The Inventory version the |