Skip to content

Entity Fields

entity_fields

Module for managing entity fields in Kaleidoscope.

This module provides classes and services for working with entity fields, which are the schema definitions for data stored in the Kaleidoscope system. It includes:

  • DataFieldTypeEnum: An enumeration of all supported field types
  • EntityField: Base class for a field definition
  • KeyField: Subclass for key fields, with key-field-only update operations
  • DataField: Subclass for data fields, with data-field-only update operations
  • EntityFieldsService: Service class for retrieving and creating entity fields

Entity fields can be of two types:

  • Key fields: Used to uniquely identify entities
  • Data fields: Used to store additional information about entities

The service provides caching mechanisms to minimize API calls and includes error handling for all network operations.

Classes:

Name Description
DataFieldTypeEnum

An enumeration of all supported field types

FormatEnforcementEnum

How a key field's format/regex is enforced

EntityFieldRoleEnum

Special roles a key field can play

ValueAggregationTypeEnum

Aggregation types for data field display

LookupDisplayOperationScopeEnum

Scope for lookup display operations

EntityField

Base class for entity field definitions

KeyField

Concrete key field with update() for identifier settings

DataField

Concrete data field with update() for display/archival settings

EntityFieldsService

Service for retrieving and creating entity fields

Example
# Get all key fields
key_fields = client.entity_fields.get_key_fields()

# Create or get a data field
field = client.entity_fields.get_or_create_data_field(
    field_name="temperature",
    field_type=DataFieldTypeEnum.NUMBER
)

# Update a key field's regex format
key_field = client.entity_fields.get_or_create_key_field("sample_id")
key_field.update(regex_format=r"^SMP-\d{6}$")

UNSET module-attribute

UNSET: Final[_UnsetType] = _UnsetType()

Sentinel value indicating an update argument was not provided.

Use this to leave a field unchanged when calling KeyField.update() or DataField.update(). Pass None explicitly to clear a nullable field.

DataFieldTypeEnum

Bases: str, Enum

Enumeration of data field types supported by the system.

This enum defines all possible types of data fields that can be used in the application. Each field type represents a specific kind of data structure and validation rules.

Attributes:

Name Type Description
TEXT

Plain text field.

NUMBER

Numeric field for storing numbers.

QUALIFIED_NUMBER

Numeric field with additional qualifiers or units.

SMILES_STRING

Field for storing SMILES (Simplified Molecular Input Line Entry System) notation.

SELECT

Single selection field from predefined options.

MULTISELECT

Multiple selection field from predefined options.

MOLFILE

Field for storing molecular structure files.

RECORD_REFERENCE

Reference to another record by record_id.

MIXTURE

Field for storing mixture compositions.

FILE

Generic file attachment field.

IMAGE

Image file field.

DATE

Date field.

URL

Web URL field.

BOOLEAN

Boolean (true/false) field.

EMAIL

Email address field.

PHONE

Phone number field.

FORMULA

Field for storing formulas or calculated expressions.

PEOPLE

Field for referencing people/users.

VOTES

Field for storing vote counts or voting data.

XY_ARRAY

Field for storing XY coordinate arrays.

DNA_OLIGO

Field for storing DNA oligonucleotide sequences.

RNA_OLIGO

Field for storing RNA oligonucleotide sequences.

PEPTID

Field for storing peptide sequences.

PLASMID

Field for storing plasmid information.

GOOGLE_DRIVE

Field for Google Drive file references.

S3_FILE

Field for AWS S3 file references.

SNOWFLAKE_QUERY

Field for Snowflake database query references.

STATUS

Field for tracking workflow/lifecycle status values.

RXN

Field for storing chemical reaction notation.

PROTEIN_STRUCTURE

Field for storing protein structure data.

FormatEnforcementEnum

Bases: str, Enum

How a key field's serial format / regex pattern is enforced on values.

Attributes:

Name Type Description
SUGGEST

Suggest the format but do not block non-matching values.

ENFORCE_ONLY

Reject values that do not match the format.

GENERATE

Auto-generate the next value from the configured serial format.

EntityFieldRoleEnum

Bases: str, Enum

