diff --git a/src/linkahead/common/datatype.py b/src/linkahead/common/datatype.py
index c0c15feca240112f1f8e33a0cd37932151fcd9f0..4d09aa3031565cccab736b6ad37de10d0a7eed8a 100644
--- a/src/linkahead/common/datatype.py
+++ b/src/linkahead/common/datatype.py
@@ -24,6 +24,7 @@
 #
 
 import re
+from typing import Literal
 
 from ..exceptions import EmptyUniqueQueryError, QueryNotUniqueError
 
@@ -34,6 +35,7 @@ DATETIME = "DATETIME"
 INTEGER = "INTEGER"
 FILE = "FILE"
 BOOLEAN = "BOOLEAN"
+DATATYPE = Literal["DOUBLE", "REFERENCE", "TEXT", "DATETIME", "INTEGER", "FILE", "BOOLEAN"]
 
 
 def LIST(datatype):
diff --git a/src/linkahead/common/models.py b/src/linkahead/common/models.py
index bcedfb7104d733bc1ac5248e8668a16549891fdc..157354b12608f8969d68739d8fefaba8e9921810 100644
--- a/src/linkahead/common/models.py
+++ b/src/linkahead/common/models.py
@@ -48,11 +48,11 @@ from os.path import isdir
 from random import randint
 from tempfile import NamedTemporaryFile
 
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Dict
 
 if TYPE_CHECKING:
     from datetime import datetime
-    from typing import Any, Literal, Optional, Type, Union, List, TextIO
+    from typing import Any, Literal, Optional, Type, Union, List, TextIO, Tuple
 
 
 from warnings import warn
@@ -71,8 +71,17 @@ from ..exceptions import (AmbiguousEntityError, AuthorizationError,
                           QueryNotUniqueError, TransactionError,
                           UniqueNamesError, UnqualifiedParentsError,
                           UnqualifiedPropertiesError)
-from .datatype import (BOOLEAN, DATETIME, DOUBLE, INTEGER, TEXT,
-                       get_list_datatype, is_list_datatype, is_reference)
+from .datatype import (
+    BOOLEAN,
+    DATETIME,
+    DOUBLE,
+    INTEGER,
+    TEXT,
+    DATATYPE,
+    get_list_datatype,
+    is_list_datatype,
+    is_reference,
+)
 from .state import State
 from .timezone import TimeZone
 from .utils import uuid, xml2str
@@ -80,24 +89,14 @@ from .versioning import Version
 
 _ENTITY_URI_SEGMENT = "Entity"
 
-
-# importances/inheritance
-class Inheritance(Enum):
-    OBLIGATORY = "OBLIGATORY"
-    SUGGESTED = "SUGGESTED"
-    RECOMMENDED = "RECOMMENDED"
-    FIX = "FIX"
-    ALL = "ALL"
-    NONE = "NONE"
-
-
 OBLIGATORY = "OBLIGATORY"
 SUGGESTED = "SUGGESTED"
 RECOMMENDED = "RECOMMENDED"
 FIX = "FIX"
 ALL = "ALL"
 NONE = "NONE"
-
+if TYPE_CHECKING:
+    INHERITANCE = Literal["OBLIGATORY", "SUGGESTED", "RECOMMENDED", "FIX", "ALL", "NONE"]
 
 SPECIAL_ATTRIBUTES = ["name", "role", "datatype", "description",
                       "id", "path", "checksum", "size", "value"]
@@ -121,7 +120,7 @@ class Entity:
         name: Optional[str] = None,
         id: Optional[int] = None,
         description: Optional[str] = None,  # @ReservedAssignment
-        datatype: Optional[str] = None,
+        datatype: Optional[DATATYPE] = None,
         value=None,
         **kwargs,
     ):
@@ -133,32 +132,33 @@ class Entity:
         # If an entity is used (e.g. as parent), it is wrapped instead of being used directly.
         # see Entity._wrap()
         self._wrapped_entity: Optional[Entity] = None
-        self._version = None
-        self._cuid = None
-        self._flags = dict()
+        self._version: Optional[Version] = None
+        self._cuid: Optional[str] = None
+        self._flags: Dict[str, str] = dict()
         self.__value = None
-        self.__datatype = None
-        self.datatype = datatype
+        self.__datatype: Optional[DATATYPE] = None
+        self.datatype: Optional[DATATYPE] = datatype
         self.value = value
         self.messages = Messages()
         self.properties = _Properties()
         self.parents = _ParentList()
-        self.path = None
-        self.file = None
-        self.unit = None
+        self.path: Optional[str] = None
+        self.file: Optional[File] = None
+        self.unit: Optional[str] = None
         self.acl: Optional[ACL] = None
-        self.permissions = None
+        self.permissions: Optional[Permissions] = None
         self.is_valid = lambda: False
         self.is_deleted = lambda: False
         self.name = name
         self.description = description
