Skip to main content

Data Provider

Introduction​

This library is included for easily queriying data in the incoming xml-paylod of the rednerpdf-request. It expects the xml-structure described in the priint:cloud documentation.

The library is built to be as extensible as possible. Aside from the default class "DataProvider" another class for a "generic" entity-type is included, that inherits from the base-class. This can be extended per project-requirements by adding further classes with default parameters and custom methods.

Initialization​

After importing the library, an instance of the dataprovider can be initialized by calling either of the class initializers

my_lib = comet.pyImport("[xml]/library/data_provider.py")
entity = my_lib.DataProvider("my_string_id", "my_node_type")
other_entity = my_lib.GenericEntity("my_other_string_id", "my_other_node_type")

... or the library-function 'initialize_entity()' to dynamically evaluate, which entity is required, based on the input.
This is used in most default placeholder-scripts, so that users can specify the entity-type in the placeholder-options while creating templates in InDesign. Example:

entity = my_lib.initialize_entity("generic", {"id":comet.gRecordStringID,"type":comet.gNodeType})

While initialization, the comet module is checked for information on previous instances of ths class. In case previous node_type and string_id match the current ones, any previously cached key values are reused in this object.

Attributes that are checked in Comet-Module
comet.lib_dataprovider_previous_string_id
comet.lib_dataprovider_previous_type
comet.lib_dataprovider_cache

Constants​

ENTITY_NAMES​

Contains a list[str] with names of all available data-provider-classes. Can be checked for available classes before initializing or providing as options for user-input. Current Classes: DataProvider, GenericEntity

CONTENT_KEYS​

Contains a dict[str,str] with keys for attributes of XML-nodes. These resemble the defaults defined in the priint:cloud XML-structure and are used in XML-queries to filter nodes and retrieve values by.
Many DataProvider-methods allow to pass a custom dict to a content_keys-parameter. In that case, the custom attribute-key needs to be mapped as value to the original key.

For examples see method get_attribute_value

Current defaults are:
KeyValue
keykey
contentcontent
idid
idrefidref
valuevalue
typetype
labellabel
attribute_groupattribute_group

METADATA_KEYS​

Contains a dict[str,tuple[str,str]] with a mapping of keys used for setting metadata and keys of attributes in the XML-datafile. These resemble the defaults defined for setting document-metadata by comet and are used in XML-queries to filter retrieve content by.
In the method for retrieving metadata-attribute-values from the XML-datafile, a custom dict can be passed to a content_keys-parameter. In that case, the custom attribute-key needs to be mapped as value to the original key.

For examples see method get_comet_pdf_metadata

Current defaults are:
KeyValue
kTitletuple("kTitle", "string")
kDescriptiontuple("kDescription", "string")
kAuthortuple("kAuthor", "string")
kAuthorTitletuple("kAuthorTitle", "string")
kAuthorDescriptiontuple("kAuthorDescription", "string")
kKeystuple("kKeys", "list")
kCopyRighttuple("kCopyRight", "string")
kCopyRightURLtuple("kCopyRightURL", "string")
kCopyRightStatetuple("kCopyRightState", "int")
kRatingtuple("kRating", "int")

Functions​

initialize_entity(...)​

(entity_name, parameters = None)​

Initializes an instance of a class in this library by a given name. The requested classes must implement the base-class DataProvider, because common methods are used by logic throughout the default-components of this project.

Parameters:entity_name (str)
Name of one of the classes of this library, that implement data-provider-logic. Case-sensitive; compares value to library's constant ENTITY_NAMES.
parameters (dict)
A dictionary of parameters with which the entity will be initialized. It is recommended to give values for the keys id and type, as they're relevant when making queries. But they're not strictly required. If omitting the id, the first id of a node matching the given type will be searched in the datafile.
Returns:List of attribute-values of nodes in the XML-datafile, that match a given type.
Return Type:list[str]

get_preload_urls(...)​

(type = "asset")​

Finds values at the content-attribute of any nodes in the XML-datafile that match the given type. Usually used to get urls of nodes that represent attribute-values for webimages. Can be used as input for preloading webimages using the webimages-library.

Parameters:type (str)
Value of the node's type-attribute, by which matching nodes are filtered in the query.
Returns:List of attribute-values of nodes in the XML-datafile, that match a given type.
Return Type:list[str]