Special role assigned to a key field.

Attributes:

Name Type Description
REGISTERED_ENTITY

Marks the key field as the workspace's registered-entity identifier.

ValueAggregationTypeEnum

Bases: str, Enum

How aggregated values are summarized for display on data fields.

Attributes:

Name Type Description
LATEST

Most recently recorded value.

LIST

All values, as a list.

EARLIEST

Earliest recorded value.

RANGE

Range (min - max).

MEAN

Arithmetic mean.

MEDIAN

Median.

MINIMUM

Minimum value.

MAXIMUM

Maximum value.

LookupDisplayOperationScopeEnum

Bases: str, Enum

Scope used when displaying a lookup data field's operation values.

Attributes:

Name Type Description
ALL

Include values from all related operations.

CHILD

Include only child operation values.

PARENT

Include only parent operation values.

EntityField

Bases: _KaleidoscopeBaseModel

Base class for fields within an entity in the Kaleidoscope system.

Concrete instances are returned as either KeyField (when is_key is True) or DataField (when is_key is False). Each subclass exposes its own update() method scoped to the properties that are valid for that field role — for example, only KeyField allows updating regex_format and serial-format settings, while only DataField allows updating display aggregation and archival flags.

Attributes:

Name Type Description
id str

The UUID of the field.

created_at datetime

Timestamp when the field was created.

is_key bool

Whether this field is a key field for the entity.

field_name str

The name of the field.

field_description str

Human-readable description of the field. Empty string if unset.

field_examples str

Example values for the field. Empty string if unset.

field_type DataFieldTypeEnum

The data type of the field.

ref_slice_id str | None

Reference to a slice ID for relational fields.

regex_format str | None

Regex pattern used to validate key field values (only meaningful on key fields).

Example
from kalbio.entity_fields import KeyField, DataField

# The service returns the appropriate subclass.
key_field = client.entity_fields.get_or_create_key_field("sample_id")
assert isinstance(key_field, KeyField)

KeyField

Bases: EntityField

A key field — uniquely identifies entities in the workspace.

Key fields support updating identifier-related settings such as regex_format, serial-format configuration, and the field's role.

Example
key_field = client.entity_fields.get_or_create_key_field("sample_id")
key_field.update(
    regex_format=r"^SMP-\d{6}$",
    format_enforcement=FormatEnforcementEnum.ENFORCE_ONLY,
)

Methods:

Name Description
update

Update one or more configurable properties of this key field.

update

update(*, field_name: str | _UnsetType = UNSET, field_description: str | _UnsetType = UNSET, field_examples: str | _UnsetType = UNSET, regex_format: str | None | _UnsetType = UNSET, serial_format_prefix: str | None | _UnsetType = UNSET, serial_format_padding: int | None | _UnsetType = UNSET, format_enforcement: FormatEnforcementEnum | None | _UnsetType = UNSET, show_format_warning: bool | _UnsetType = UNSET, initial_counter_value: int | _UnsetType = UNSET, role: EntityFieldRoleEnum | None | _UnsetType = UNSET) -> 'KeyField' | None

Update one or more configurable properties of this key field.

Only the arguments you pass are sent to the server. To clear a nullable field (e.g. remove an existing regex), pass None explicitly. Omitted arguments default to UNSET and are left unchanged.

Parameters:

Name Type Description Default
field_name str | _UnsetType

New name for the field.

UNSET
field_description str | _UnsetType

Human-readable description of the field (max 500 characters). Pass an empty string to clear.

UNSET
field_examples str | _UnsetType

Example values for the field (max 500 characters). Pass an empty string to clear.

UNSET
regex_format str | None | _UnsetType

Regex pattern to enforce on key values; pass None to clear.

UNSET
serial_format_prefix str | None | _UnsetType

Prefix for auto-generated identifiers; pass None to clear.

UNSET
serial_format_padding int | None | _UnsetType

Zero-padding width for the serial counter; pass None to clear.

UNSET
format_enforcement FormatEnforcementEnum | None | _UnsetType

How the format is enforced; pass None to clear.

UNSET
show_format_warning bool | _UnsetType

