linkahead.common.models module

Collection of the central classes of the LinkAhead client, namely the Entity class and all of its subclasses and the Container class which is used to carry out transactions.

All additional classes are either important for the entities or the transactions.

class linkahead.common.models.ACI(realm: str | None, username: str | None, role: str | None, permission: str | None)

Bases: object

FIXME: Add docstring

add_to_element(e: _Element)
class linkahead.common.models.ACL(xml: _Element | None = None)

Bases: object

FIXME: Add docstring

clear()
combine(other: ACL) ACL

Combine and return new instance.

deny(username: str | None = None, realm: str | None = None, role: str | None = None, permission: str | None = None, priority: bool = False, revoke_grant: bool = True)

Deny a permission to a user or role for this entity.

You must specify either only the username and the realm, or only the role.

By default a previously existing grant rule would be revoked, because otherwise this denial would override the grant rules anyways. However, for keeping contradicting rules pass revoke_grant=False.

Parameters:
  • permission (str) – The permission to be denied.

  • username (str, optional) – The username. Exactly one is required, either the username or the role.

  • realm (str, optional) – The user’s realm. Required when username is not None.

  • role (str, optional) – The role (as in Role-Based Access Control). Exactly one is required, either the username or the role.

  • priority (bool, default False) – Whether this permission is denied with priority over non-priority rules.

  • revoke_grant (bool, default True) – Whether a contradicting grant (with same priority flag) in this ACL will be revoked.

get_acl_for_role(role: str) ACL
get_acl_for_user(username: str, realm: str | None = None)
get_permissions_for_role(role: str)
get_permissions_for_user(username: str, realm: str | None = None)
global_acl: ACL | None = None
grant(permission: str | None, username: str | None = None, realm: str | None = None, role: str | None = None, priority: bool = False, revoke_denial: bool = True)

Grant a permission to a user or role.

You must specify either only the username and the realm, or only the role.

By default a previously existing denial rule would be revoked, because otherwise this grant wouldn’t have any effect. However, for keeping contradicting rules pass revoke_denial=False.

Parameters:
  • permission (str) – The permission to be granted.

  • username (str, optional) – The username. Exactly one is required, either the username or the role.

  • realm (str, optional) – The user’s realm. Required when username is not None.

  • role (str, optional) – The role (as in Role-Based Access Control). Exactly one is required, either the username or the role.

  • priority (bool, default False) – Whether this permission is granted with priority over non-priority rules.

  • revoke_denial (bool, default True) – Whether a contradicting denial (with same priority flag) in this ACL will be revoked.

is_empty()
is_permitted(role, permission)
parse_xml(xml: _Element)

Clear this ACL and parse the xml.

Iterate over the rules in the xml and add each rule to this ACL.

Contradicting rules will both be kept.

Parameters:

xml (lxml.etree._Element) – The xml element containing the ACL rules, i.e. <Grant> and <Deny> rules.

revoke_denial(username: str | None = None, realm: str | None = None, role: str | None = None, permission: str | None = None, priority: bool = False)
revoke_grant(username: str | None = None, realm: str | None = None, role: str | None = None, permission: str | None = None, priority: bool | str = False)
to_xml(xml: _Element | None = None)
class linkahead.common.models.Container

Bases: list

Container is a type safe list for Entities.

It also provides several short-cuts for transactions like retrieval, insertion, update, and deletion which are a applied to all entities in the container or the whole container respectively.

add_message(m)
append(entity)

Append an entity container.

If the parameter is an integer an entity with the corresponding ID is appended. If the parameter is a string an entity with the corresponding name is appended. Raise a TypeError if the entity is not a sub type of the correct class (as defined via the constructor).

@param entity: The entity to be appended.

clear_server_messages()
delete(raise_exception_on_error: bool = True, flags: QueryDict | None = None, chunk_size: int = 100)

Delete all entities in this container.

Entities are identified via their id if present and via their name otherwise. If any entity has no id and no name a TransactionError will be raised.

Note: If only a name is given this could lead to ambiguities. If this happens, none of them will be deleted. An error is raised instead.

extend(entities)

Extend this Container by appending all single entities in the given list of entities.

@param entities: list of entities.

static from_xml(xml_str)

Creates a Container from the given xml string.

@return The created Container.

get_all_errors()

Returns a dictionary with all errors from all entities in this container.

The dictionary keys are the ids of those entities having contained an error.

get_all_messages()
get_entity_by_id(id: int | str) Entity

Get the first entity which has the given id. Note: If several entities are in this list which have the same id, this method will only return the first and ignore the others.

@param name: The id of the entity to be returned. @return: Entity with the given id.

get_entity_by_name(name: str, case_sensitive: bool = True) Entity

Get the first entity which has the given name. Note: If several entities are in this list which have the same name, this method will only return the first and ignore the others.

@param name: the name of the entity to be returned. @param case_sensitive (True/False): Do a case-sensitive search for name (or not). @return: Entity with the given name.

get_errors()

Get all error messages of this container.

@return Messages: Error messages.

get_property_values(*selectors: str | tuple[str]) list[tuple[str]]

Return a list of tuples with values of the given selectors.

I.e. a tabular representation of the container’s content.

