Unicat Python SDK

Up - Home


The unicat package, reading/traversing/properties

from unicat import Unicat
from config import PROJECT_GID, SECRET_API_KEY, LOCAL_ASSET_FOLDER

# please use the keyring module in .config to store/retrieve the SECRET_API_KEY

unicat = Unicat("https://unicat.app", PROJECT_GID, SECRET_API_KEY, LOCAL_ASSET_FOLDER)
if not unicat.connect():
    raise Exception("Invalid connection settings")

Connection methods

unicat.connect(*, omit_extended_definitions: bool = False) -> bool
unicat.sync() -> True

omit_extended_definitions (new in v0.7.18) When True, excludes extended definitions from the initial project schema (faster connect on projects with many extended definitions). Default is False (full schema). See Deferred loading of extended definitions.

Reading methods

unicat.get_record(gid: str, *, force: bool) -> UnicatRecord | None
unicat.get_records(gids: list[str], *, force: bool) -> list[UnicatRecord]
unicat.get_root_record() -> UnicatRecord
unicat.get_asset(gid: str, *, force: bool) -> UnicatAsset | None
unicat.get_asset_by_pathname(pathname: str, *, force: bool) -> UnicatAsset | None
unicat.get_assets(gids: list[str], *, force: bool) -> list[UnicatAsset]
unicat.get_assets_by_pathname(pathnames: list[str], *, force: bool) -> dict[str, UnicatAsset]
unicat.get_root_asset() -> UnicatAsset
unicat.get_definition(gid: str) -> UnicatDefinition | None
unicat.get_definitions(gids: list[str]) -> list[UnicatDefinition]
unicat.get_definition_by_name(name: str) -> UnicatDefinition | None
unicat.get_definitions_by_name(names: list[str]) -> dict[str, UnicatDefinition | None]
unicat.get_class(gid: str) -> UnicatClass | None
unicat.get_classes(gids: list[str]) -> list[UnicatClass]
unicat.get_class_by_name(name: str) -> UnicatClass | None
unicat.get_classes_by_name(names: list[str]) -> dict[str, UnicatClass | None]
unicat.get_field(gid: str) -> UnicatField | None
unicat.get_fields(gids: list[str]) -> list[UnicatField]
unicat.get_field_by_name(name: str) -> UnicatField | None
unicat.get_fields_by_name(names: list[str]) -> dict[str, UnicatField | None]
unicat.get_query(gid: str) -> UnicatQuery | None
unicat.get_queries(gids: list[str]) -> list[UnicatQuery]
unicat.get_record_query_by_name(name: str) -> UnicatQuery | None
unicat.get_record_queries_by_name(names: list[str]) -> dict[str, UnicatQuery | None]
unicat.get_asset_query_by_name(name: str) -> UnicatQuery | None
unicat.get_asset_queries_by_name(names: list[str]) -> dict[str, UnicatQuery | None]
unicat.get_schema_query_by_name(name: str) -> UnicatQuery | None
unicat.get_schema_queries_by_name(names: list[str]) -> dict[str, UnicatQuery | None]
unicat.get_all_module_names() -> list[str]  # New in v0.7.9
unicat.get_module(name: str, *, force: bool) -> UnicatModule | None  # New in v0.7.9
unicat.get_modules(names: list[str], *, force: bool) -> list[UnicatModule]  # New in v0.7.9

Traversing methods

unicat.walk_record_children(parent_record: UnicatRecord, channel: gid, ordering: gid) -> Iterator[UnicatRecord]
unicat.walk_record_tree(channel: gid, ordering: gid) -> Iterator[UnicatRecord]
unicat.walk_record_query(language: str, query: UnicatQuery, *, limit: int) -> Iterator[tuple[int, UnicatRecord]]
unicat.walk_asset_children(parent_asset: UnicatAsset) -> Iterator[UnicatAsset]
unicat.walk_asset_tree() -> Iterator[UnicatAsset]
unicat.walk_asset_query(language: str, query: UnicatQuery, *, limit: int) -> Iterator[tuple[int, UnicatAsset]]
unicat.walk_definitions() -> Iterator[UnicatDefinition]
unicat.walk_classes() -> Iterator[UnicatClass]
unicat.walk_fields() -> Iterator[UnicatField]
unicat.walk_schema_query(language: str, query: UnicatQuery, *, limit: int) -> Iterator[tuple[int, UnicatQuery]]
unicat.walk_queries() -> Iterator[UnicatQuery]
unicat.walk_modules() -> Iterator[UnicatModule]  # New in v0.7.9

Properties

unicat.project: UnicatProject

UnicatProject properties & methods

project.gid: gid
project.name: str
project.owner: UnicatUser
project.icon: str  # used to construct /media url
project.status: str
project.languages: list[str]
project.default_language: str
project.channels: dict[str, gid]
project.default_channel: gid
project.channel_name(key: gid) -> str
project.orderings: dict[str, gid]
project.default_ordering: gid
project.ordering_name(key: gid) -> str
project.fieldlists: dict[str, gid]
project.default_fieldlist: gid
project.fieldlist_name(key: gid) -> str
project.backups: list[UnicatProjectBackup]
project.get_backup(version: int) -> UnicatProjectBackup | None
project.members: list[UnicatProjectMember]