Whether to surface a UI warning on format mismatches.

UNSET
initial_counter_value int | _UnsetType

Starting value for the serial counter.

UNSET
role EntityFieldRoleEnum | None | _UnsetType

Special role for this key field; pass None to clear.

UNSET

Returns:

Type Description
'KeyField' | None

The updated KeyField (also reflected on self), or None

'KeyField' | None

if the server returned an unexpected response shape.

Raises:

Type Description
KalbioAPIError

If the API request fails.

Example
# Add a regex pattern and enforce it
key_field.update(
    regex_format=r"^SMP-\d{6}$",
    format_enforcement=FormatEnforcementEnum.ENFORCE_ONLY,
)

# Clear an existing regex
key_field.update(regex_format=None)
Source code in kalbio/entity_fields.py
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
def update(
    self,
    *,
    field_name: Union[str, _UnsetType] = UNSET,
    field_description: Union[str, _UnsetType] = UNSET,
    field_examples: Union[str, _UnsetType] = UNSET,
    regex_format: Union[Optional[str], _UnsetType] = UNSET,
    serial_format_prefix: Union[Optional[str], _UnsetType] = UNSET,
    serial_format_padding: Union[Optional[int], _UnsetType] = UNSET,
    format_enforcement: Union[Optional[FormatEnforcementEnum], _UnsetType] = UNSET,
    show_format_warning: Union[bool, _UnsetType] = UNSET,
    initial_counter_value: Union[int, _UnsetType] = UNSET,
    role: Union[Optional[EntityFieldRoleEnum], _UnsetType] = UNSET,
) -> Optional["KeyField"]:
    """Update one or more configurable properties of this key field.

    Only the arguments you pass are sent to the server. To clear a
    nullable field (e.g. remove an existing regex), pass `None`
    explicitly. Omitted arguments default to `UNSET` and are left
    unchanged.

    Args:
        field_name: New name for the field.
        field_description: Human-readable description of the field
            (max 500 characters). Pass an empty string to clear.
        field_examples: Example values for the field (max 500 characters).
            Pass an empty string to clear.
        regex_format: Regex pattern to enforce on key values; pass None to clear.
        serial_format_prefix: Prefix for auto-generated identifiers; pass None to clear.
        serial_format_padding: Zero-padding width for the serial counter; pass None to clear.
        format_enforcement: How the format is enforced; pass None to clear.
        show_format_warning: Whether to surface a UI warning on format mismatches.
        initial_counter_value: Starting value for the serial counter.
        role: Special role for this key field; pass None to clear.

    Returns:
        The updated `KeyField` (also reflected on `self`), or None
        if the server returned an unexpected response shape.

    Raises:
        KalbioAPIError: If the API request fails.

    Example:
        ```python
        # Add a regex pattern and enforce it
        key_field.update(
            regex_format=r"^SMP-\\d{6}$",
            format_enforcement=FormatEnforcementEnum.ENFORCE_ONLY,
        )

        # Clear an existing regex
        key_field.update(regex_format=None)
        ```
    """
    body: dict = {}
    if not isinstance(field_name, _UnsetType):
        body["field_name"] = field_name
    if not isinstance(field_description, _UnsetType):
        body["field_description"] = field_description
    if not isinstance(field_examples, _UnsetType):
        body["field_examples"] = field_examples
    if not isinstance(regex_format, _UnsetType):
        body["regex_format"] = regex_format
    if not isinstance(serial_format_prefix, _UnsetType):
        body["serial_format_prefix"] = serial_format_prefix
    if not isinstance(serial_format_padding, _UnsetType):
        body["serial_format_padding"] = serial_format_padding
    if not isinstance(format_enforcement, _UnsetType):
        body["format_enforcement"] = (
            format_enforcement.value
            if isinstance(format_enforcement, FormatEnforcementEnum)
            else format_enforcement
        )
    if not isinstance(show_format_warning, _UnsetType):
        body["show_format_warning"] = show_format_warning
    if not isinstance(initial_counter_value, _UnsetType):
        body["initial_counter_value"] = initial_counter_value
    if not isinstance(role, _UnsetType):
        body["role"] = (
            role.value if isinstance(role, EntityFieldRoleEnum) else role
        )

    if not body:
        return self

    resp = self._client._put(f"/key_fields/{self.id}", body)
    if resp is None or "resource" not in resp:
        return None

    updated = KeyField.model_validate(resp["resource"])
    _copy_fields(updated, self)
    self._client.entity_fields._clear_key_field_caches()
    return self