If the elements of the selectors parameter are tuples, they will return the properties of the referenced entity, if present. E.g. (“window”, “height”) will return the value of the height property of the referenced window entity.

All tuples of the returned list have the same length as the selectors parameter and the ordering of the tuple’s values correspond to the order of the parameter as well.

The tuple contains None for all values that are not available in the entity. That does not necessarily mean, that the values are not stored in the database (e.g. if a single entity was retrieved without referenced entities).

Parameters:

*selectors (str or tuple of str) – Each selector is a list or tuple of property names, e.g. “height”, “width”.

Returns:

table – A tabular representation of the container’s content.

Return type:

list of tuples

get_warnings()

Get all warning messages of this container.

@return Messages: Warning messages.

has_errors()

@return True: if and only if this container has any error messages.

has_warnings()

@return True: if and only if this container has any warning messages.

insert(strict: bool = False, raise_exception_on_error: bool = True, unique: bool = True, sync: bool = True, flags: QueryDict | None = None)

Insert this file entity into LinkAhead. A successful insertion will generate a new persistent ID for this entity. This entity can be identified, retrieved, updated, and deleted via this ID until it has been deleted.

If the insertion fails, a LinkAheadException will be raised. The server will have returned at least one error-message describing the reason why it failed in that case (call <this_entity>.get_all_messages() in order to get these error-messages).

Some insertions might cause warning-messages on the server-side, but the entities are inserted anyway. Set the flag ‘strict’ to True in order to force the server to take all warnings as errors. This prevents the server from inserting this entity if any warning occurs.

Parameters:
  • strict (bool, optional) – Flag for strict mode. Default is False.

  • sync (bool, optional) – synchronize this container with the response from the server. Otherwise, this method returns a new container with the inserted entities and leaves this container untouched. Default is True.

  • unique (bool, optional) – Flag for unique mode. If set to True, the server will check if the name of the entity is unique. If not, the server will return an error. Default is True.

  • flags (dict, optional) – Additional flags for the server. Default is None.

is_valid()
remove(entity: Entity)

Remove the first entity from this container which is equal to the given entity. Raise a ValueError if there is no such entity.

Alternatively, if the argument is not an entity but an ID, the contained entity with this ID is removed.

@param entity: The entity to be removed.

retrieve(query: str | list | None = None, unique: bool = True, raise_exception_on_error: bool = True, sync: bool = True, flags: QueryDict | None = None)

Retrieve all entities in this container identified via their id if present and via their name otherwise. Any locally already existing attributes (name, description, …) will be preserved. Any such properties and parents will be synchronized as well. They will not be overridden. This method returns a Container containing the this entity.

If any entity has no id and no name a LinkAheadException will be raised.

Note: If only a name is given this could lead to ambiguities. All entities with the name in question will be returned. Therefore, the container could contain more elements after the retrieval than before.

to_xml(add_to_element: _Element | None = None, local_serialization: bool = False) _Element

Get an xml tree representing this Container or append all entities to the given xml element.

Parameters:

add_to_element (etree._Element, optional) – optional element to which all entities of this container is to be appended. Default is None

Returns:

xml_element

Return type:

etree._Element

update(strict: bool = False, raise_exception_on_error: bool = True, unique: bool = True, sync: bool = True, flags: dict[str, Any] | None = None)

Update these entites.

class linkahead.common.models.DropOffBox(*args, **kwargs)

Bases: list

path = None
sync()
class linkahead.common.models.Entity(name: str | None = None, id: int | None = None, description: str | None = None, datatype: DATATYPE | None = None, value=None, role=None)

Bases: object

Entity is a generic LinkAhead object.

The majority of all methods of the derived classes (e.g. Record, RecordType, Property …) are defined here, e.g. add_property, add_parent, retrieve … Each entity may have some attributes (id, name, description, …), a set of properties, a set of parent entities and a set of messages which are generated through the processing in the client library or the server, or which can be used by the user to control several server-side plug-ins.

add_message(msg=None, type=None, code=None, description=None, body=None)

Add a message (msg) to this entity. If and only if no msg is given this method will created a new message from the parameters type, code, description, and body.

@param msg: The message to be added to this entity. @param type: The type of the message to be added. @param code: The code of the message to be added. @param description: The description of the message to be added. @param body: The body of the message to be added.

add_parent(parent: Entity | int | str | None = None, id: int | None = None, name: str | None = None, inheritance: INHERITANCE = 'NONE')

Add a parent to this entity.

Parameters:
  • parent (Entity or int or str or None) – The parent entity, either specified by the Entity object itself, or its id or its name. Default is None.

  • id (int) – Integer id of the parent entity. Ignored if parent is not None.

  • name (str) – Name of the parent entity. Ignored if parent is not none.

  • inheritance (str, INHERITANCE) – One of obligatory, recommended, suggested, or all. Specifies the minimum importance which parent properties need to have to be inherited by this entity. If no inheritance is given, no properties will be inherited by the child. This parameter is case-insensitive.

Notes

Note that the behaviour of the inheritance argument currently has not yet been specified when assigning parents to Records, it only works for inheritance of RecordTypes (and Properties). For more information, it is recommended to look into the data insertion tutorial.