UnicatUser properties & methods

user.gid: gid
user.username: str
user.name: str
user.avatar: str  # used to construct /media url

UnicatProjectMember properties & methods

projectmember.project: UnicatProject
projectmember.user: UnicatUser
projectmember.status: str
projectmember.roles: list[str]
projectmember.options: dict
projectmember.key: str

UnicatProjectBackup properties & methods

backup.version: int
backup.name: str
backup.created_by: str
backup.timestamp: timestamp  # 1610635123.351925

UnicatDefinition properties & methods

definition.gid: gid
definition.original: UnicatDefinition | None
definition.name: str
definition.label: dict[str, str]  # key is language
definition.classes: list[UnicatClass]
definition.classes_as_gids: list[gid]
definition.fields: list[UnicatField]
definition.fields_as_gids: list[gid]
definition.titlefield: UnicatField
definition.fieldlists: dict[str, list[UnicatField]]  # key is fieldlist key
definition.layout: UnicatLayout
definition.childdefinitions: list[UnicatDefinition]
definition.is_base: bool
definition.is_new: bool
definition.is_extended: bool
definition.is_working_copy: bool
definition.is_committed: bool
definition.all_fields: list[UnicatField]
definition.base_classes: list[UnicatClass]
definition.base_fields: list[UnicatField]
definition.all_base_fields: list[UnicatField]
definition.extended_classes: list[UnicatClass]
definition.extended_fields: list[UnicatField]
definition.all_extended_fields: list[UnicatField]
definition.metadata: dict[str, UnicatMetadataField]

UnicatClass properties & methods

class_.gid: gid
class_.original: UnicatClass | None
class_.name: str
class_.label: dict[str, str]  # key is language
class_.fields: list[UnicatField]
class_.fields_as_gids: list[gid]
class_.layout: UnicatLayout
class_.is_new: bool
class_.is_working_copy: bool
class_.is_committed: bool
class_.metadata: dict[str, UnicatMetadataField]

UnicatField properties & methods

field.gid: gid
field.original: UnicatField | None
field.name: str
field.type: str
field.class_: UnicatClass | None
field.options: dict
field.is_localized: bool
field.is_required: bool
field.label: dict[str, str]  # key is language
field.initial: dict[str, str]  # key is language
field.unit: str
field.title: dict[str, str]  # key is language
field.is_new: bool
field.is_working_copy: bool
field.is_committed: bool
field.metadata: dict[str, UnicatMetadataField]

UnicatLayout properties & methods

layout.gid: gid
layout.original: UnicatLayout | None
layout.name: str
layout.root: gid
layout.components: dict[gid, dict]
layout.is_new: bool
layout.is_working_copy: bool

UnicatQuery properties & methods

query.gid: gid
query.type: str  # schema, record, or asset
query.name: str
query.q: str
query.filter: list

UnicatAsset properties & methods

asset.gid: gid
asset.pathname: str
asset.path: str
asset.name: str
asset.is_file: bool
asset.type: str
asset.childcount: int
asset.status: str
asset.is_deleted: bool
asset.info: dict
asset.transforms: dict[str, dict] | None
asset.default_transform: dict | None
asset.title: dict[str, str]  # key is language
asset.description: dict[str, str]  # key is language
asset.metadata: dict[str, UnicatMetadataField]  # New in v0.7.15
asset.created_on: timestamp  # 1610635123.351925
asset.updated_on: timestamp  # 1610635123.351925
asset.publish() -> str  # public_url
asset.publish_transformed(transform: UnicatTransform | None) -> str  # public_url
asset.download(pathname: str | None) -> False | None | str  # local_filepath
asset.download_transformed(transform: UnicatTransform | None, pathname: str | None) -> False | None | str  # local_filepath

UnicatRecord properties & methods

record.gid: gid
record.canonical: gid
record.parent: gid
record.backlinks: list[gid]
record.is_link: bool
record.is_deleted: bool
record.treelevel: int
record.path: list[gid]
record.title: dict[str, str]  # key is language
record.channels: list[gid]  # enabled channels only
record.orderings: dict[gid, int]
record.childcount: int
record.definition: UnicatDefinition
record.created_on: timestamp  # 1610635123.351925
record.updated_on: timestamp  # 1610635123.351925
record.fields: dict[str, dict[str, UnicatRecordField]]  # key is language, then fieldname
record.validation_report: None | list[dict[str, Any]]  # validation result after updates

UnicatRecordField properties & methods

recordfield.field: UnicatField
recordfield.value: Any
recordfield.key: None | str

A record field can have a value, a reference (record, asset), or it can be nested for class-fields.
We also support 'list' versions of these.

For textline/textlist fields that have a values option (a selection of values to choose from), the key property holds the key, and the value property holds the label (unless value_labels is disabled for that field, then value holds the key too). The key is None in all other cases.

