Metadata-Version: 2.4
Name: zenodo-mock
Version: 0.1.1
Summary: A local, credential-free stand-in for the Zenodo deposit/records API, for offline publish round-trips and tests.
Author-email: Irish Centre for High End Computing <james.grogan@ichec.ie>
License: AGPL-3.0-or-later
Project-URL: Repository, https://git.ichec.ie/platform-engineering/modules/pipelines/zenodo-mock
Project-URL: Homepage, https://git.ichec.ie/platform-engineering/modules/pipelines/zenodo-mock
Keywords: Zenodo,mock,testing,deposit API,publish
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Testing :: Mocking
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# zenodo-mock

A local, credential-free stand-in for the [Zenodo](https://zenodo.org) API, so a
full publish round-trip can run on a dev VM or in CI **without a Zenodo token**.

Stdlib only — no runtime dependencies.

## Install

```sh
pip install zenodo-mock
```

## Run

```sh
zenodo-mock --port 8766
# Deposit API:  http://127.0.0.1:8766/api/deposit/depositions
```

(Or `python -m zenodo_mock --port 8766`.)

The deposit API always runs. Pass `--source-outputs <dir>` to also serve a fixed
pre-staged read record (the fetch/consume demo); omit it to run deposit-only,
which is all a bare VM needs. Uploaded deposit files land under `--storage-dir`.

## Publish round-trip (no token)

Point any Zenodo publisher at the mock. For example, `marinerg-data`:

```sh
marinerg-data publish <bundle> --zenodo-url http://127.0.0.1:8766/api --skip-ckan
# → mints a DOI (10.5072/zenodo.<id>), uploads files, and the record becomes
#   resolvable at /api/records/<id>. --new-version works too.
```

The DOI is **pre-reserved on the draft** and returned in
`metadata.prereserve_doi`, as Zenodo's deposit API does — so a publisher can
record the identifier before it takes the step it cannot undo.

## Use it from a test

```python
from zenodo_mock.testing import spawn

def test_publish_round_trip(tmp_path):
    with spawn(tmp_path / "deposits") as base_url:
        publish_against(f"{base_url}/api")
```

`spawn` runs the mock in a subprocess on a kernel-chosen port, waits for it to
be serving, and tears it down — so concurrent suites cannot collide, and no
caller has to reimplement the readiness wait. Add `zenodo-mock` to your dev
dependency group.

## What it implements

The subset of the Zenodo deposit API a publisher drives: create deposition,
bucket upload, delete file, set metadata, publish (mints a DOI and registers a
resolvable record), and new-version. State is in-memory. **Not a faithful
Zenodo** — just enough for the round-trip.

## Provenance

Extracted from `marinerg-i/data-access-service` (`infra/zenodo_mock/`) when that
repo was archived, so the mock could be reused independently of the catalogue.

`tests/test_server.py` covers the deposit store, `tests/test_http.py` the HTTP
layer over it, and `tests/test_spawn.py` the subprocess helper. The mock is
also driven by the suites of `marinerg-data` and `ckanext-marinerg`, which is
what proves their encodings of the Zenodo API and this one agree.

## Licence

AGPL-3.0-or-later. See `LICENSE`.