Raises:

UserWarning – If neither a parent parameter, nor the id, nor name parameter is passed to this method.

add_property(property: int | str | Entity | None = None, value: int | str | bool | datetime | Entity | list[int] | list[str] | list[bool] | list[Entity] | None = None, id: int | None = None, name: str | None = None, description: str | None = None, datatype: DATATYPE | None = None, unit: str | None = None, importance: IMPORTANCE | None = None, inheritance: INHERITANCE | None = None) Entity

Add a property to this entity.

The first parameter is meant to identify the property entity either via its id or name, or by providing the corresponding Entity Python object. The second parameter is the value of the new property. Any other named parameter may be passed by means of the keywwords. Accepted keywords are: id, name, description, importance, inheritance, datatype, and unit.

Notes

If you want to add a property to an already existing entity, the property id of that property needs to be specified before you send the updated entity to the server.

Parameters:
  • property (int, str, Entity, optional) – An identifier for the property to be added, either its name, its id, or the corresponding Entity Python object. If None, either the name or the id argument have to be specified explicitly. Default is None.

  • value (int, str, bool, datetime, Entity, or list of these types, optional) – The value of the new property. In case of a reference to another entity, this value may be the referenced entities id or the Entity as a Python object. Default is None.

  • id (int, optional) – Id of the property, by default None

  • name (str, optional) – Name of the property, by default None

  • description (str, optional) – Description of the property, by default None

  • datatype (str, optional) – Datatype of the property, by default None

  • unit (str, optional) – Unit of the property, by default None

  • importance (str, optional) – Importance of the property, by default None

  • inheritance (str, optional) – Inheritance of the property, by default None

Returns:

This Entity object to which the new property has been added.

Return type:

Entity

Warns:
  • UserWarning – If the first parameter is None then id or name must be defined and not be None.

  • UserWarning – If the first parameter is an integer then it is interpreted as the id and id must be undefined or None.

  • UserWarning – If the first parameter is not None and neither an instance of Entity nor an integer it is interpreted as the name and name must be undefined or None.

Raises:

ValueError: – If you try to add an Entity object with File or Record role (or, equivalently, a File or Record object) as a property, a ValueError is raised.

Examples

Add a simple integer property with the name TestProp and the value 27 to a Record:

>>> import linkahead as db
>>> rec = db.Record(name="TestRec").add_parent(name="TestType")
>>> rec.add_property("TestProp", value=27)  # specified by name, you could equally use the
>>>                                         # property's id if it is known

You can also use the Python object:

>>> prop = db.Property(name="TestProp", datatype=db.INTEGER)
>>> rec.add_property(prop, value=27)  # specified via the Python object

In case of updating an existing Record, the Property needs to be specified by id:

>>> rec = db.Record(name="TestRec").retrieve()
>>> prop2 = db.Property(name="OtherTestProp").retrieve()
>>> rec.add_property(id=prop2.id, value="My new value")
>>> rec.update()

Let’s look at the more advanced example of adding a list of integers as value of the above integer TestProp:

>>> rec.add_property("TestProp", value=[27,28,29], datatype=db.LIST(db.INTEGER))

Note that since TestProp is a scalar integer Property, the datatype LIST<INTEGER> has to be specified explicitly.

Finally, we can also add reference properties, specified by the RecordType of the referenced entity.

>>> ref_rec = db.Record(name="ReferencedRecord").add_parent(name="OtherRT")
>>> rec.add_property(name="OtherRT", value=ref_rec)  # or value=ref_rec.id if ref_rec has
>>>                                                  # one set by the server

See more on adding properties and inserting data in https://docs.indiscale.com/caosdb-pylib/tutorials/Data-Insertion.html.

property checksum
clear_server_messages()
copy() Entity

Return a copy of entity.

FIXME: This method doesn’t have a deep keyword argument. If deep == True return a deep copy, recursively copying all sub entities.

Standard properties are copied using add_property. Special attributes, as defined by the global variable SPECIAL_ATTRIBUTES and additionaly the “value” are copied using setattr.

property datatype
delete(raise_exception_on_error=True)
deny(realm: str | None = None, username: str | None = None, role: str | None = None, permission: str | None = None, priority: bool = False, revoke_grant: bool = True)

Deny a permission to a user or role for this entity.

You must specify either only the username and the realm, or only the role.

By default a previously existing grant rule would be revoked, because otherwise this denial would override the grant rules anyways. However, for keeping contradicting rules pass revoke_grant=False.

Parameters:
  • permission (str) – The permission to be denied.

  • username (str, optional) – The username. Exactly one is required, either the username or the role.

  • realm (str, optional) – The user’s realm. Required when username is not None.

  • role (str, optional) – The role (as in Role-Based Access Control). Exactly one is required, either the username or the role.

  • priority (bool, default False) – Whether this permission is denied with priority over non-priority rules.

  • revoke_grant (bool, default True) – Whether a contradicting grant (with same priority flag) in this ACL will be revoked.

property description
property file
get_all_messages() Messages
get_errors()

Get all error messages of this entity.

@return Messages(list): Error messages.

get_errors_deep(roots=None) list[tuple[str, list[Entity]]]

