diff --git a/libs/lib/xaal/lib/bindings.py b/libs/lib/xaal/lib/bindings.py
index 0dd2ad1ead7394b0b1319c707c2e7a1a580ba76f..d9588b6c2b90ac935bf180a9c1b3e28b0b83586a 100644
--- a/libs/lib/xaal/lib/bindings.py
+++ b/libs/lib/xaal/lib/bindings.py
@@ -2,13 +2,12 @@ import uuid
 
 from .exceptions import UUIDError
 
-
 class UUID:
     def __init__(self, *args, **kwargs):
         self.__uuid = uuid.UUID(*args, **kwargs)
 
     @staticmethod
-    def random_base(digit=2):
+    def random_base(digit=2) -> 'UUID':
         """zeros the last digits of a random uuid, usefull w/ you want to forge some addresses
         two digit is great.
         """
@@ -20,48 +19,48 @@ class UUID:
             raise UUIDError
 
     @staticmethod
-    def random():
+    def random() -> 'UUID':
         tmp = uuid.uuid1().int
         return UUID(int=tmp)
 
-    def __add__(self, value):
+    def __add__(self, value:int) -> 'UUID':
         tmp = self.__uuid.int + value
         return UUID(int=tmp)
 
-    def __sub__(self, value):
+    def __sub__(self, value:int) -> 'UUID':
         tmp = self.__uuid.int - value
         return UUID(int=tmp)
 
-    def __eq__(self, value):
+    def __eq__(self, value) -> bool:
         return self.__uuid == value
 
-    def __lt__(self, value):
+    def __lt__(self, value) -> bool:
         return self.__uuid.int < value
 
-    def __gt__(self, value):
+    def __gt__(self, value) -> bool:
         return self.__uuid.int > value
 
-    def __str__(self):
+    def __str__(self) -> str:
         return str(self.__uuid)
 
-    def __repr__(self):  # pragma: no cover
+    def __repr__(self) -> str:  # pragma: no cover
         return f"UUID('{self.__uuid}')"
 
-    def __hash__(self):
+    def __hash__(self) -> int:
         return self.__uuid.__hash__()
 
-    def get(self):
+    def get(self) -> uuid.UUID:
         return self.__uuid
 
-    def set(self, value):
+    def set(self, value:uuid.UUID):
         self.__uuid = value
 
     @property
-    def str(self):
+    def str(self) -> str:
         return str(self)
 
     @property
-    def bytes(self):
+    def bytes(self) -> bytes:
         return self.__uuid.bytes
 
 
diff --git a/libs/lib/xaal/lib/devices.py b/libs/lib/xaal/lib/devices.py
index d9c8ca3a764ce3e326d9d5207c9d53c2e127e11c..4d4ff1a9fb8aa9fccd2cbd9884b466f592736470 100644
--- a/libs/lib/xaal/lib/devices.py
+++ b/libs/lib/xaal/lib/devices.py
@@ -19,20 +19,24 @@
 #
 
 import time
+import logging
+from tabulate import tabulate
+from typing import Optional, Union, Any
+
 
 from . import config
 from . import tools
 from . import bindings
 from .exceptions import DeviceError
+from .types import UUIDT, DeviceT, EngineT, AsyncEngineT
+
 
-from tabulate import tabulate
-import logging
 logger = logging.getLogger(__name__)
 
 
 class Attribute(object):
 
-    def __init__(self, name, dev=None, default=None):
+    def __init__(self, name, dev: Optional[DeviceT] = None, default: Any = None):
         self.name = name
         self.default = default
         self.device = dev
@@ -76,15 +80,34 @@ class Attributes(list):
         raise KeyError(name)
 
 class Device(object):
+    __slots__ = [
+        "__dev_type",
+        "__address",
+        "group_id",
+        "vendor_id",
+        "product_id",
+        "hw_id",
+        "__version",
+        "__url",
+        "schema",
+        "info",
+        "unsupported_attributes",
+        "unsupported_methods",
+        "unsupported_notifications",
+        "alive_period",
+        "next_alive",
+        "__attributes",
+        "methods",
+        "engine",
+    ]
+
+    def __init__(
+        self,
+        dev_type: str,
+        addr: Optional[UUIDT] = None,
+        engine: Union[EngineT, AsyncEngineT, None] = None,
+    ):
 
-    __slots__ = ['__dev_type','__address','group_id',
-                'vendor_id','product_id','hw_id',
-                '__version','__url','schema','info',
-                'unsupported_attributes','unsupported_methods','unsupported_notifications',
-                'alive_period','next_alive',
-                '__attributes','methods','engine']
-
-    def __init__(self, dev_type, addr=None, engine=None):
         # xAAL internal attributes for a device
         self.dev_type = dev_type        # xaal dev_type
         self.address = addr             # xaal addr
@@ -92,8 +115,8 @@ class Device(object):
         self.vendor_id = None           # vendor ID ie : ACME
         self.product_id = None          # product ID
         self.hw_id = None               # hardware info
-        self.__version = None           # product release
-        self.__url = None               # product URL
+        self.version = None           # product release
+        self.url = None               # product URL
         self.schema = None              # schema URL
         self.info = None                # additionnal info
 
@@ -111,21 +134,21 @@ class Device(object):
         self.engine = engine
 
     @property
-    def dev_type(self):
+    def dev_type(self) -> str:
         return self.__dev_type
 
     @dev_type.setter
-    def dev_type(self, value):
+    def dev_type(self, value: str):
         if not tools.is_valid_dev_type(value):
             raise DeviceError(f"The dev_type {value} is not valid")
         self.__dev_type = value
 
     @property
-    def version(self):
+    def version(self) -> Optional[str]:
         return self.__version
 
     @version.setter
-    def version(self, value):
+    def version(self, value: Any):
         # version must be a string
         if value:
             self.__version = "%s" % value
@@ -137,7 +160,7 @@ class Device(object):
         return self.__address
 
     @address.setter
-    def address(self, value):
+    def address(self, value: Optional[UUIDT]):
         if value is None:
             self.__address = None
             return
@@ -231,13 +254,13 @@ class Device(object):
             print(tabulate(r,tablefmt="fancy_grid"))
 
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return f"<xaal.Device {id(self):x} {self.address} {self.dev_type}>"
 
     #####################################################
     # default public methods
     #####################################################
-    def _get_description(self):
+    def _get_description(self) -> dict:
         result = {}
         if self.vendor_id:
             result['vendor_id'] = self.vendor_id
diff --git a/libs/lib/xaal/lib/types.py b/libs/lib/xaal/lib/types.py
new file mode 100644
index 0000000000000000000000000000000000000000..12c6f75f50c2c72a56ab4889c16baa0422186b4a
--- /dev/null
+++ b/libs/lib/xaal/lib/types.py
@@ -0,0 +1,17 @@
+# Python type hints for the xAAL library
+
+from typing import TYPE_CHECKING, TypeVar
+
+if TYPE_CHECKING:
+    from .devices import Device, Attributes, Attribute
+    from .engine import Engine
+    from .aioengine import AsyncEngine
+    from .bindings import UUID
+
+DeviceT = TypeVar("DeviceT", bound="Device")
+AttributeT = TypeVar("AttributeT", bound="Attribute")
+AttributesT = TypeVar("AttributesT", bound="Attributes")
+EngineT = TypeVar("EngineT", bound="Engine")
+AsyncEngineT = TypeVar("AsyncEngineT", bound="AsyncEngine")
+
+UUIDT = TypeVar("UUIDT", bound="UUID")