DataField

Bases: EntityField

A data field — stores additional information about entities.

Data fields support updating display, aggregation, archival, and type-related settings.

Example
data_field = client.entity_fields.get_or_create_data_field(
    "temperature", DataFieldTypeEnum.NUMBER,
)
data_field.update(
    display_aggregation_type=ValueAggregationTypeEnum.MEAN,
    is_archived=False,
)

Methods:

Name Description
update

Update one or more configurable properties of this data field.

update

update(*, field_name: str | _UnsetType = UNSET, field_description: str | _UnsetType = UNSET, field_examples: str | _UnsetType = UNSET, is_archived: bool | _UnsetType = UNSET, is_readonly: bool | _UnsetType = UNSET, display_aggregation_type: ValueAggregationTypeEnum | None | _UnsetType = UNSET, display_includes_sub_records: bool | _UnsetType = UNSET, display_includes_operations: bool | _UnsetType = UNSET, lookup_display_aggregation_type: ValueAggregationTypeEnum | None | _UnsetType = UNSET, lookup_display_includes_sub_records: bool | _UnsetType = UNSET, lookup_display_operation_scope: LookupDisplayOperationScopeEnum | _UnsetType = UNSET, attrs: dict | _UnsetType = UNSET) -> 'DataField' | None

Update one or more configurable properties of this data field.

Only the arguments you pass are sent to the server. Omitted arguments default to UNSET and are left unchanged. For nullable display aggregation fields, pass None explicitly to clear them.

Parameters:

Name Type Description Default
field_name str | _UnsetType

New name for the field.

UNSET
field_description str | _UnsetType

Human-readable description of the field (max 500 characters). Pass an empty string to clear.

UNSET
field_examples str | _UnsetType

Example values for the field (max 500 characters). Pass an empty string to clear.

UNSET
is_archived bool | _UnsetType

Whether the field is archived.

UNSET
is_readonly bool | _UnsetType

Whether the field is read-only.

UNSET
display_aggregation_type ValueAggregationTypeEnum | None | _UnsetType

How aggregated values are displayed; pass None to clear.

UNSET
display_includes_sub_records bool | _UnsetType

Whether to include sub-records in the display value.

UNSET
display_includes_operations bool | _UnsetType

Whether to include operations in the display value.

UNSET
lookup_display_aggregation_type ValueAggregationTypeEnum | None | _UnsetType

Aggregation type for lookup display; pass None to clear.

UNSET
lookup_display_includes_sub_records bool | _UnsetType

Whether lookups include sub-records.

UNSET
lookup_display_operation_scope LookupDisplayOperationScopeEnum | _UnsetType

Scope of operations included in lookup displays.

UNSET
attrs dict | _UnsetType

Type-specific attributes JSON for this field.

UNSET

Returns:

Type Description
'DataField' | None

The updated DataField (also reflected on self), or None

'DataField' | None

if the server returned an unexpected response shape.

Raises:

Type Description
KalbioAPIError

If the API request fails.

Example
# Archive a field
data_field.update(is_archived=True)