find_entity_ids(...)​

(type = "product", content = "id")​

Finds values at the attribute specified in the parameter content of any nodes in the XML-datafile that match the given type. Usually used to get ids of entities, for further processing.

Parameters:type (str)
Value of the node's type-attribute, by which matching nodes are filtered in the query.
content (str)
Name of the node's attribute, from which the value is retrieved.
Returns:List of string-ids of entities in the XML-datafile.
Return Type:list[str]

Methods of default class DataProvider​

is_valid_entity()​

Checks if the xml-node of the current entity has an ID.

Returns:Whether the current entity has an ID
Return Type:bool

get_string_id()​

Gets the String-ID that was set when initializing the object or after a different one was set usgin 'set_string_id'

Returns:The String-ID of the current entity.
Return Type:str

set_string_id(...)​

( string_id = "", find_string_id = False, content_keys = None )​

Sets a new String-ID for the current entity. Resets any cached Key-Values if the new ID differs from the previous one. If no String-ID is provided and find_string_id is set to True, the ID is evaluated by searching the XML-file for the ID of the first item-node that matches with the current node-type.

Parameters:string_id (str)
The new String-Id or an empty string
find_string_id (bool)
- True: Find the ID in the XML-file at the first item-node with the current node-type (or any type, if no type is specified in the entity).
- False: Use the provided String-ID.
content_keys (dict)
Use custom attributes when looking for the String-ID.
For example, to find the code of items with the attribute tipo matching the node_type of the current entity, use this as input: {"type":"tipo","id":"code"}
Returns:The String-ID of the current entity.
Return Type:str

get_node_type()​

Retrieve the node-type of the current entity.

Returns:The _node_type property of the entity.
Return Type:str

set_node_type(...)​

( node_type = "" )​

Sets a new node-type for the current entity. Resets any cached Key-Values if the new node-type differs from the previous one.

Parameters:node_type (str)
The new node-type or an empty string
Returns:The new node-type that was set on the entity.
Return Type:str

get_key_values(...)​

( keys = None, content_keys = None, node_conditions = None, settings = None, relative_node_level = 1 )​

Retrieve values of XML-nodes based on specified parameters. Retrieves cached values, if values of the current entity (same node-type and string-id) have been loaded previously. Otherwise, executes queries in XML and caches the found values.

Parameters:keys (list[str])
list of keys, whose values should be retrieved. If empty list or None, values for all keys are retrieved
content_keys (dict)
Replace default-attributes of xml-nodes in xml-queries with custom attributes.
For example, to find the value-attribute of items with the code-attribute matching the list of keys, use this as input: {"key":"code","content":"value"}
Found XML-Node:
<item key="my_key"code="my_code" value="my value"content="my content"/>

Default Keys for node-properties: CONTENT_KEYS
node_conditions (dict)
Add query conditions to the base-node of the query
For example, to find items, where the spam-attribute has the value eggs, use this as input: {"spam":"eggs"}

Found XML-node: <item key="my_key" spam="eggs" content="my content"/>
Not found:
<item key="my_key" spam="foo" content="my content"/>
<item key="my_key" spam="bar" content="my content"/>
settings (dict[str,bool])
Transform the return-value based on different settings:
only_content True: Return the content-attribute of the found values as String instead of dict with all the node's atttributes.
Returns:{"spam":["Eggs","More Eggs"]}
only_first True: Return the attributes of the first found node
Returns:{"spam":{"content":"Eggs", "id":"xyz"}}
only_first True and only_content True: Return only the first found content-value as string
Returns:{"spam":"Eggs"}
See examples below.
relative_node_level (int)
Change the level, the searched node is at, relative to the base-node.
- >= 1: Insert n children nodes to the query.
- 0: Look at the base node.
- <= -1: Insert n parent nodes to the query.
Returns:found values in a dict (keys: input-parameter keys). By default, a value consists of a list of dicts with all attributes of the found xml-nodes
Return Type:dict[str, dict|list|str]
Examples:​
<data>
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item key="spam" content="Eggs" id="id1" code="spam1"/>
<item key="spam" content="More Eggs" id="id2" code="spam2"/>
<item key="foo" content="Bar" id="id3" code="foo1"/>
<item key="foo" content="Baz" id="id4" code="foo2"/>
</item>
</data>
my_val = entity.get_key_values(["spam","foo"])
# returns: {"spam":[{"content":"Eggs","id":"id1},{"content":"More Eggs","id":"id2}],"foo":[{"content":"Bar","id":"id3},{"content":"Baz","id":"id4}]}

