Table of Contents

Goal

In this tutorial, you will learn how to:

  • Create a new record in Kadi4Mat using the Record class.
  • Safely check whether a record identifier already exists.
  • Handle conflicts when creating records with unique identifiers.

Prerequisites

Before you start, make sure you have:

Specific for this tutorial

  • A desired unique identifier for the new record you want to create.

Function Overview

The Record class can either retrieve an existing record or create a new one, depending on the create parameter.

  • create=False → retrieves an existing record with the given identifier.
  • create=True → creates a new record if no accessible record with the identifier exists.
  • The identifier must be unique; conflicts with existing public or private records may raise exceptions or prevent creation.

See full API reference: kadi-apy.readthedocs-Record

Constructor structure and parameters:

Record_class

A record can be created either by calling the Record(...) constructor directly or via the manager’s record(...) method:

>>>
>>> rec = Record(manager, ...)
>>> 
>>> rec = manager.record(...)
>>>

Both approaches must result in identical initialization semantics.

Final Workflow and Results

The following workflow demonstrates a safe way to create a new record while avoiding identifier conflicts. Detailed reasons and API internals are beyond the scope of this tutorial.

Step 1 – Create with create=True

>>> rec = Record(manager, identifier="my_toy_record", title="My Toy Record", create=True)

If no exception:

Check whether the record was newly created:

>>> print(rec.created)
  • True → A new record was successfully created.

  • False → A record with this identifier already exists (public or owned by the user) → choose a different identifier and repeat Step 1

If an exception is raised:

  • A private, inaccessible record with this identifier exists → choose a different identifier and repeat Step 1

Optional: Helper Function safe_create_record()

For convenience, the safe_create_record() function wraps the logic of safely creating a new record, handling identifier checks and exceptions automatically. This section is optional, but highly recommended for repetitive workflows. The core logic of this wrapper function originates from a contribution by Adrian.

Important note: Always check the return value. If it is None, the record was not created.

Structure of the safe_create_record() function.

from kadi_apy.lib.resources.records import Record
from kadi_apy.lib.exceptions import KadiAPYRequestError, KadiAPYInputError


def safe_create_record(manager, identifier, title=None, **kwargs):
    """
    Safely create a new record in Kadi4Mat.

    Parameters:
        manager (KadiManager): Pre-configured KadiManager object for API requests.
        identifier (str): Desired unique identifier for the new record.
        title (str, optional): Title for the new record.
        **kwargs: Additional metadata to attach to the record.



    Returns:
        Record object if successfully created, otherwise None.
    """

    # Ensure a valid KadiManager instance is provided
    if not isinstance(manager, KadiManager):
        raise TypeError(
            "\nInvalid instance: A valid KadiManager instance must be provided.\n"
        )

    # Validate identifier characters (only letters, numbers, '-', '_', and spaces)
    if not all(c.isalnum() or c in "-_ " for c in identifier):
        raise ValueError(
            f"\nInvalid identifier: '{identifier}'. Only letters, numbers, hyphens, underscores, and spaces are allowed.\n"
        )

    try:

        new_record = Record(manager, identifier=identifier, create=True, **kwargs)

        if new_record.created:          # A new record was created
            return new_record
        else:                           # A record (public or owned by the user) with this identifier already exists
            return None


    except KadiAPYRequestError:
        # A private record with this identifier exists but is not accessible.
        return None


Practical Examples of Record Creation Outcomes

This section demonstrates common scenarios when using safe_create_record().

>>> # An existing public record with identifier "eb2-002"
>>> rec = safe_create_record(manager, identifier="eb2-002")
>>> print(rec)
None
>>>
>>>
>>> # An existing private record (not accessible) with identifier "workflow"
>>> rec = safe_create_record(manager, identifier="workflow")
>>> print(rec)
None
>>>
>>>
>>>
>>> # A non-existing record but with an invalid identifier
>>> rec = safe_create_record(manager, identifier="a_toy@record", title="A Toy Record")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/mnt/c/Users/kadi_apy_script.py", line 116, in safe_create_record
    raise ValueError(
ValueError:
Invalid identifier: 'a_toy@record'. Only letters, numbers, hyphens, underscores, and spaces are allowed.

>>>
>>>
>>>
>>> # A non-existing record with a valid identifier (will be created)
>>> rec = safe_create_record(manager, identifier="A-Toy-Record", title="A Toy Record")
>>> print(rec)
record 'A Toy Record' (id: 1325, identifier: 'a-toy-record')
>>>
>>>
>>>
>>> # Create a new record including a description
>>> text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
>>> rec = safe_create_record(manager = manager, identifier = "a-toy-record-with-description", description = text)
>>> print(rec)
record 'a-toy-record-with-description' (id: 1334, identifier: 'a-toy-record-with-description')
>>>

The same record (id: 1334, identifier: 'a-toy-record-with-description) viewed in the Kadiweb.

a_toy_record_with_description

Installation Guide