Get all error messages of this entity and all sub-entities / parents / properties.

@return A list of tuples. Tuple index 0 contains the error message

and tuple index 1 contains the tree.

get_importance(property)

Get the importance of a given property regarding this entity.

get_messages()

Get all messages of this entity.

@return: Messages(list)

get_parent(key: int | Entity | str) Entity | None

Return the first parent matching the key or None if no match exists.

Parameters:

key (int or Enity or str) – The id, Entity, or name of the parent that should be returned. If an Entity is given, its id or its name is used to find a matching parent.

Returns:

parent – The first parent of this entity that matches the given id, entity, or name.

Return type:

Entity

get_parents()

Get all parents of this entity.

@return: ParentList(list)

get_parents_recursively(retrieve: bool = True) list[Entity]

Get all ancestors of this entity.

Parameters:

retrieve (bool, optional) – If False, do not retrieve parents from the server.

Returns:

out – The parents of this Entity

Return type:

list[Entity]

get_properties()

Get all properties of this entity.

@return: PropertyList(list)

get_property(pattern: int | str | Entity) Property | None

Return the first matching property or None.

Parameters:

pattern (str or int or Entity) – The name or id to look for (case-insensitive) or an Entity where the name or id is used to match the properites of this instance.

Returns:

property – The first Property of this Entity with a matching name or id.

Return type:

Property

get_property_values(*selectors)

Return a tuple with the values described by the given selectors.

This represents an entity’s properties as if it was a row of a table with the given columns.

If the elements of the selectors parameter are tuples, they will return the properties of the referenced entity, if present. E.g. (“window”, “height”) will return the value of the height property of the referenced window entity.

The tuple’s values correspond to the order of selectors parameter.

The tuple contains None for all values that are not available in the entity. That does not necessarily mean, that the values are not stored in the database (e.g. if a single entity was retrieved without referenced entities).

Parameters:

*selectors (str or tuple of str) – Each selector is a list or tuple of property names, e.g. “height”, “width”.

Returns:

row – A row-like representation of the entity’s properties.

Return type:

tuple

get_warnings()

Get all warning messages of this entity.

@return Messages(list): Warning messages.

grant(realm: str | None = None, username: str | None = None, role: str | None = None, permission: str | None = None, priority: bool = False, revoke_denial: bool = True)

Grant a permission to a user or role for this entity.

You must specify either only the username and the realm, or only the role.

By default a previously existing denial rule would be revoked, because otherwise this grant wouldn’t have any effect. However, for keeping contradicting rules pass revoke_denial=False.

Parameters:
  • permission (str) – The permission to be granted.

  • username (str, optional) – The username. Exactly one is required, either the username or the role.

  • realm (str, optional) – The user’s realm. Required when username is not None.

  • role (str, optional) – The role (as in Role-Based Access Control). Exactly one is required, either the username or the role.

  • priority (bool, default False) – Whether this permission is granted with priority over non-priority rules.

  • revoke_denial (bool, default True) – Whether a contradicting denial (with same priority flag) in this ACL will be revoked.

has_errors()

@return True: if and only if this entities has any error messages.

has_parent(parent: Entity, recursive: bool = True, retrieve: bool = True, check_name: bool = True, check_id: bool = False)

Check if this entity has a given parent.

If ‘check_name’ and ‘check_id’ are both False, test for identity on the Python level. Otherwise use the name and/or ID for the check. Note that, if checked, name or ID should not be None, lest the check fail.

Parameters:
  • parent (Entity) – Check for this parent.

  • recursive (bool, optional) – Whether to check recursively.

  • check_name (bool, optional) – Whether to use the name for ancestry check.

  • check_id (bool, optional) – Whether to use the ID for ancestry check.

  • retrieve (bool, optional) – If False, do not retrieve parents from the server.

Returns:

out – True if parent is a true parent, False otherwise.

Return type:

bool

property id: Any
insert(raise_exception_on_error=True, unique=True, sync=True, strict=False, flags: dict | None = None)

Insert this entity into a LinkAhead server. A successful insertion will generate a new persistent ID for this entity. This entity can be identified, retrieved, updated, and deleted via this ID until it has been deleted.

If the insertion fails, a LinkAheadException will be raised. The server will have returned at least one error-message describing the reason why it failed in that case (call <this_entity>.get_all_messages() in order to get these error-messages).

Some insertions might cause warning-messages on the server-side, but the entities are inserted anyway. Set the flag ‘strict’ to True in order to force the server to take all warnings as errors. This prevents the server from inserting this entity if any warning occurs.

Parameters:
  • strict (bool, optional) – Flag for strict mode. Default is False.

  • raise_exception_on_error (bool, optional) – Flag to raise an exception when an error occurs. Default is True.

  • unique (bool, optional) – Flag to only allow insertion of elements with unique names. Default is True.

  • flags (dict, optional) – A dictionary of flags to be send with the insertion. Default is None.

is_permitted(permission: Permission, role: str | None = None)
property name
property path
property pickup
remove_parent(parent)
remove_property(property)
remove_value_from_property(property_name: str, value: Any, remove_if_empty_afterwards: bool | None = True)

Remove a value from a property given by name.