my_val = entity.get_key_values(["spam","foo"], settings={"only_first":True})
# returns: {"spam":{"content":"value","id":"id1}}

my_val = entity.get_key_values(["spam","foo"], settings={"only_content":True})
# returns: {"spam":["value","value2"],"foo":["Bar","Baz"]}

my_val = entity.get_key_values(["spam","foo"], settings={"only_content":True,"only_first":True})
# returns: {"spam":"value","foo":"Bar"}

my_val = entity.get_key_values(["spam1","foo1"], content_keys={'key':'code','content':'id'}, settings={"only_content":True,"only_first":True})
# returns: {"spam1":"id1","foo1":"id3"}

my_val = entity.get_key_values(["label"], relative_node_level=0, content_keys={'content':'label'}, settings={"only_content":True,"only_first":True})
# returns: {"label":"Spam and Eggs"}

get_transformed_key_values(...)​

( keys = None, settings = None )​

Retrieve cached values for specified keys transformed based on settings. For more information see documentation of method get_key_values

Parameters:keys (list[str])
list of keys, whose values should be retrieved. If empty list or None, values for all keys are retrieved
settings (dict[str,bool])
Transform the return-value based on different settings.
Returns:cached values as a dict (keys: input-parameter keys). By default, a value consists of a list of dicts with all attributes of the found xml-nodes
Return Type:dict[str, dict|list|str]

get_attribute_value(...)​

( key, content_keys = None )​

Retrieve the first value of a found item below the current base-node. Retrieves data from cache or loads from XML, if not cached yet.

Parameters:key (str)
Key of the desired XML-node whose value should be retrieved.
content_keys (dict[str,str])
Replace attributes in xml-queries with custom attributes. By default, the value is retrieved from the XML-attribute content. This behaviour can be changed by providing a dict that maps the default-attribute to a custom one. For example: {"key":"code","content":"value"} to search for the specified key at attribute code and retrieve the attribute value at value instead of content

Default Keys for node-properties: CONTENT_KEYS
Returns:A string value from the content-attribute at the first node with the specified key.
Return Type:str
Examples:​
<data>
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item key="spam" code="foo" content="Eggs" value="Bar"/>
</item>
</data>
my_val = entity.get_attribute_value("spam")
# returns: "Eggs"

my_val = entity.get_attribute_value("foo", content_keys={'key':'code','content':'value'})
# returns: "Bar"

get_attribute_values(...)​

( key, content_keys = None )​

Retrieve values of all found items below the current base-node. Retrieves data from cache or loads from XML, if not cached yet.

Parameters:key (str)
Key of the desired XML-node whose value should be retrieved.
content_keys (dict[str,str])
Replace attributes in xml-queries with custom attributes. By default, the value is retrieved from the XML-attribute content. This behaviour can be changed by providing a dict that maps the default-attribute to a custom one. For example: {"key":"code","content":"value"} to search for the specified key at attribute code and retrieve the attribute value at value instead of content

Default Keys for node-properties: CONTENT_KEYS
Returns:A list of string values from the content-attribute at all nodes with the specified key.
Return Type:list[str]
Examples:​
<data>
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item key="spam" code="foo" content="Eggs" value="Bar"/>
<item key="spam" code="foo" content="More Eggs" value="Baz"/>
</item>
</data>
my_val = entity.get_attribute_values("spam")
# returns: ["Eggs", "More Eggs"]

my_val = entity.get_attribute_values("foo", content_keys={'key'='foo','content'='value'})
# returns: ["Bar", "Baz]

get_base_attribute_value(...)​

( key )​

Retrieve a value at the base node of the current entity at the attribute of key. Retrieves data from cache or loads from XML, if not cached yet.

Parameters:key (str)
Key of the desired attribute at the base-node.
Returns:A string-value from the current base-node.
Return Type:str
Examples:​
<data>
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item (...)/>
</item>
</data>
my_val = entity.get_base_attribute_value("label")
# returns: "Spam and Eggs"

