diff --git a/reqs_checker.py b/reqs_checker.py
new file mode 100644
index 0000000000000000000000000000000000000000..c180efa34888ef5e603dc58a36bb1d113b8b4dae
--- /dev/null
+++ b/reqs_checker.py
@@ -0,0 +1,54 @@
+import re
+
+
+def read_requirements_txt(file_path: str) -> list[str]:
+    with open(file_path, "r") as file:
+        lines = file.readlines()
+
+    def _dev_req_index() -> int:
+        return next((i for i, line in enumerate(lines) if "# dev requirements" in line), len(lines))
+
+    dev_req_index = _dev_req_index()
+    assert dev_req_index != len(lines), f"Missing # dev requirements section in {file_path}"
+
+    return [line.strip() for line in lines[: _dev_req_index()] if line.strip() and not line.startswith("#")]
+
+
+def read_requirements_setup(file_path: str) -> list[str]:
+    with open(file_path, "r") as file:
+        content = file.read()
+
+    # Find and extract the install_requires section
+    matches = re.findall(r"install_requires=\[(.*?)\]", content, re.DOTALL)
+    if matches:
+        return re.findall(r'"([^"]+)"', matches[0])
+
+    return []
+
+
+def compare_requirements(reqs: list[str], setup_reqs: list[str]) -> tuple[set[str], set[str]]:
+    missing_in_setup = set(reqs) - set(setup_reqs)
+    missing_in_requirements = set(setup_reqs) - set(reqs)
+
+    return missing_in_setup, missing_in_requirements
+
+
+def main() -> None:
+    reqs = read_requirements_txt("requirements.txt")
+    setup_reqs = read_requirements_setup("setup.py")
+
+    missing_in_setup, missing_in_requirements = compare_requirements(reqs, setup_reqs)
+
+    if not missing_in_setup and not missing_in_requirements:
+        print("Requirements are synchronized.")  # noqa: T201
+    else:
+        if missing_in_setup:
+            print("Missing or different in setup.py:", ", ".join(missing_in_setup))  # noqa: T201
+        if missing_in_requirements:
+            print("Missing or different in requirements.txt:", ", ".join(missing_in_requirements))  # noqa: T201
+
+        exit(1)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/requirements.txt b/requirements.txt
index ce50fc8a1259acf7d6bc9ddfc4f05c4b2fc26d3f..555629c57a3ffb4f28efcec53893d285ba88dd37 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,29 +1,30 @@
 jsonschema~=4.20.0
 fastapi~=0.104.1
-pydantic~=2.0.3
-ansible-runner==2.3.4
-uvicorn[standard]~=0.22.0
-httpx~=0.25.1
-
+pydantic~=2.5.1
+ansible~=9.0.1
+requests~=2.31.0
+uvicorn~=0.22.0
+ncclient~=0.6.13
+xmltodict~=0.13.0
+netaddr~=0.9.0
+jmespath~=1.0.0
+dictdiffer~=0.9.0
+ansible-runner~=2.3.3
+junos-eznc~=2.6.8
+jxmlease~=1.0.3
 ansible-core~=2.16.0
 ansible_merge_vars~=5.0.0
+httpx~=0.25.1
 GitPython~=3.1.40
 jinja2==3.1.2
-junos-eznc~=2.6.8
-jxmlease~=1.0.3
-ncclient~=0.6.13
 ruamel.yaml~=0.18.5
-xmltodict~=0.13.0
-dictdiffer~=0.9.0
-jmespath~=1.0.1
 
 # dev requirements
 pytest~=7.4.3
-Faker~=20.0.3
+Faker~=20.1.0
 responses~=0.24.1
 sphinx~=7.2.6
 sphinx-rtd-theme~=1.3.0
-requests~=2.31.0
 docutils~=0.18.1
 isort~=5.12.0
 black~=23.11.0
diff --git a/setup.py b/setup.py
index 24315c22f4fc64bd2ade4886cdffe2f61f5f8910..4d4fa260cae1cceaed6220de2e6119ea51e504e1 100644
--- a/setup.py
+++ b/setup.py
@@ -9,21 +9,21 @@ setup(
     url="https://gitlab.geant.org/goat/gap/lso",
     packages=find_packages(),
     install_requires=[
-        "jsonschema~=4.18.0",
-        "fastapi~=0.100.0",
-        "pydantic~=2.0.2",
-        "ansible~=8.1.0",
+        "jsonschema~=4.20.0",
+        "fastapi~=0.104.1",
+        "pydantic~=2.5.1",
+        "ansible~=9.0.1",
         "requests~=2.31.0",
         "uvicorn~=0.22.0",
         "ncclient~=0.6.13",
         "xmltodict~=0.13.0",
-        "netaddr~=0.8.0",
+        "netaddr~=0.9.0",
         "jmespath~=1.0.0",
         "dictdiffer~=0.9.0",
         "ansible-runner~=2.3.3",
         "junos-eznc~=2.6.8",
         "jxmlease~=1.0.3",
-        "ansible-core~=2.15.1",
+        "ansible-core~=2.16.0",
         "ansible_merge_vars~=5.0.0",
         "httpx~=0.25.1",
         "GitPython~=3.1.40",
diff --git a/tox.ini b/tox.ini
index 927b8974a48b33a3031b4b28dce6c342837cf1eb..6e87b69aec7adab4e3c8c3bfe75f4f373dc61137 100644
--- a/tox.ini
+++ b/tox.ini
@@ -21,6 +21,7 @@ deps =
     -r requirements.txt
 
 commands =
+    python reqs_checker.py
     isort -c .
     ruff .
     black --check .