diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..015f4f621ef61e3de854087ccc4fecc38d2148c0
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,15 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+
+default_language_version:
+  python: python
+
+repos:
+  - repo: https://github.com/pre-commit/mirrors-mypy
+    rev: v1.3.0
+    hooks:
+    - id: mypy
+      files: Phys
+      exclude: "tests"
+      additional_dependencies: [types-requests]
+      args: [--show-error-codes]
diff --git a/Phys/DaVinci/python/DaVinci/LbExec.py b/Phys/DaVinci/python/DaVinci/LbExec.py
index 1f74ed93c404de51a8ad0d135a08322ddaddcbf1..da7e050297cf6673ef2b9ffbe927c98ff8827c27 100644
--- a/Phys/DaVinci/python/DaVinci/LbExec.py
+++ b/Phys/DaVinci/python/DaVinci/LbExec.py
@@ -10,10 +10,11 @@
 ###############################################################################
 from contextlib import contextmanager
 from typing import Optional
-from GaudiConf.LbExec import Options as DefaultOptions, InputProcessTypes
-from pydantic import root_validator
-from PyConf.reading import (upfront_decoder, reconstruction, get_tes_root)
-from PyConf.application import default_raw_event
+from GaudiConf.LbExec import Options as DefaultOptions, InputProcessTypes  # type: ignore[import]
+from pydantic import root_validator  # type: ignore[import]
+from PyConf.reading import upfront_decoder, reconstruction  # type: ignore[import]
+from PyConf.reading import get_tes_root  # type: ignore[import]
+from PyConf.application import default_raw_event  # type: ignore[import]
 import logging
 
 
diff --git a/Phys/DaVinci/python/DaVinci/algorithms.py b/Phys/DaVinci/python/DaVinci/algorithms.py
index 4c10b9e339c0a7d12c805c9e6f4a6df9a063f5f9..d94e818425e3a172d6c834670343cf3e8d665318 100644
--- a/Phys/DaVinci/python/DaVinci/algorithms.py
+++ b/Phys/DaVinci/python/DaVinci/algorithms.py
@@ -12,26 +12,30 @@ import re
 import logging
 import itertools
 from collections import OrderedDict
+from typing import Any, Union
 
-from GaudiConf.LbExec import InputProcessTypes
-from PyConf.Algorithms import LoKi__HDRFilter, LoKi__VoidFilter, VoidFilter
-from PyConf.reading import get_particles, get_decreports, get_hlt_reports, dstdata_filter
-import Functors as F
+from GaudiConf.LbExec import InputProcessTypes  # type: ignore[import]
+from PyConf.Algorithms import LoKi__HDRFilter, LoKi__VoidFilter, VoidFilter  # type: ignore[import]
+from PyConf.Algorithms import HltDecReportsDecoder  # type: ignore[import]
+from PyConf.reading import get_particles, get_decreports, get_hlt_reports, dstdata_filter  # type: ignore[import]
+import Functors as F  # type: ignore[import]
+from DaVinci.LbExec import Options
 
 log = logging.getLogger(__name__)
 
 