-        self.id = id
-        self.state = None
+        self.id: Optional[int] = id
+        self.state: Optional[State] = None
 
     def copy(self):
         """
         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.
@@ -204,7 +204,7 @@ class Entity:
         return self._wrapped_entity.version
 
     @version.setter
-    def version(self, version):
+    def version(self, version: Optional[Version]):
         self._version = version
 
     @property
@@ -276,14 +276,14 @@ class Entity:
 
         return self._wrapped_entity.description
 
-    @property
-    def checksum(self):
-        return self._checksum
-
     @description.setter
     def description(self, new_description):
         self.__description = new_description
 
+    @property
+    def checksum(self):
+        return self._checksum
+
     @property
     def unit(self):
         if self.__unit is not None or self._wrapped_entity is None:
@@ -355,7 +355,7 @@ class Entity:
         realm: Optional[str] = None,
         username: Optional[str] = None,
         role: Optional[str] = None,
-        permission: str = None,
+        permission: Optional[str] = None,
         priority: bool = False,
         revoke_denial: bool = True,
     ):
@@ -397,7 +397,7 @@ class Entity:
         realm: Optional[str] = None,
         username: Optional[str] = None,
         role: Optional[str] = None,
-        permission: str = None,
+        permission: Optional[str] = None,
         priority: bool = False,
         revoke_grant: bool = True,
     ):
@@ -452,7 +452,7 @@ class Entity:
             permission=permission,
             priority=priority)
 
-    def is_permitted(self, permission: str, role: Optional[str] = None):
+    def is_permitted(self, permission: Permission, role: Optional[str] = None):
         if role is None:
             # pylint: disable=unsupported-membership-test
 
@@ -580,7 +580,7 @@ class Entity:
         datatype: Optional[str] = None,
         unit: Optional[str] = None,
         importance: Optional[str] = None,
-        inheritance: Union[str, Inheritance, None] = None,
+        inheritance: Union[str, INHERITANCE, None] = None,
     ) -> Entity:  # @ReservedAssignment
         """Add a property to this entity.
 
@@ -756,7 +756,7 @@ class Entity:
         parent: Union[Entity, int, str, None] = None,
         id: Optional[int] = None,
         name: Optional[str] = None,
-        inheritance: Union[str, Inheritance, None] = None,
+        inheritance: Union[INHERITANCE, str, None] = None,
     ):  # @ReservedAssignment
         """Add a parent to this entity.
 
@@ -771,7 +771,7 @@ class Entity:
         name : str
             Name of the parent entity. Ignored if `parent is not
             none`.
-        inheritance : str, Inheritance
+        inheritance : str, INHERITANCE
             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.
@@ -978,7 +978,7 @@ out: List[Entity]
 
         return self.properties
 
-    def get_property(self, pattern):
+    def get_property(self, pattern: Union[int, str, Entity]) -> Union[Property, None]:
         """ Return the first matching property or None.
 
         Parameters
@@ -1023,7 +1023,9 @@ out: List[Entity]
 
         return None
 
-    def _get_value_for_selector(self, selector):
+    def _get_value_for_selector(
+        self, selector: Union[str, List[str], Tuple[str]]
+    ) -> Any:
         """return the value described by the selector
 
         A selector is a list or a tuple of strings describing a path in an
@@ -1195,8 +1197,8 @@ out: List[Entity]
         self,
         xml: Optional[etree._Element] = None,
         add_properties=ALL,
-        local_serialization=False,
-    ):
+        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.
@@ -1216,9 +1218,8 @@ out: List[Entity]
         assert isinstance(xml, etree._Element)
 
         # unwrap wrapped entity
-
         if self._wrapped_entity is not None:
-            xml: etree._Element = self._wrapped_entity.to_xml(xml, add_properties)
+            xml = self._wrapped_entity.to_xml(xml, add_properties)
 
         if self.id is not None:
             xml.set("id", str(self.id))
@@ -1960,8 +1961,8 @@ class Message(object):
         self,
         type: Optional[str] = None,
         code: Optional[int] = None,
-        description=None,
-        body: str = None,
+        description: Optional[str]=None,
+        body: Optional[str] = None,
     ):  # @ReservedAssignment
         self.description = description
         self.type = type if type is not None else "Info"
@@ -2010,7 +2011,13 @@ class RecordType(Entity):
             property=property, id=id, name=name, description=description, datatype=datatype,
             value=value, unit=unit, importance=importance, inheritance=inheritance)
 
-    def add_parent(self, parent=None,  id=None, name=None, inheritance:Union[str, Inheritance]=OBLIGATORY):
+    def add_parent(
+        self,
+        parent=None,
+        id=None,
+        name=None,
+        inheritance: Union[INHERITANCE, str, None] = OBLIGATORY,
+    ):
         """Add a parent to this RecordType
 
         Parameters
@@ -2301,7 +2308,7 @@ class _Properties(list):
         return self
 
     def to_xml(
-        self, add_to_element: etree._Element, add_properties: Union[str, Inheritance]
+        self, add_to_element: etree._Element, add_properties: Union[str, INHERITANCE]
     ):
         for p in self:
             importance = self._importance.get(p)
@@ -4191,10 +4198,10 @@ class ACL():
         self._priority_grants: set[ACI] = set()
         self._priority_denials: set[ACI] = set()
 
