Tutorial: create your first record

In this tutorial you will create a minimal InvenioRDM draft, inspect the generated response, and publish it as a record.

The goal is to experience the complete client workflow. For task-oriented variations, use the how-to guides.

Prerequisites

You need:

  • Python 3.10 or newer;
  • access to an InvenioRDM instance;
  • an API token created in that instance;
  • permission to create records.

The official InvenioRDM documentation describes Bearer tokens as the supported authentication mechanism for REST API calls.

1. Create a project

mkdir invenio-record-example
cd invenio-record-example
python -m venv .venv
source .venv/bin/activate
pip install invenio-rest-api-client

2. Configure the connection

Keep credentials outside the Python source:

export INVENIO_BASE_URL="https://invenio.example.org"
export INVENIO_TOKEN="replace-with-your-token"

Create create_record.py:

import os

from invenio_rest_api_client import AuthenticatedClient

client = AuthenticatedClient(
    base_url=os.environ["INVENIO_BASE_URL"],
    token=os.environ["INVENIO_TOKEN"],
    raise_on_unexpected_status=True,
)

raise_on_unexpected_status=True turns undocumented HTTP statuses into UnexpectedStatus exceptions instead of silently returning None.

3. Describe the record

Add the imports and request model:

from datetime import date

from invenio_rest_api_client.models import (
    Access,
    AccessFiles,
    AccessRecord,
    CreateADraftRecordBody,
    Creator,
    Files,
    Metadata,
    PersonOrOrg,
    PersonOrOrgType,
    ResourceType,
    ResourceTypeId,
)

body = CreateADraftRecordBody(
    access=Access(
        record=AccessRecord.PUBLIC,
        files=AccessFiles.PUBLIC,
    ),
    files=Files(enabled=False),
    metadata=Metadata(
        resource_type=ResourceType(id=ResourceTypeId.DATASET),
        title="Climate observations",
        publication_date=date.today(),
        creators=[
            Creator(
                person_or_org=PersonOrOrg(
                    type=PersonOrOrgType.PERSONAL,
                    given_name="Ada",
                    family_name="Lovelace",
                )
            )
        ],
        publisher="Example Repository",
    ),
)

The schema makes the minimum metadata visible in Python: resource type, title, publication date, at least one creator, and publisher.

4. Create, publish, and retrieve the record

Add:

from http import HTTPStatus

from invenio_rest_api_client.api.drafts import publish_a_draft_record
from invenio_rest_api_client.api.records import (
    create_a_draft_record,
    get_a_record_by_id,
)

with client:
    response = create_a_draft_record.sync_detailed(
        client=client,
        body=body,
    )

    if response.status_code is not HTTPStatus.CREATED:
        raise RuntimeError(
            f"Could not create draft ({response.status_code}): "
            f"{response.content.decode(errors='replace')}"
        )

    draft = response.parsed
    if draft is None or draft.id is None:
        raise RuntimeError("The create response did not contain a draft ID")

    print(f"Created draft {draft.id}")

    published = publish_a_draft_record.sync(
        draft.id,
        client=client,
    )
    if published is None or published.id is None:
        raise RuntimeError("The publish response did not contain a record ID")

    print(f"Published record {published.id}")

    record = get_a_record_by_id.sync(
        published.id,
        client=client,
    )
    if record is None:
        raise RuntimeError("The published record could not be retrieved")

    print(record["metadata"]["title"])

The sync_detailed function is useful here because it preserves the status, headers, raw body, and parsed model in one Response object.

5. Run the workflow

Run the script:

python create_record.py

You should see the draft identifier followed by the published record identifier.

The last line should be:

Climate observations

What you learned

You have:

  • configured an authenticated client;
  • built a validated record request with Pydantic models;
  • used a detailed response for explicit HTTP handling;
  • created a draft and published it;
  • retrieved the resulting record.

Next, learn how to search records or read the Record API reference.