# Set how aggregated values are displayed
data_field.update(
    display_aggregation_type=ValueAggregationTypeEnum.MEAN,
    display_includes_sub_records=True,
)
Source code in kalbio/entity_fields.py
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
def update(
    self,
    *,
    field_name: Union[str, _UnsetType] = UNSET,
    field_description: Union[str, _UnsetType] = UNSET,
    field_examples: Union[str, _UnsetType] = UNSET,
    is_archived: Union[bool, _UnsetType] = UNSET,
    is_readonly: Union[bool, _UnsetType] = UNSET,
    display_aggregation_type: Union[
        Optional[ValueAggregationTypeEnum], _UnsetType
    ] = UNSET,
    display_includes_sub_records: Union[bool, _UnsetType] = UNSET,
    display_includes_operations: Union[bool, _UnsetType] = UNSET,
    lookup_display_aggregation_type: Union[
        Optional[ValueAggregationTypeEnum], _UnsetType
    ] = UNSET,
    lookup_display_includes_sub_records: Union[bool, _UnsetType] = UNSET,
    lookup_display_operation_scope: Union[
        LookupDisplayOperationScopeEnum, _UnsetType
    ] = UNSET,
    attrs: Union[dict, _UnsetType] = UNSET,
) -> Optional["DataField"]:
    """Update one or more configurable properties of this data field.

    Only the arguments you pass are sent to the server. Omitted arguments
    default to `UNSET` and are left unchanged. For nullable display
    aggregation fields, pass `None` explicitly to clear them.

    Args:
        field_name: New name for the field.
        field_description: Human-readable description of the field
            (max 500 characters). Pass an empty string to clear.
        field_examples: Example values for the field (max 500 characters).
            Pass an empty string to clear.
        is_archived: Whether the field is archived.
        is_readonly: Whether the field is read-only.
        display_aggregation_type: How aggregated values are displayed; pass None to clear.
        display_includes_sub_records: Whether to include sub-records in the display value.
        display_includes_operations: Whether to include operations in the display value.
        lookup_display_aggregation_type: Aggregation type for lookup display; pass None to clear.
        lookup_display_includes_sub_records: Whether lookups include sub-records.
        lookup_display_operation_scope: Scope of operations included in lookup displays.
        attrs: Type-specific attributes JSON for this field.

    Returns:
        The updated `DataField` (also reflected on `self`), or None
        if the server returned an unexpected response shape.

    Raises:
        KalbioAPIError: If the API request fails.

    Example:
        ```python
        # Archive a field
        data_field.update(is_archived=True)

        # Set how aggregated values are displayed
        data_field.update(
            display_aggregation_type=ValueAggregationTypeEnum.MEAN,
            display_includes_sub_records=True,
        )
        ```
    """
    body: dict = {}
    if not isinstance(field_name, _UnsetType):
        body["field_name"] = field_name
    if not isinstance(field_description, _UnsetType):
        body["field_description"] = field_description
    if not isinstance(field_examples, _UnsetType):
        body["field_examples"] = field_examples
    if not isinstance(is_archived, _UnsetType):
        body["is_archived"] = is_archived
    if not isinstance(is_readonly, _UnsetType):
        body["is_readonly"] = is_readonly
    if not isinstance(display_aggregation_type, _UnsetType):
        body["display_aggregation_type"] = (
            display_aggregation_type.value
            if isinstance(display_aggregation_type, ValueAggregationTypeEnum)
            else display_aggregation_type
        )
    if not isinstance(display_includes_sub_records, _UnsetType):
        body["display_includes_sub_records"] = display_includes_sub_records
    if not isinstance(display_includes_operations, _UnsetType):
        body["display_includes_operations"] = display_includes_operations
    if not isinstance(lookup_display_aggregation_type, _UnsetType):
        body["lookup_display_aggregation_type"] = (
            lookup_display_aggregation_type.value
            if isinstance(lookup_display_aggregation_type, ValueAggregationTypeEnum)
            else lookup_display_aggregation_type
        )
    if not isinstance(lookup_display_includes_sub_records, _UnsetType):
        body["lookup_display_includes_sub_records"] = (
            lookup_display_includes_sub_records
        )
    if not isinstance(lookup_display_operation_scope, _UnsetType):
        body["lookup_display_operation_scope"] = (
            lookup_display_operation_scope.value
            if isinstance(
                lookup_display_operation_scope, LookupDisplayOperationScopeEnum
            )
            else lookup_display_operation_scope
        )
    if not isinstance(attrs, _UnsetType):
        body["attrs"] = attrs

    if not body:
        return self

    resp = self._client._put(f"/data_fields/{self.id}", body)
    if resp is None or "resource" not in resp:
        return None

    # /data_fields response shape is { resource: { field, validation }, event }
    field_payload = resp["resource"].get("field", resp["resource"])
    updated = DataField.model_validate(field_payload)
    _copy_fields(updated, self)
    self._client.entity_fields._clear_data_field_caches()
    return self

