flowchart TB
user("User<br>[person]"):::user
metadata[/"Metadata file<br>['.zenodo.toml']"/]
metadata_formats("Metadata formats<br>[e.g. 'cff', 'json',<br>'toml', 'yml']")
deposit("Deposit<br>[Zenodo server]"):::external
record("Record<br>[Zenodo server]"):::external
file[/"File<br>[e.g. PDF]"/]
token[/"Token<br>[authentication]"/]
zen_do["zen-do<br>[CLI]"]
user -->|edit| metadata
user -->|provide| token
metadata -->|read| zen_do
metadata <-.->|convert| metadata_formats
token --> zen_do
zen_do -->|convert| metadata_formats
file -->|add| zen_do
user --> file
zen_do -->|publish<br>update<br>discard<br>list<br>get| deposit
deposit -.->|publish| record
%% Styling
classDef user fill:#FFFFFF,color:#000000;
classDef external fill:#F5F5F5;
Architecture
This document contains the architectural design for zen-do. For design details of the Seedcase Project as a whole, see the Seedcase Design documentation.
The purpose of this description is to ensure that the team shares a common understanding about the implementation and to outline the design to anyone else interested in the internal workings of the package.
Actions and objects
This section describes the different actions and objects used throughout the package.
| Object | Description |
|---|---|
| deposit(s) | A Zenodo deposit is the combined set of files and metadata that make up the content that will eventually form the published record. |
| record(s) | A Zenodo record is a given published set of metadata and files for a specific DOI. |
| metadata | The metadata for a deposit, kept within a file .zenodo.toml. |
| file(s) | The files to add to a deposit. |
| format | The file formats for the Zenodo metadata file(s) to convert between. |
| token | The Zenodo personal access token to authenticate with the Zenodo API. |
| Action | Description |
|---|---|
| init | Create an empty metadata file to be filled in. |
| list | List all Zenodo deposits in an account. |
| get | Get a Zenodo deposit in an account from a metadata file. |
| convert | Convert metadata files to and from different formats. |
| update | Updates an existing Zenodo deposit’s metadata only (not file) based on the contents of a metadata file. |
| publish | Publish a new Zenodo record from an existing or new Zenodo deposit based on the metadata file and, if given, updating the file(s) in the deposit. |
| discard | Discard a draft of or update to a Zenodo deposit (but not record). |
Metadata file
The only allowable metadata file format that zen-do uses is TOML, which is a simple, human-readable format that is easy to write and read. Why TOML rather than Zenodo’s suggested JSON format? JSON is not a friendly format for humans to write and read, it doesn’t allow comments, and doesn’t support multi-line strings, which can be useful for writing long descriptions. TOML is the opposite, as it allows comments, multi-line strings, and is more human-friendly.
The file is named .zenodo.toml and contains all the metadata for a Zenodo deposit. The file can be converted to and from other formats, such as .zenodo.json, _quarto.yml, pyproject.toml, and CITATION.cff (filling in the relevant fields where relevant in those other formats).
We use the design pattern of “one .zenodo.toml file for one Zenodo deposit”. So this file must be given (or present in the working directory) for many of the actions to work. There must also be a unique “related identifier” for this (new or existing) deposit added to this .zenodo.toml file in order to identify it within the list of deposits of a user’s account. This is described in more detail in the interface documentation.
C4 Models
This section contains diagrams for zen-do that are inspired by the C4 Model. The C4 Model is an established visualisation approach to describe the architecture of a software system. It breaks the system down into four levels of architectural abstraction: system context, containers, components, and code. For zen-do, we only use diagrams that are similar to the context and container models.
System context
The system context diagram shows the users and external systems that interact with zen-do. The users provide zen-do with the metadata file, the file or files to add to a Zenodo deposit, and the token for the Zenodo account.
Container/component
In C4, a container diagram zooms in on the system boundary to show the containers within it while a a component diagram is “a grouping of related functionality encapsulated behind a well-defined interface”, like a class or a module. For zen-do, we have a single container (the CLI) so we combine the container and component diagrams into one. The diagram below shows the main actions and objects within zen-do, how they interact with each other at a high level, and the technologies used for each.
flowchart TB
user("User<br>[person]"):::user
subgraph input ["Input"]
metadata[/"Metadata file<br>['.zenodo.toml']"/]
file[/"File<br>[e.g. PDF]"/]
token[/"Token<br>[authentication]"/]
end
subgraph zen-do
init["init<br>[Python]"]
get["get<br>[Python]"]
list["list<br>[Python]"]
convert["convert<br>[Python]"]
update["update<br>[Python]"]
publish["publish<br>[Python]"]
discard["discard<br>[Python]"]
deposit[/"Deposit<br>[Zenodo server]"/]:::external
account[/"Account<br>[Zenodo server]"/]:::external
update & discard & publish -->|request| deposit
get & list -->|request| account
end
subgraph output ["Output"]
record("Record<br>[Zenodo server]"):::external
metadata_formats("Metadata formats<br>[e.g. 'cff', 'json',<br>'toml', 'yml']")
empty_metadata("Empty metadata file<br>['.zenodo.toml']")
deposit_get("Deposit<br>[JSON]")
deposits_list("List of deposits<br>[JSON]")
end
deposit -.->|publish| record
account -->|response| deposit_get
account -->|response| deposits_list
convert --> metadata_formats
init -->|create| empty_metadata
user --> input
token -->|required<br>except init<br>and convert| zen-do
metadata -->|required<br>except init<br>and list| zen-do
file -->|required| publish
%% Styling
style zen-do fill:#FFFFFF,color:#000000;
style output fill:#FFFFFF,color:#000000;
style input fill:#FFFFFF,color:#000000;
classDef user fill:#FFFFFF,color:#000000;
classDef external fill:#F5F5F5;