get_parent_attribute_value(...)​

( key )​

Retrieve a value at the parent-node of the base-node of the current entity at the attribute of key. Retrieves data from cache or loads from XML, if not cached yet.

Parameters:key (str)
Key of the desired attribute at the parent-node.
Returns:A string-value from the parent-node of the current base-node.
Return Type:str
Examples:​
<data>
<item type="parent_node_type" id="parent_string_id" label="Foo Bar">
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item (...)/>
</item>
</item>
</data>
my_val = entity.get_parent_attribute_value("label")
# returns: "Foo Bar"

get_referenced_ids(...)​

( type = None, reference_type = None, content_keys = None, node_conditions = None )​

Retrieve a list of strings that reference to a different node-structure in the XML-data. Custom content-keys can be used used as parameter to override default behaviour. Custom node-conditions can be used as input to override the search below the base-node of the current entity.

Parameters:type (str)
Type of the desired XML-nodes whose id-references should be retrieved. If no node-type is provided, all id-references are returned.
reference_type (str)
Optional query filter for value in attribute reference_type.
content_keys (dict[str,str])
Replace attributes in xml-queries with custom attributes. By default, id-references are retrieved from the XML-attribute idref. This behaviour can be changed by providing a dict that maps the default-attribute to a custom one. For example: {"type":"entity_type","idref":"entity_id_reference"} to search for the specified type at attribute entity_type and retrieve the reference-value at entity_id_reference instead of idref