EntityFieldIdentifier module-attribute

EntityFieldIdentifier: TypeAlias = EntityField | str

An Identifier Type for Entity Fields.

An EntityField should be able to be identified by:

  • EntityField (object instance) — also accepts KeyField and DataField
  • UUID (str)
  • field_name (str)

EntityFieldsService

EntityFieldsService(client: KaleidoscopeClient)

Service class for managing key fields and data fields in Kaleidoscope.

Entity fields can be of two types:

  • Key fields: Used to uniquely identify entities
  • Data fields: Used to store additional information about entities
Example
key_fields = client.entity_fields.get_key_fields()
temperature = client.entity_fields.get_or_create_data_field(
    field_name="temperature",
    field_type=DataFieldTypeEnum.NUMBER,
)

Methods:

Name Description
get_key_fields

Retrieve key fields and cache the result.

get_key_field_by_id

Get a key field by an identifier.

get_or_create_key_field

Retrieve an existing key field by name or create it.

get_data_fields

Retrieve data fields and cache the result.

get_data_field_by_id

Get a data field by identifier.

get_or_create_data_field

Create a data field or return the existing one.

Source code in kalbio/entity_fields.py
562
563
def __init__(self, client: KaleidoscopeClient):
    self._client = client

get_key_fields cached

get_key_fields() -> list[KeyField]

Retrieve key fields and cache the result.

Returns:

Type Description
list[KeyField]

Key field definitions for the workspace.

Notes

On error, the caches are cleared and an empty list is returned.

Example
key_fields = client.entity_fields.get_key_fields()
Source code in kalbio/entity_fields.py
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
@lru_cache
def get_key_fields(self) -> List[KeyField]:
    """Retrieve key fields and cache the result.

    Returns:
        Key field definitions for the workspace.

    Notes:
        On error, the caches are cleared and an empty list is returned.

    Example:
        ```python
        key_fields = client.entity_fields.get_key_fields()
        ```
    """
    resp = self._client._get("/key_fields")
    fields = TypeAdapter(List[KeyField]).validate_python(resp)
    for field in fields:
        field._set_client(self._client)
    return fields

get_key_field_by_id

get_key_field_by_id(identifier: EntityFieldIdentifier) -> KeyField | None

Get a key field by an identifier.

Parameters:

Name Type Description Default
identifier EntityFieldIdentifier

Key field identifier. Data field identifiers will return None.

This method will accept and resolve any type of EntityFieldIdentifier.

required

Returns:

Type Description
KeyField | None

Matching key field if found. If not, returns None.

Example
key_field = client.entity_fields.get_key_field_by_id("sample_id")
Source code in kalbio/entity_fields.py
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
def get_key_field_by_id(
    self, identifier: EntityFieldIdentifier
) -> KeyField | None:
    """Get a key field by an identifier.

    Args:
        identifier: Key field identifier. Data field identifiers will return None.

            This method will accept and resolve any type of EntityFieldIdentifier.

    Returns:
        Matching key field if found. If not, returns None.

    Example:
        ```python
        key_field = client.entity_fields.get_key_field_by_id("sample_id")
        ```
    """

    id_map = self._get_key_field_id_map()
    field_id = self._resolve_key_field_id(identifier)

    if field_id:
        return id_map.get(field_id, None)
    else:
        return None

get_or_create_key_field

get_or_create_key_field(field_name: str) -> KeyField

Retrieve an existing key field by name or create it.

Parameters:

Name Type Description Default
field_name str

Name of the key field to fetch or create.

required

Returns:

Type Description
KeyField

Existing or newly created key field.

Raises:

Type Description
KalbioAPIError

If the API request fails.