Do nothing if this entity does not have a property of this property_name or if the property value is different of the given value. By default, the property is removed from this entity if it becomes empty (i.e., value=None) through removal of the value. This behavior can be changed by setting remove_if_empty_afterwards to False in which case the property remains.

Notes

If the property value is a list and the value to be removed occurs more than once in this list, only its first occurrance is deleted (similar to the behavior of Python’s list.remove().)

If the property was empty (prop.value == None) before, the property is not removed afterwards even if remove_if_empty_afterwards is set to True. Rationale: the property being empty is not an effect of calling this function.

Parameters:
  • property_name (str) – Name of the property from which the value will be removed.

  • value – Value that is to be removed.

  • remove_if_empty_afterwards (bool, optional) – Whether the property shall be removed from this entity if it is emptied by removing the value. Default is True.

Returns:

This entity.

Return type:

self

retrieve(unique=True, raise_exception_on_error=True, flags=None)

Retrieve this entity identified via its id if present and via its name otherwise. Any locally already existing attributes (name, description, …) will be preserved. Any such properties and parents will be synchronized as well. They will not be overridden. This method returns a Container containing the this entity.

Note: If only a name is given this could lead to ambiguities. Usually this would raise a LinkAheadException. Set the flag ‘unique’ to False if this Exception should be suppressed. If unique is False this method returns a Container object which carries the returned entities. They are distinct from this one. This entity will no be changed somehow.

@param unique=True: flag to suppress the ambiguity exception.

@return Container with the returned entities or single entity if and only if unique was True and no exception was raised.

retrieve_acl()
revoke_denial(realm=None, username=None, role=None, permission=None, priority=False)
revoke_grant(realm=None, username=None, role=None, permission=None, priority=False)
property role
set_flag(key, value=None)
property size
property thumbnail
to_xml(xml: etree._Element | None = None, add_properties: INHERITANCE = 'ALL', local_serialization: bool = False) etree._Element

Generate an xml representation of this entity. If the parameter xml is given, all attributes, parents, properties, and messages of this entity will be added to it instead of creating a new element.

Raise an error if xml is not a lxml.etree.Element

@param xml: an xml element to which all attributes, parents,

properties, and messages are to be added.

FIXME: Add documentation for the add_properties parameter. FIXME: Add docuemntation for the local_serialization parameter.

@return: xml representation of this entity.

property unit
update(strict=False, raise_exception_on_error=True, unique=True, flags=None, sync=True)

Update this entity.

There are two possible work-flows to perform this update: First:

  1. retrieve an entity

  2. do changes

  3. call update method

Second:
  1. construct entity with id

  2. call update method.

For slight changes the second one it is more comfortable. Furthermore, it is possible to stay off-line until calling the update method. The name, description, unit, datatype, path, and value of an entity may be changed. Additionally, properties, parents and messages may be added.

However, the first one is more powerful: It is possible to delete and change properties, parents and attributes, which is not possible via the second one for internal reasons (which are reasons of definiteness).

If the update fails, a LinkAheadException will be raised. The server will have returned at least one error message describing the reason why it failed in that case (call <this_entity>.get_all_messages() in order to get these error-messages).

Some updates might cause warning messages on the server-side, but the updates are performed anyway. Set flag ‘strict’ to True in order to force the server to take all warnings as errors. This prevents the server from updating this entity if any warnings occur.

@param strict=False: Flag for strict mode.

update_acl(**kwargs)

Update this entity’s ACL on the server.

A typical workflow is to first edit self.acl and then call this method.

Note

This overwrites any existing ACL, so you may want to run retrieve_acl before updating the ACL in this entity.

Parameters:

**kwargs (dict) – Keyword arguments that are passed through to the Entity.update method. Useful for e.g. unique=False in the case of naming collisions.

Returns:

e – This entity after the update of the ACL.

Return type:

Entity

property value
property version
class linkahead.common.models.File(name: str | None = None, id: int | None = None, description: str | None = None, path: str | None = None, file: str | TextIO | None = None, pickup: str | None = None, thumbnail: str | None = None, from_location=None)

Bases: Record

This class represents LinkAhead’s file entities.

For inserting a new file to the server, path gives the new location, and (exactly?) one of file and pickup should (must?) be given to specify the source of the file.

Symlinking from the “extroot” file system is not supported by this API yet, it can be done manually using the InsertFilesInDir flag. For sample code, look at test_files.py in the Python integration tests of the load_files.py script in the advanced user tools.

@param name: A name for this file record (That’s an entity name - not to be

confused with the last segment of the files path).

@param id: An ID. @param description: A description for this file record. @param path: The complete path, including the file name, of the file in the

server’s “caosroot” file system.

@param file: A local path or python file object. The file designated by

this argument will be uploaded to the server via HTTP.

@param pickup: A file/folder in the DropOffBox (the server will move that

file into its “caosroot” file system).

@param thumbnail: (Local) filename to a thumbnail for this file. @param properties: A list of properties for this file record. @todo is this

implemented?

@param from_location: Deprecated, use pickup instead.

add_property(property=None, id=None, name=None, description=None, datatype=None, value=None, unit=None, importance='FIX', inheritance='FIX')