-def set_filter(name, code, dec_reports):
+def set_filter(name: str, code: str, dec_reports: HltDecReportsDecoder
+               ) -> Union[LoKi__HDRFilter, LoKi__VoidFilter]:
     """
     Adding an HDR filter to FunTuple algorithms checking if the corresponding HLT/Sprucing line fired.
 
     Args:
         name (str): filter's name.
         code (str): filter's code.
-        dec_reports (HltDecreportsDecoder instance): HltDecReportsDecoder containing the configuration for HLT/Sprucing lines.
+        dec_reports (HltDecReportsDecoder instance): HltDecReportsDecoder containing the configuration for HLT/Sprucing lines.
 
     Returns:
-        Filter with name and code defined by the user.
+        Filter (LoKi__HDRFilter or LoKi__VoidFilter) with name and code defined by the user.
     """
     if dec_reports:
         algFilter = LoKi__HDRFilter(
@@ -44,7 +48,8 @@ def set_filter(name, code, dec_reports):
     return algFilter
 
 
-def add_filter(name, code):
+def add_filter(name: str,
+               code: str) -> Union[LoKi__HDRFilter, LoKi__VoidFilter]:
     """
     Adding an event pre-filter using a code defined by the user.
 
@@ -52,8 +57,11 @@ def add_filter(name, code):
         name (str): filter's name.
         code (str): filter's code.
 
+    Raises:
+        SyntaxError: if the specified filter code does not end with brackets ')'.
+
     Returns:
-        Filter with name and code defined by the user.
+        Filter (LoKi__HDRFilter or LoKi__VoidFilter) with name and code defined by the user.
     """
     print(
         "DaVinciFilter.add_filter is deprecated -- please use create_lines_filter instead"
@@ -63,7 +71,7 @@ def add_filter(name, code):
     if code.startswith("HLT_PASS("):
         #check if it ends with braces
         if not code.endswith(")"):
-            raise Exception("The specified code must end with brackets ')'")
+            raise SyntaxError("The specified code must end with brackets ')'")
 
         #find all the line names between apostrophe
         # e.g. turns string "HLT_PASS('Line1 ','Line2')" to list('Line1', 'Line2)
@@ -89,7 +97,7 @@ def add_filter(name, code):
     return set_filter(name, code, dec_reports)
 
 
-def create_lines_filter(name, lines):
+def create_lines_filter(name: str, lines: list[str]) -> VoidFilter:
     """
     Create an event pre-filter requiring the specified lines.
 
@@ -121,7 +129,8 @@ def create_lines_filter(name, lines):
     return VoidFilter(name=name, Cut=F.require_all(*cuts))
 
 
-def apply_filters(options, algs_dict):
+def apply_filters(options: Options,
+                  algs_dict: dict[str, list[Any]]) -> dict[str, list[Any]]:
     """
     Adding filter algorithms.
 
@@ -133,7 +142,7 @@ def apply_filters(options, algs_dict):
         Dict where at each node filters  are prepended to the initial list of user algorithms.
     """
 
-    alg_filterd_dict = {}
+    alg_filterd_dict: dict[str, list[Any]] = {}
     for name, algs in algs_dict.items():
         algs_list = []
 
@@ -146,7 +155,7 @@ def apply_filters(options, algs_dict):
             ]
 
         if options.evt_pre_filters:
-            evt_pre_filters = []
+            evt_pre_filters: list[Any] = []
             for title, code in options.evt_pre_filters.items():
                 evt_filter = add_filter(title, code)
                 evt_pre_filters.append(evt_filter)
@@ -159,7 +168,7 @@ def apply_filters(options, algs_dict):
     return alg_filterd_dict
 
 
-def make_fsr_algs(options):
+def make_fsr_algs(options: Options) -> dict[str, list[Any]]:
     """
     Make FSR related algorithms.
 
@@ -167,14 +176,14 @@ def make_fsr_algs(options):
         options (DaVinci.Options): lbexec provided options object
 
     Returns:
-        List of FSR algorithm instances to be configured.
+        Dist with list of FSR algorithm instances to be configured.
     """
     from PyConf.Algorithms import EventAccounting, GenFSRMerge, RecordStream
 
-    fsrAlgs = {}
+    fsrAlgs: dict[str, list[Any]] = {}
 
     if options.simulation:
-        algs = []
+        algs: list[Any] = []
         if options.merge_genfsr:
             algs.append(GenFSRMerge(name="GenFSRMerge"))
         if options.write_fsr and options.output_file:
@@ -197,7 +206,7 @@ def make_fsr_algs(options):
     return fsrAlgs
 
 
-def configured_FunTuple(config):
+def configured_FunTuple(config: dict[str, Any]) -> dict[str, Any]:
     """
     Function for the FunTuple configuration and instantiation of the related HDR filter.
 
@@ -214,25 +223,25 @@ def configured_FunTuple(config):
     Returns:
        - List of filters and tupling algorithms.
     """
-    from FunTuple import FunTuple_Particles as Funtuple
+    from FunTuple import FunTuple_Particles as Funtuple  # type: ignore[import]
 
-    dictAlgs = {}
+    dictAlgs: dict[str, list[Any]] = {}
     for key in config.keys():
         inputs = get_particles(config[key]["location"])
         dictAlgs[key] = []
 
-        i = 0
+        i: int = 0
         for line in config[key]["filters"]:
-            filter_name = "Filter_%s" % key
+            filter_name: str = f"Filter_{key}"
             if len(config[key]["filters"]) > 1:
-                filter_name += "_%d" % i
+                filter_name += f"_{i}"
                 i = i + 1
 
             tupleFilter = add_filter(filter_name, line)
             dictAlgs[key].append(tupleFilter)
 
         funTuple = Funtuple(
-            name="Tuple_%s" % key,
+            name=f"Tuple_{key}",
             tuple_name=config[key]["tuple"],
             fields=config[key]["fields"],
             variables=config[key]["variables"],
diff --git a/Phys/DaVinci/python/DaVinci/common_particles.py b/Phys/DaVinci/python/DaVinci/common_particles.py
index ae2fed916e0dd246d06c57f923473846288c5715..3b3fe4fa432551404fb9c07845176a5b12bba0c6 100644
--- a/Phys/DaVinci/python/DaVinci/common_particles.py
+++ b/Phys/DaVinci/python/DaVinci/common_particles.py
@@ -11,18 +11,18 @@
 """
 Definitions of "common particles" very similar to those of Runs 1 & 2.
 """
-from GaudiKernel.SystemOfUnits import MeV
-import Functors as F
-from Functors.math import in_range
-from PyConf.tonic import configurable
-from PyConf.Algorithms import FunctionalParticleMaker
-from Hlt2Conf.standard_particles import (make_long_kaons, make_long_muons,
-                                         standard_protoparticle_filter,
-                                         get_long_track_selector)
-from Hlt2Conf.algorithms_thor import ParticleFilter, ParticleCombiner
-from PyConf.reading import (get_charged_protoparticles as
-                            _make_charged_protoparticles)
-from RecoConf.reco_objects_from_file import make_pvs as _make_pvs_v2
+from GaudiKernel.SystemOfUnits import MeV  # type: ignore[import]
+import Functors as F  # type: ignore[import]
+from Functors.math import in_range  # type: ignore[import]
+from PyConf.tonic import configurable  # type: ignore[import]
+from PyConf.Algorithms import FunctionalParticleMaker  # type: ignore[import]
+from Hlt2Conf.standard_particles import (  # type: ignore[import]
+    make_long_kaons, make_long_muons, standard_protoparticle_filter,
+    get_long_track_selector)
+from Hlt2Conf.algorithms_thor import ParticleFilter, ParticleCombiner  # type: ignore[import]
+from PyConf.reading import (get_charged_protoparticles  # type: ignore[import]
+                            as _make_charged_protoparticles)
+from RecoConf.reco_objects_from_file import make_pvs as _make_pvs_v2  # type: ignore[import]
 from DaVinci.filter_selectors import default_particle_cuts
 
 ####################################
diff --git a/Phys/DaVinci/python/DaVinci/config.py b/Phys/DaVinci/python/DaVinci/config.py
index ad038c48b312818e83afe1c4e0e2bc8b2d43ddb4..250cfc33b6dacd2b5035d7a07c6be6a3853e3847 100644
--- a/Phys/DaVinci/python/DaVinci/config.py
+++ b/Phys/DaVinci/python/DaVinci/config.py
@@ -14,10 +14,10 @@ DaVinci configured using PyConf components.
 
 import logging
 from collections import namedtuple, OrderedDict
-from Configurables import ApplicationMgr
-from PyConf.application import configure, configure_input, configured_ann_svc
+from Configurables import ApplicationMgr  # type: ignore[import]
+from PyConf.application import configure, configure_input, configured_ann_svc  # type: ignore[import]
 from PyConf.application import metainfo_repos
-from PyConf.control_flow import CompositeNode, NodeLogic
+from PyConf.control_flow import CompositeNode, NodeLogic  # type: ignore[import]
 from DaVinci.algorithms import (make_fsr_algs, apply_filters)
 
 log = logging.getLogger(__name__)
diff --git a/Phys/DaVinci/python/DaVinci/filter_selectors.py b/Phys/DaVinci/python/DaVinci/filter_selectors.py
index deed091eb37d8390605cef2058c3abc6bb6d62ed..7334d4c2a695a391f6eadde9d5e3024e9a170b27 100644
--- a/Phys/DaVinci/python/DaVinci/filter_selectors.py
+++ b/Phys/DaVinci/python/DaVinci/filter_selectors.py
@@ -1,5 +1,5 @@
 ###############################################################################
-# (c) Copyright 2021-2022 CERN for the benefit of the LHCb Collaboration      #
+# (c) Copyright 2021-2023 CERN for the benefit of the LHCb Collaboration      #
 #                                                                             #
 # This software is distributed under the terms of the GNU General Public      #
 # Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
@@ -13,15 +13,16 @@ Definitions of:
 
 - Default cuts a la runs 1&2 common particles.
 """
-from GaudiKernel.SystemOfUnits import MeV
-import Functors as F
+from GaudiKernel.SystemOfUnits import MeV  # type: ignore[import]
+from PyConf.dataflow import DataHandle  # type: ignore[import]
+import Functors as F  # type: ignore[import]
 
 #################################
 # Default particle cuts
 #################################
 
 
-def default_particle_cuts(pvs):
+def default_particle_cuts(pvs: DataHandle):
     """
     Return a string with the default particle standard loose cuts.
     """