Example
key_field = client.entity_fields.get_or_create_key_field("sample_id")
Source code in kalbio/entity_fields.py
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
def get_or_create_key_field(self, field_name: str) -> KeyField:
    """Retrieve an existing key field by name or create it.

    Args:
        field_name: Name of the key field to fetch or create.

    Returns:
        Existing or newly created key field.

    Raises:
        KalbioAPIError: If the API request fails.

    Example:
        ```python
        key_field = client.entity_fields.get_or_create_key_field("sample_id")
        ```
    """
    field = self.get_key_field_by_id(field_name)
    if field is not None:
        return field

    self._clear_key_field_caches()

    data = {"field_name": field_name}
    resp = self._client._post("/key_fields/", data)
    field = KeyField.model_validate(resp)
    field._set_client(self._client)
    return field

get_data_fields cached

get_data_fields() -> list[DataField]

Retrieve data fields and cache the result.

Returns:

Type Description
list[DataField]

Data field definitions for the workspace.

Notes

On error, the caches are cleared and an empty list is returned.

Example
data_fields = client.entity_fields.get_data_fields()
Source code in kalbio/entity_fields.py
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
@lru_cache
def get_data_fields(self) -> List[DataField]:
    """Retrieve data fields and cache the result.

    Returns:
        Data field definitions for the workspace.

    Notes:
        On error, the caches are cleared and an empty list is returned.

    Example:
        ```python
        data_fields = client.entity_fields.get_data_fields()
        ```
    """
    resp = self._client._get("/data_fields")
    fields = TypeAdapter(List[DataField]).validate_python(resp)
    for field in fields:
        field._set_client(self._client)
    return fields

get_data_field_by_id

get_data_field_by_id(identifier: EntityFieldIdentifier) -> DataField | None

Get a data field by identifier.

Parameters:

Name Type Description Default
identifier EntityFieldIdentifier

Identifier for a data field. Key field identifiers return None.

This method will accept and resolve any type of EntityFieldIdentifier.

required

Returns:

Type Description
DataField | None

Matching data field, if found.

Example
data_field = client.entity_fields.get_data_field_by_id("temperature")
Source code in kalbio/entity_fields.py
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
def get_data_field_by_id(
    self, identifier: EntityFieldIdentifier
) -> DataField | None:
    """Get a data field by identifier.

    Args:
        identifier: Identifier for a data field. Key field identifiers return None.

            This method will accept and resolve any type of EntityFieldIdentifier.


    Returns:
        Matching data field, if found.

    Example:
        ```python
        data_field = client.entity_fields.get_data_field_by_id("temperature")
        ```
    """

    id_map = self._get_data_field_id_map()
    field_id = self._resolve_data_field_id(identifier)

    if field_id:
        return id_map.get(field_id, None)
    else:
        return None

get_or_create_data_field

get_or_create_data_field(field_name: str, field_type: DataFieldTypeEnum) -> DataField

Create a data field or return the existing one.

Parameters:

Name Type Description Default
field_name str

Name of the data field to create or retrieve.

required
field_type DataFieldTypeEnum

Data field type.

required

Returns:

Type Description
DataField

Existing or newly created data field.

Raises:

Type Description
KalbioAPIError

If the API request fails.

Example
concentration = client.entity_fields.get_or_create_data_field(
    field_name="concentration",
    field_type=DataFieldTypeEnum.NUMBER,
)
Source code in kalbio/entity_fields.py
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
def get_or_create_data_field(
    self, field_name: str, field_type: DataFieldTypeEnum
) -> DataField:
    """Create a data field or return the existing one.

    Args:
        field_name: Name of the data field to create or retrieve.
        field_type: Data field type.

    Returns:
        Existing or newly created data field.

    Raises:
        KalbioAPIError: If the API request fails.

    Example:
        ```python
        concentration = client.entity_fields.get_or_create_data_field(
            field_name="concentration",
            field_type=DataFieldTypeEnum.NUMBER,
        )
        ```
    """
    field = self.get_data_field_by_id(field_name)
    if field is not None:
        return field

    self._clear_data_field_caches()

    data: dict = {
        "field_name": field_name,
        "field_type": field_type.value,
        "attrs": {},
    }
    resp = self._client._post("/data_fields/", data)
    field = DataField.model_validate(resp)
    field._set_client(self._client)
    return field