-    def _get_boolean_priority(self, priority: str):
+    def _get_boolean_priority(self, priority: Any):
         return str(priority).lower() in ["true", "1", "yes", "y"]
 
-    def _remove_item(self, item, priority: str):
+    def _remove_item(self, item, priority: bool):
         try:
             self._denials.remove(item)
         except KeyError:
@@ -4219,7 +4226,7 @@ class ACL():
         username: Optional[str] = None,
         realm: Optional[str] = None,
         role: Optional[str] = None,
-        permission: str = None,
+        permission: Optional[str] = None,
         priority: Union[bool, str] = False,
     ):
         priority = self._get_boolean_priority(priority)
@@ -4300,7 +4307,7 @@ class ACL():
         username: Optional[str] = None,
         realm: Optional[str] = None,
         role: Optional[str] = None,
-        permission: str = None,
+        permission: Optional[str] = None,
         priority: bool = False,
         revoke_grant: bool = True,
     ):
@@ -4499,10 +4506,10 @@ class Query():
     def getFlag(self, key):
         return self.flags.get(key)
 
-    def __init__(self, q):
-        self.flags = dict()
+    def __init__(self, q: Union[str, etree._Element]):
+        self.flags: Dict[str, str] = dict()
         self.messages = Messages()
-        self.cached = None
+        self.cached: Optional[bool] = None
         self.etag = None
 
         if isinstance(q, etree._Element):
@@ -4547,8 +4554,13 @@ class Query():
             yield next_page
             index += page_length
 
-    def execute(self, unique=False, raise_exception_on_error=True, cache=True,
-                page_length=None):
+    def execute(
+        self,
+        unique: bool = False,
+        raise_exception_on_error: bool = True,
+        cache: bool = True,
+        page_length: Optional[int] = None,
+    ):
         """Execute a query (via a server-requests) and return the results.
 
         Parameters
@@ -4635,8 +4647,14 @@ class Query():
             return cresp
 
 
-def execute_query(q, unique=False, raise_exception_on_error=True, cache=True,
-                  flags=None, page_length=None):
+def execute_query(
+    q: str,
+    unique: bool = False,
+    raise_exception_on_error: bool = True,
+    cache: bool = True,
+    flags: Optional[Dict[str, str]] = None,
+    page_length: Optional[int] = None,
+):
     """Execute a query (via a server-requests) and return the results.
 
     Parameters
@@ -4728,7 +4746,7 @@ class DropOffBox(list):
 
 class UserInfo():
 
-    def __init__(self, xml):
+    def __init__(self, xml: etree._Element):
         self.roles = [role.text for role in xml.findall("Roles/Role")]
         self.name = xml.get("username")
         self.realm = xml.get("realm")
@@ -4778,7 +4796,7 @@ class Info():
 
 class Permission():
 
-    def __init__(self, name, description=None):
+    def __init__(self, name: str, description: Optional[str] = None):
         self.name = name
         self.description = description
 
@@ -4802,13 +4820,13 @@ class Permissions():
 
     known_permissions = None
 
-    def __init__(self, xml):
+    def __init__(self, xml: etree._Element):
         self.parse_xml(xml)
 
     def clear(self):
         self._perms = set()
 
-    def parse_xml(self, xml):
+    def parse_xml(self, xml: etree._Element):
         self.clear()
 
         for e in xml:
@@ -4840,12 +4858,12 @@ def parse_xml(xml: Union[str, etree._Element]):
     if isinstance(xml, etree._Element):
         elem: etree._Element = xml
     else:
-        elem: etree._Element = etree.fromstring(xml)
+        elem = etree.fromstring(xml)
 
     return _parse_single_xml_element(elem)
 
 
-def _parse_single_xml_element(elem):
+def _parse_single_xml_element(elem: etree._Element):
     classmap = {
         'record': Record,
         'recordtype': RecordType,
@@ -4899,7 +4917,7 @@ def _parse_single_xml_element(elem):
             "code"), description=elem.get("description"), body=elem.text)
 
 
-def _evaluate_and_add_error(parent_error: TransactionError, ent: Entity):
+def _evaluate_and_add_error(parent_error: TransactionError, ent: Union[Entity, Container]):
     """Evaluate the error message(s) attached to entity and add a
     corresponding exception to parent_error.
 
@@ -4908,7 +4926,7 @@ def _evaluate_and_add_error(parent_error: TransactionError, ent: Entity):
     parent_error : TransactionError
         Parent error to which the new exception will be attached. This
         exception will be a direct child.
-    ent : Entity
+    ent : Entity or Container
         Entity that caused the TransactionError. An exception is
         created depending on its error message(s).
 
@@ -5029,7 +5047,7 @@ def raise_errors(arg0: Union[Entity, QueryTemplate, Container]):
         raise transaction_error
 
 
-def delete(ids:Union[List[int], range], raise_exception_on_error=True):
+def delete(ids: Union[List[int], range], raise_exception_on_error=True):
     c = Container()
 
     if isinstance(ids, list) or isinstance(ids, range):