See Entity.add_property.

download(target: str | None = None) str

Download this file-entity’s actual file from the file server. It will be stored to the target or will be hold as a temporary file.

@param target: Where to store this file. @return: local path of the downloaded file.

static download_from_path(target_file: BufferedWriter | _TemporaryFileWrapper, path: str)
to_xml(xml: etree._Element | None = None, add_properties: INHERITANCE = 'ALL', local_serialization: bool = False) etree._Element

Convert this file to an xml element.

@return: xml element

class linkahead.common.models.Info

Bases: object

Info about the LinkAhead instance that you are connected to. It has a simple string representation in the form of “Connected to a LinkAhead with N Records”.

messages

Collection of messages that the server’s Info response contained.

Type:

Messages

user_info

Information about the user that is connected to the server, such as name, realm or roles.

Type:

UserInfo

time_zone

The timezone information returned by the server.

Type:

TimeZone

sync()

Retrieve server information from the server’s Info response.

class linkahead.common.models.Message(type: str | None = None, code: int | None = None, description: str | None = None, body: str | _Attrib | None = None)

Bases: object

get_code() int | None
to_xml(xml: _Element | None = None) _Element
class linkahead.common.models.Messages(iterable=(), /)

Bases: list

This specialization of list stores error, warning, info, and other messages. The mentioned three messages types play a special role. They are generated by the client and the server while processing the entity to which the message in question belongs. It is RECOMMENDED NOT to specify such messages manually. The other messages are ignored by the server unless there is a plug-in which interprets them.

Any message MUST have a type. It MAY have a code (an integer), a description (short string), or a body (longer string):

<$Type code=$code description=$description>$body</$Type>

Error, warning, and info messages will be deleted before any transaction.

Examples: <<< msgs = Messages()

<<< # create Message <<< msg = Message(type=”HelloWorld”, code=1, description=”Greeting the world”, … body=”Hello, world!”)

<<< # append it to the Messages <<< msgs.append(msg)

<<< # use Messages as list of Message objects <<< for m in msgs: … assert isinstance(m,Message)

<<< # remove it <<< msgs.remove(msg)

<<< # ok append it again … <<< msgs.append(msg) <<< # get it back via get(…) and the key tuple (type, code) <<< assert id(msgs.get(“HelloWorld”,1))==id(msg)

append(msg)

Append object to the end of the list.

clear_server_messages()

Removes all messages of type error, warning and info. All other messages types are custom types which should be handled by custom code.

get(type, code=None, default=None, exact=False)

returns a message from the list that kind of matches type and code

case and types (str/int) are ignored

If no suitable message is found, the default argument is returned If exact=True, the message has to match code and type exactly

remove(obj, obj2=None)

Remove first occurrence of value.

Raises ValueError if the value is not present.

to_xml(add_to_element: _Element)
class linkahead.common.models.Parent(id: int | None = None, name: str | None = None, description: str | None = None, inheritance: INHERITANCE | None = None)

Bases: Entity

The parent entities.

property affiliation
to_xml(xml: etree._Element | None = None, add_properties: INHERITANCE = 'NONE', local_serialization: bool = False)

Generate an xml representation of this entity. If the parameter xml is given, all attributes, parents, properties, and messages of this entity will be added to it instead of creating a new element.

Raise an error if xml is not a lxml.etree.Element

@param xml: an xml element to which all attributes, parents,

properties, and messages are to be added.

FIXME: Add documentation for the add_properties parameter. FIXME: Add docuemntation for the local_serialization parameter.

@return: xml representation of this entity.

class linkahead.common.models.ParentList(*args, **kwargs)

Bases: list

append(parent)

Append object to the end of the list.

extend(parents)

Extend list by appending elements from the iterable.

filter(parent: Parent | None = None, pid: str | int | None = None, name: str | None = None, conjunction: bool = False) list

Return all Parents from the given ParentList that match the selection criteria.

Please refer to the documentation of _filter_entity_list for a detailed description of behaviour.

Params

listobjectIterable(Parent)

List to be filtered

parentParent

Parent to match name and ID with. Cannot be set

pidstr, int

Parent ID to match

namestr

Parent name to match simultaneously with ID or name.

conjunctionbool, defaults to False

Set to return only entities that match both id and name if both are given.

returns:

matches – List containing all matching Parents

rtype:

list

remove(parent: Entity | int | str)

Remove first occurrence of parent.

Parameters:
  • parent (Union[Entity, int, str], the parent to be removed identified via ID or name. If a)

  • be (Parent object is provided the ID and then the name is used to identify the parent to)

  • removed.

Return type:

None

to_xml(add_to_element: _Element)
class linkahead.common.models.Permission(name: str, description: str | None = None)

Bases: object

class linkahead.common.models.Permissions(xml: _Element)

Bases: object

clear()
known_permissions: Permissions | None = None
parse_xml(xml: _Element)
class linkahead.common.models.Property(name: str | None = None, id: int | None = None, description: str | None = None, datatype: DATATYPE | None = None, value=None, unit: str | None = None)

Bases: Entity

LinkAhead’s Property object.

add_parent(parent=None, id=None, name=None, inheritance='FIX')