Default Keys for node-properties: CONTENT_KEYS
node_conditions (dict[str,str])
Change the query conditions for the base node. By default, the current entity's base-node is used. This resets the cached key-values of the entity.
Returns:A list of string-values at the attribute idref (or content_keys["idref]) of nodes with type (or content_keys["type"]) matching the given type (or all nodes) below the base-node.
Return Type:list[str]
Examples:​
<data>
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item type="product" idref="foo"/>
<item type="product" idref="bar"/>
<item type="product" reference_type="cross-selling" idref="abc"/>
<item type="product" reference_type="cross-selling" idref="xyz"/>
</item>
<item type="other_node_type" id="other_string_id" label="Foo Bar">
<item type="sku" idref="123"/>
<item type="sku" idref="456"/>
<item entity_type="sku" entity_id_reference="789"/>
<item entity_type="sku" entity_id_reference="987"/>
</item>

<!-- references lead to these nodes: -->
<item type="product" id="foo">
<item (...)/>
</item>
<item type="product" id="bar">
<item (...)/>
</item>
<item type="product" reference_type="cross-selling" id="abc">
<item (...)/>
</item>
<item type="product" reference_type="cross-selling" id="xyz">
<item (...)/>
</item>
<item type="sku" id="123">
<item (...)/>
</item>
<item type="sku" id="456">
<item (...)/>
</item>
<item entity_type="sku" entity_id="789">
<item (...)/>
</item>
<item entity_type="sku" entity_id="987">
<item (...)/>
</item>
</data>
my_val = entity.get_referenced_ids(type=None)
# returns: ["foo", "bar", "abc", "xyz"]

my_val = entity.get_referenced_ids(type="product", reference_type="cross-selling")
# returns: ["abc", "xyz"]

my_val = entity.get_referenced_ids(type=None, node_conditions={"id":"other_string_id","type":"other_node_type"})
# returns: ["123", "456"]

my_val = entity.get_referenced_ids("sku", content_keys={"key":"entity_type","content":"entity_id_reference"}, node_conditions={"id":"other_string_id","type":"other_node_type"})
# returns: ["789", "987"]

get_references(...)​

( type = None, reference_type = None, content_keys = None, node_conditions = None )​

Same as get_referenced_ids but retrieves a dict with all attributes of nodes, that reference to a different node-structure in the XML-data. For further explanation see documentation of method get_referenced_ids.

Parameters:See documentation of method get_referenced_ids
Returns:A dict of given type as key (or all found types) as key and a list of dicts representing the found nodes as values. Nodes are identified by the attribute idref (or content_keys["idref]) when type (or content_keys["type"]) matches the given type (or all nodes if no type is given) below the base-node.
Return Type:dict[str, list[dict]]
Examples:​
<data>
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item type="sku" idref="123"/>
<item type="sku" idref="456"/>
</item>

<!-- references lead to these nodes: -->
<item type="sku" id="123">
<item (...)/>
</item>
<item type="sku" id="456">
<item (...)/>
</item>
</data>
my_val = entity.get_references("sku")
""" returns:
{"sku":[
{"type":"sku", "idref":"123"},
{"type":"sku", "idref":"456"}
]}
"""

get_reference_parent(...)​

( type = None, reference_type = None, content_keys = None, node_conditions = None )​

Parameters:type (str)
Type of the desired XML-parent-node, where a cild-node references to the current entity (or the entity described in node_conditions). If no node-type is provided, any node that matches the remaining conditions is returned.
reference_type (str)
Optional query filter for value in attribute reference_type.
content_keys (dict[str,str])
incomplete
node_conditions (dict[str,str])
incomplete
Returns:A dict with given type (or any found type) as key and a dict representing the found node as value. The parent node is identified by a child-node with matching attributes idref (or content_keys["idref]) and type (or content_keys["type"]).
Return Type:dict[str, list[dict]]
Examples:​
<data>
<!-- parents of referenced items: -->
<item type="my_node_type" id="my_string_id" label="Spam and Eggs">
<item type="sku" idref="123"/>
<item entity_type="other_type" entity_id_reference="456"/>
</item>
<item type="other_node_type" id="other_string_id" label="Foo Bar">
<item type="sku" idref="foo"/>
<item type="other_type" idref="bar"/>
</item>

<!-- referenced items: -->
<item type="sku" id="123">
<item (...)/>
</item>
<item type="other_type" id="456">
<item (...)/>
</item>
<item type="sku" id="foo">
<item (...)/>
</item>
<item type="other_type" id="bar">
<item (...)/>
</item>
</data>

Assuming that current entity is a referenced item with type="sku" id="123":

my_val = entity.get_reference_parent("my_node_type")
# returns {"my_node_type": {"type":"my_node_type", "id":"my_string_id", "label":"Spam and Eggs"}}

get_comet_pdf_metadata()​

Shortcut for querying for default attribute-keys that can be used for dynamically setting the metadata of the generated PDF based on XML-input. For setting PDF-Metadata see function set_document_metadata of the document-library.

Default Attribute-Keys for dynamic Metadata-Information: METADATA_KEYS

Returns:All found values of the default Metadata-keys as a dictionary or empty dictionary, if no values are found. Values are typed for correct use in function set_document_metadata of the document-library
Return Type:dict[str, str|int|list]

Examples:​

<data>
<item type="my_node_type" id="my_string_id">
<item key="kTitle" content="My Title"/>
<item key="kDescription" content="My Description"/>
<item key="kAuthor" content="My Author"/>
<item key="kAuthorTitle" content="My AuthorTitle"/>
<item key="kAuthorDescription" content="My AuthorDescription"/>
<item key="kKeys" content="My Keyword 1"/>
<item key="kKeys" content="My Keyword 2"/>
<item key="kCopyRight" content="My CopyRight"/>
<item key="kCopyRightURL" content="My CopyRightURL"/>
<item key="kCopyRightState" content="1"/>
<item key="kRating" content="5"/>

<item key="custom_title" content="My CUSTOM Title">
</item>
</data>
my_value = entity.get_comet_pdf_metadata()
"""returns:
{
"kTitle": "My Title",
"kDescription": "My Description",
"kAuthor": "My Author",
"kAuthorTitle": "My AuthorTitle",
"kAuthorDescription": "My AuthorDescription",
"kKeys": ["My Keyword 1", "My Keyword 2"],
"kCopyRight": "My CopyRight",
"kCopyRightURL": "My CopyRightURL",
"kCopyRightState": 1,
"kRating": 5
}"""

my_value = entity.get_comet_pdf_metadata({"kTitle":"custom_title"})
"""returns:
{
"kTitle": "My CUSTOM Title",
"kDescription": "My Description",
"kAuthor": "My Author",
"kAuthorTitle": "My AuthorTitle",
"kAuthorDescription": "My AuthorDescription",
"kKeys": ["My Keyword 1", "My Keyword 2"],
"kCopyRight": "My CopyRight",
"kCopyRightURL": "My CopyRightURL",
"kCopyRightState": 1,
"kRating": 5
}"""