Skip to content

Tagged Resource

albert.resources.tagged_base

BaseTaggedResource

BaseTaggedResource is a Pydantic model that includes functionality for handling tags as either Tag objects or strings.

Show JSON schema:
{
  "$defs": {
    "AuditFields": {
      "description": "The audit fields for a resource",
      "properties": {
        "by": {
          "default": null,
          "title": "By",
          "type": "string"
        },
        "byName": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Byname"
        },
        "at": {
          "anyOf": [
            {
              "format": "date-time",
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "At"
        }
      },
      "title": "AuditFields",
      "type": "object"
    },
    "EntityLink": {
      "properties": {
        "id": {
          "title": "Id",
          "type": "string"
        },
        "name": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Name"
        },
        "category": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "title": "Category"
        }
      },
      "required": [
        "id"
      ],
      "title": "EntityLink",
      "type": "object"
    },
    "Status": {
      "description": "The status of a resource.\n\nAttributes\n----------\nACTIVE : str\n    The resource is fully operational and visible in normal operations.\nINACTIVE : str\n    The resource is hidden from normal operations and disabled from use.",
      "enum": [
        "active",
        "inactive"
      ],
      "title": "Status",
      "type": "string"
    },
    "Tag": {
      "description": "A freeform text label used to categorize and connect entities.\n\nTags are shared by name across the platform and can be applied to inventory\nitems, companies, tasks, and other records to group and filter them. Managed\nthrough [`TagCollection`][albert.collections.tags.TagCollection] (``client.tags``);\nthe usual entry point is [`get_or_create`][albert.collections.tags.TagCollection.get_or_create].\n\n!!! example\n    ```python\n    from albert.resources.tags import Tag\n    tag = Tag(tag=\"high-priority\")\n    ```\nMethods\n-------\nfrom_string(tag) -> Tag\n    Build a Tag from its name string.",
      "properties": {
        "status": {
          "anyOf": [
            {
              "$ref": "#/$defs/Status"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The status of the resource, optional."
        },
        "Created": {
          "anyOf": [
            {
              "$ref": "#/$defs/AuditFields"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Audit fields for the creation of the resource, optional."
        },
        "Updated": {
          "anyOf": [
            {
              "$ref": "#/$defs/AuditFields"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "Audit fields for the update of the resource, optional."
        },
        "name": {
          "description": "The name of the tag (its text label).",
          "title": "Name",
          "type": "string"
        },
        "albertId": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "default": null,
          "description": "The Albert ID of the tag (format ``TAG...``). Set when the tag is retrieved from or created in Albert. Methods ------- from_string(tag) -> Tag Build a Tag from its name string.",
          "title": "Albertid"
        }
      },
      "required": [
        "name"
      ],
      "title": "Tag",
      "type": "object"
    }
  },
  "description": "BaseTaggedResource is a Pydantic model that includes functionality for handling tags as either Tag objects or strings.",
  "properties": {
    "status": {
      "anyOf": [
        {
          "$ref": "#/$defs/Status"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "The status of the resource, optional."
    },
    "Created": {
      "anyOf": [
        {
          "$ref": "#/$defs/AuditFields"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Audit fields for the creation of the resource, optional."
    },
    "Updated": {
      "anyOf": [
        {
          "$ref": "#/$defs/AuditFields"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "Audit fields for the update of the resource, optional."
    },
    "Tags": {
      "anyOf": [
        {
          "items": {
            "anyOf": [
              {
                "$ref": "#/$defs/Tag"
              },
              {
                "$ref": "#/$defs/EntityLink"
              }
            ]
          },
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "default": null,
      "description": "A list of Tag objects or strings representing tags.",
      "title": "Tags"
    }
  },
  "title": "BaseTaggedResource",
  "type": "object"
}

Fields:

tags

tags: list[SerializeAsEntityLink[Tag]] | None = None

A list of Tag objects or strings representing tags.

convert_tags

convert_tags(data: dict[str, Any]) -> dict[str, Any]
Source code in src/albert/resources/tagged_base.py
@model_validator(mode="before")  # must happen before to keep type validation
@classmethod
def convert_tags(cls, data: dict[str, Any]) -> dict[str, Any]:
    if not isinstance(data, dict):
        return data
    tags = data.get("tags")
    if not tags:
        tags = data.get("Tags")
    if not tags and isinstance(data.get("Data"), dict):
        tags = data["Data"].get("tags") or data["Data"].get("Tags")
    if tags:
        new_tags = []
        for t in tags:
            if isinstance(t, Tag):
                new_tags.append(t)
            elif isinstance(t, str):
                new_tags.append(Tag.from_string(t))
            elif isinstance(t, dict):
                if "id" in t and not (t.get("name") or t.get("tagName") or t.get("tag")):
                    raise ValueError(
                        "Tag references by dict require the tag's name alongside its id "
                        "(e.g. {'id': 'TAG…', 'name': 'AAMA'}): the platform requires both "
                        "on write. Resolve the pair via client.tags.get_or_create first."
                    )
                new_tags.append(Tag(**t))
            else:
                # We do not expect this else to be hit because tags should only be Tag or str
                logging.warning(f"Unexpected value for Tag. {t} of type {type(t)}")
                continue
        data["tags"] = new_tags
    return data