Add a parent Entity to this Property.

Parameters:
  • parent (Entity or int or str or None) – The parent entity, either specified by the Entity object itself, or its id or its name. Default is None.

  • id (int) – Integer id of the parent entity. Ignored if parent is not None.

  • name (str) – Name of the parent entity. Ignored if parent is not none.

  • inheritance (str, default: FIX) – One of obligatory, recommended, suggested, or fix. Specifies the minimum importance which parent properties need to have to be inherited by this entity. If no inheritance is given, no properties will be inherited by the child. This parameter is case-insensitive.

add_property(property=None, value=None, id=None, name=None, description=None, datatype=None, unit=None, importance='FIX', inheritance='FIX')

See Entity.add_property.

is_reference(server_retrieval: bool = False) bool | None

Returns whether this Property is a reference

Parameters:

server_retrieval (bool, optional) – If True and the datatype is not set, the Property is retrieved from the server, by default False

Returns:

Returns whether this Property is a reference or None if a server call is needed to check correctly, but server_retrieval is set to False.

Return type:

bool, NoneType

to_xml(xml: etree._Element | None = None, add_properties: INHERITANCE = 'ALL', local_serialization: bool = False)

Generate an xml representation of this entity. If the parameter xml is given, all attributes, parents, properties, and messages of this entity will be added to it instead of creating a new element.

Raise an error if xml is not a lxml.etree.Element

@param xml: an xml element to which all attributes, parents,

properties, and messages are to be added.

FIXME: Add documentation for the add_properties parameter. FIXME: Add docuemntation for the local_serialization parameter.

@return: xml representation of this entity.

class linkahead.common.models.PropertyList

Bases: list

A list class for Property objects

This class provides addional functionality like get/set_importance or get_by_name.

append(property: list[Entity] | Entity | Property, importance: IMPORTANCE | None = None, inheritance: INHERITANCE | None = None)

Append object to the end of the list.

extend(parents)

Extend list by appending elements from the iterable.

filter(prop: Property | None = None, pid: str | int | None = None, name: str | None = None, conjunction: bool = False) list

Return all Properties from the given PropertyList that match the selection criteria.

Please refer to the documentation of _filter_entity_list for a detailed description of behaviour.

Params

listobjectIterable(Property)

List to be filtered

propProperty

Property to match name and ID with. Cannot be set simultaneously with ID or name.

pidstr, int

Property ID to match

namestr

Property name to match

conjunctionbool, defaults to False

Set to return only entities that match both id and name if both are given.

returns:

matches – List containing all matching Properties

rtype:

list

get_by_name(name: str) Entity

Get a property of this list via it’s name. Raises a LinkAheadException if not exactly one property has this name.

@param name: the name of the property to be returned. @return: A property

get_importance(property: Property | Entity | str | None)
remove(prop: Entity | int)

Remove first occurrence of value.

Raises ValueError if the value is not present.

set_importance(property: Property | None, importance: IMPORTANCE)
to_xml(add_to_element: etree._Element, add_properties: INHERITANCE)
class linkahead.common.models.Query(q: str | _Element)

Bases: object

q

The query string, may also be a query XML snippet.

Type:

str, etree._Element

flags

A dictionary of flags to be send with the query request.

Type:

dict of str

messages

A container of messages included in the last query response.

Type:

Messages()

cached

indicates whether the server used the query cache for the execution of this query.

Type:

bool

results

The number of results (when this was a count query) or the container with the resulting entities.

Type:

int or Container

execute(unique: bool = False, raise_exception_on_error: bool = True, cache: bool = True, page_length: int | None = None) Container | int

Execute a query (via a server-requests) and return the results.

Parameters:
  • unique (bool) – Whether the query is expected to have only one entity as result. Defaults to False.

  • raise_exception_on_error (bool) – Whether an exception should be raises when there are errors in the resulting entities. Defaults to True.

  • cache (bool) – Whether to use the server-side query cache (equivalent to adding a “cache” flag) to the Query object. Defaults to True.

  • page_length (int) – Whether to use paging. If page_length > 0 this method returns a generator (to be used in a for-loop or with list-comprehension). The generator yields containers with up to page_length entities. Otherwise, paging is disabled, as well as for count queries and when unique is True. Defaults to None.

  • Raises

  • -------

  • PagingConsistencyError – If the database state changed between paged requests.

Yields:

page (Container) – Returns a container with the next page_length resulting entities.

Returns:

results – Returns an integer when it was a COUNT query. Otherwise, returns a Container with the resulting entities.

Return type:

Container or integer

getFlag(key)
putFlag(key: str, value: str | None = None)
removeFlag(key)
class linkahead.common.models.QueryTemplate(id: int | None = None, name: str | None = None, query: str | None = None, description: str | None = None)

Bases: object

clear_server_messages()
delete(raise_exception_on_error=True)
get_errors()
get_messages()
get_parents()
get_properties()
has_errors()
has_id()
insert(strict: bool = True, raise_exception_on_error: bool = True, unique: bool = True, sync: bool = True, flags: QueryDict | None = None) Container
retrieve(raise_exception_on_error: bool = True, unique: bool = True, sync: bool = True, flags: QueryDict | None = None) Container
to_xml(xml: _Element | None = None) _Element
update(strict: bool = True, raise_exception_on_error: bool = True, unique: bool = True, sync: bool = True, flags: QueryDict | None = None) Container
class linkahead.common.models.Record(name: str | None = None, id: int | None = None, description: str | None = None)