# for values

artnr = record.fields[language]["artnr"]  # a recordfield
artnr.value             # "CMS 225-945"
artnr.field.label       # "Article number"
artnr.field.type        # "textline"

# for references

image = record.fields[language]["image"]  # both recordfield and asset
image.value             # "a0a80c9c-fa1b-4573-ac98-b7b07c81b583"
image.field.label       # "Image"
image.pathname          # "/products/cms225.eps"

Note: if image.value is None, trying to access image.pathname will result in an AttributeError

# for class fields

dimensions_interior = record.fields[language]["dimensions_interior"]
                        # a recordfield and classfield
dimensions_interior.value               # {"width__mm": 374, …}
dimensions_interior["width__mm"].value  # 374  -- this is a recordfield

# for list values

colors = record.fields[language]["colors"]
colors.value            # ["Red", "Blue"]
colors.key              # ["r", "b"] -- not named `keys`
colors.field.label      # "Colors"
colors[0].value         # "Red" -- this is just a string
colors[0].key           # "r"

# for list references

images = record.fields[language]["images"]
images.value            # ["a0a80c9c-fa1b-4573-ac98-b7b07c81b583", ]
images.field.label      # "Images"
images[0]               # this is just an asset
images[0].pathname      # "/products/cms225.eps"

# for classlist fields

tablespecs = record.fields[language]["tablespecs"]
tablespecs.value                        # [{"width__mm": 7, …}, …]
tablespecs.field.label                  # "Table specs"
tablespecs[0]                           # this is recordfield-like
tablespecs[0]["width__mm"].value        # 7
tablespecs[0]["width__mm"].field.label  # "Width"

UnicatMetadataField properties & methods

metadata_field.name: str
metadata_field.type: str
metadata_field.is_localized: bool
metadata_field.value: None | Any | dict(str, None | Any)  # key is language

A metadata field can have a value or a reference (asset, field), and it can be localized. If you need the gid for the reference and don't want it to automatically make an API call, use the underlying metadata_field._value to get it.

# example field

artnr = unicat.get_field_by_name("artnr")

# for values

meta_align = artnr.metadata["heading.alignment"]
meta_align.name            # "heading.alignment"
meta_align.type            # "textline"
meta_align.is_localized    # False
meta_align.value           # "left"

# for localized values

meta_abbr = artnr.metadata["heading.abbreviation"]
meta_abbr.name             # "heading.abbreviation"
meta_abbr.type             # "textline"
meta_abbr.is_localized     # True
meta_abbr.value            # {"en": "Artnr", "nl": "Artnr"}
meta_abbr.value["en"]      # "Artnr"

# for references

meta_icon = artnr.metadata["heading.icon"]
meta_icon.type             # "image"
meta_icon.is_localized     # False
meta_icon.value            # UnicatAsset | None
meta_icon.value.gid        # "a0a80c9c-fa1b-4573-ac98-b7b07c81b583"
meta_icon.value.pathname   # "/products/cms225.eps"

meta_related = artnr.metadata["heading.related_field"]
meta_related.type          # "fieldpicker"
meta_related.is_localized  # False
meta_related.value         # UnicatField | None
meta_related.value.gid     # "0c9ca0a8-fa1b-4573-ac98-81b583b7b07c"
meta_related.value.name    # "EAN"

# for localized references

meta_icon = artnr.metadata["heading.icon"]
meta_icon.type             # "image"
meta_icon.is_localized     # True
meta_icon.value            # {"en": UnicatAsset | None, "nl": UnicatAsset | None}  | None
meta_icon.value["en"]      # UnicatAsset | None
meta_icon.value["en"].gid  # "a0a80c9c-fa1b-4573-ac98-b7b07c81b583"
meta_icon.value["en"].pathname   # "/products/cms225.eps"

meta_related = artnr.metadata["heading.related_field"]
meta_related.type             # "fieldpicker"
meta_related.is_localized     # True
meta_related.value            # {"en": UnicatField | None, "nl": UnicatField | None} | None
meta_related.value["en"]      # UnicatField | None
meta_related.value["en"].gid  # "0c9ca0a8-fa1b-4573-ac98-81b583b7b07c"
meta_related.value["en"].name # "EAN"

UnicatModule properties & methods

New in v0.7.9

module.name: str
module.version: str  # in 1.2.3 format
module.keys: dict(str, Any)
module.actions: dict(str, UnicatModuleAction)
module.logs: list(UnicatModuleLog)

UnicatModuleAction properties & methods

New in v0.7.9

module_action.name: str
module_action.configuration: dict(str, Any)

UnicatModuleLog properties & methods

New in v0.7.9

module_log.timestamp: timestamp  # 1610635123.351925
module_log.version: str  # in 1.2.3 format
module_log.action: str
module_log.configuration: dict(str, Any)
module_log.command: str
module_log.started_at: timestamp  # 1610635123.351925
module_log.ended_at: timestamp  # 1610635123.351925
module_log.duration: float # seconds
module_log.status: str
module_log.output: str