Bases: Entity

This class represents LinkAhead’s Record entities.

add_property(property=None, value=None, id=None, name=None, description=None, datatype=None, unit=None, importance='FIX', inheritance='FIX')

See Entity.add_property.

to_xml(xml: etree._Element | None = None, add_properties: INHERITANCE = 'ALL', local_serialization: bool = False)

Generate an xml representation of this entity. If the parameter xml is given, all attributes, parents, properties, and messages of this entity will be added to it instead of creating a new element.

Raise an error if xml is not a lxml.etree.Element

@param xml: an xml element to which all attributes, parents,

properties, and messages are to be added.

FIXME: Add documentation for the add_properties parameter. FIXME: Add docuemntation for the local_serialization parameter.

@return: xml representation of this entity.

class linkahead.common.models.RecordType(name: str | None = None, id: int | None = None, description: str | None = None, datatype: DATATYPE | None = None)

Bases: Entity

This class represents LinkAhead’s RecordType entities.

add_parent(parent: Entity | int | str | None = None, id: int | None = None, name: str | None = None, inheritance: INHERITANCE = 'OBLIGATORY')

Add a parent to this RecordType

Parameters:
  • parent (Entity or int or str or None) – The parent entity, either specified by the Entity object itself, or its id or its name. Default is None.

  • parent – The parent entity, either specified by the Entity object itself, or its id or its name. Default is None.

  • id (int) – Integer id of the parent entity. Ignored if parent is not None.

  • name (str) – Name of the parent entity. Ignored if parent is not none.

  • inheritance (INHERITANCE, default OBLIGATORY) – One of obligatory, recommended, suggested, or all. Specifies the minimum importance which parent properties need to have to be inherited by this entity. If no inheritance is given, no properties will be inherited by the child. This parameter is case-insensitive.

add_property(property=None, value=None, id=None, name=None, description=None, datatype=None, unit=None, importance='RECOMMENDED', inheritance='FIX')

See Entity.add_property.

to_xml(xml: etree._Element | None = None, add_properties: INHERITANCE = 'ALL', local_serialization: bool = False) etree._Element

Generate an xml representation of this entity. If the parameter xml is given, all attributes, parents, properties, and messages of this entity will be added to it instead of creating a new element.

Raise an error if xml is not a lxml.etree.Element

@param xml: an xml element to which all attributes, parents,

properties, and messages are to be added.

FIXME: Add documentation for the add_properties parameter. FIXME: Add docuemntation for the local_serialization parameter.

@return: xml representation of this entity.

class linkahead.common.models.UserInfo(xml: _Element)

Bases: object

User information from a server response.

name

Username

Type:

str

realm

Realm in which this user lives, e.g., CaosDB or LDAP.

Type:

str

roles

List of roles assigned to this user.

Type:

list[str]

linkahead.common.models.delete(ids: list[int] | range, raise_exception_on_error: bool = True)
linkahead.common.models.execute_query(q: str, unique: bool = False, raise_exception_on_error: bool = True, cache: bool = True, flags: QueryDict | None = None, page_length: int | None = None) Container | Entity | int

Execute a query (via a server-requests) and return the results.

Parameters:
  • q (str) – The query string.

  • unique (bool) – Whether the query is expected to have only one entity as result. Defaults to False.

  • raise_exception_on_error (bool) – Whether an exception should be raised when there are errors in the resulting entities. Defaults to True.

  • cache (bool) – Whether to use the server’s query cache (equivalent to adding a “cache” flag) to the Query object. Defaults to True. Not to be confused with the cached module.

  • flags (dict of str) – Flags to be added to the request.

  • page_length (int) – Whether to use paging. If page_length > 0 this method returns a generator (to be used in a for-loop or with list-comprehension). The generator yields containers with up to page_length entities. Otherwise, paging is disabled, as well as for count queries and when unique is True. Defaults to None.

Raises:

PagingConsistencyError – If the database state changed between paged requests.

Yields:

page (Container) – Returns a container with the next page_length resulting entities.

Returns:

results – Returns an integer when it was a COUNT query. Otherwise, returns a Container with the resulting entities.

Return type:

Container or Entity or integer

linkahead.common.models.get_global_acl()
linkahead.common.models.get_known_permissions()
linkahead.common.models.parse_xml(xml: str | _Element)

parse a string or tree representation of an xml document to a set of entities (records, recordtypes, properties, or files).

@param xml: a string or tree representation of an xml document. @return: list of entities or single entity.

linkahead.common.models.raise_errors(arg0: Entity | QueryTemplate | Container)

Raise a TransactionError depending on the error code(s) inside Entity, QueryTemplate or Container arg0. More detailed errors may be attached to the TransactionError depending on the contents of arg0.

Parameters:

arg0Entity, QueryTemplate, or Container

LinkAhead object whose messages are evaluated according to their error codes

linkahead.common.models.sync_global_acl()