diff --git a/app/__init__.py b/app/__init__.py
index d6e0be82f97df8f1723e018ffe03a0aaa4f2b24e..9769088443da22f8ee84d2e73ccbeb4157581192 100755
--- a/app/__init__.py
+++ b/app/__init__.py
@@ -28,6 +28,9 @@ from flask_migrate import Migrate
 from flask_sqlalchemy import SQLAlchemy
 
 from jinja2 import select_autoescape
+import numpy as np
+import psycopg2
+from psycopg2.extensions import AsIs as psycopg2_AsIs
 import sqlalchemy as sa
 import werkzeug.debug
 from wtforms.fields import HiddenField
@@ -68,6 +71,19 @@ cache = Cache(
 )
 
 
+# NumPy & Psycopg2 (necessary with Numpy 2.0)
+# probablement à changer quand on passera à psycopg3.2
+def adapt_numpy_scalar(numpy_scalar):
+    """Adapt numeric types for psycopg2"""
+    return psycopg2_AsIs(numpy_scalar if not np.isnan(numpy_scalar) else "'NaN'")
+
+
+psycopg2.extensions.register_adapter(np.float32, adapt_numpy_scalar)
+psycopg2.extensions.register_adapter(np.float64, adapt_numpy_scalar)
+psycopg2.extensions.register_adapter(np.int32, adapt_numpy_scalar)
+psycopg2.extensions.register_adapter(np.int64, adapt_numpy_scalar)
+
+
 def handle_sco_value_error(exc):
     "page d'erreur avec message"
     return render_template("sco_value_error.j2", exc=exc), 404
diff --git a/app/but/jury_but.py b/app/but/jury_but.py
index 8ccb06d6baab0c11259a5c1619e09ca628012e2d..4f3fb5c9cab7c0eb80602a10281a67bd5a6ba23d 100644
--- a/app/but/jury_but.py
+++ b/app/but/jury_but.py
@@ -1557,8 +1557,8 @@ class DecisionsProposeesUE(DecisionsProposees):
         res: ResultatsSemestreBUT = (
             self.rcue.res_pair if paire else self.rcue.res_impair
         )
-        self.moy_ue = np.NaN
-        self.moy_ue_with_cap = np.NaN
+        self.moy_ue = np.nan
+        self.moy_ue_with_cap = np.nan
         self.ue_status = {}
 
         if self.ue.type != sco_codes.UE_STANDARD:
diff --git a/app/comp/moy_mod.py b/app/comp/moy_mod.py
index 7f33065b15e758247e0e27374d6a14cdf5a8db4a..cfdea10b07cf744e9ae52277153b156a4c45edb9 100644
--- a/app/comp/moy_mod.py
+++ b/app/comp/moy_mod.py
@@ -549,7 +549,7 @@ def load_evaluations_poids(moduleimpl_id: int) -> tuple[pd.DataFrame, list]:
             EvaluationUEPoids.evaluation
         ).filter_by(moduleimpl_id=moduleimpl_id):
             try:
-                evals_poids[ue_poids.ue_id][ue_poids.evaluation_id] = ue_poids.poids
+                evals_poids.loc[ue_poids.evaluation_id, ue_poids.ue_id] = ue_poids.poids
             except KeyError:
                 pass  # poids vers des UE qui n'existent plus ou sont dans un autre semestre...
 
@@ -564,7 +564,7 @@ def load_evaluations_poids(moduleimpl_id: int) -> tuple[pd.DataFrame, list]:
     if np.isnan(evals_poids.values.flat).any():
         ue_coefs = modimpl.module.get_ue_coef_dict()
         for ue in ues:
-            evals_poids[ue.id][evals_poids[ue.id].isna()] = (
+            evals_poids.loc[evals_poids[ue.id].isna(), ue.id] = (
                 1 if ue_coefs.get(ue.id, default_poids) > 0 else 0
             )
 
diff --git a/app/comp/moy_sem.py b/app/comp/moy_sem.py
index 20d9752ce3d1c09040ef304731f182f4bef80026..540b7866897708c41c21f5cfe3cdc915e276b9d5 100644
--- a/app/comp/moy_sem.py
+++ b/app/comp/moy_sem.py
@@ -82,7 +82,7 @@ def compute_sem_moys_apc_using_ects(
         moy_gen = (etud_moy_ue_df * ects).sum(axis=1) / ects.sum(axis=1)
     except ZeroDivisionError:
         # peut arriver si aucun module... on ignore
-        moy_gen = pd.Series(np.NaN, index=etud_moy_ue_df.index)
+        moy_gen = pd.Series(np.nan, index=etud_moy_ue_df.index)
     except TypeError:
         if None in ects:
             formation = db.session.get(Formation, formation_id)
@@ -93,7 +93,7 @@ def compute_sem_moys_apc_using_ects(
                 scodoc_dept=g.scodoc_dept, formation_id=formation_id)}">{formation.get_titre_version()}</a>)"""
                 )
             )
-            moy_gen = pd.Series(np.NaN, index=etud_moy_ue_df.index)
+            moy_gen = pd.Series(np.nan, index=etud_moy_ue_df.index)
         else:
             raise
     return moy_gen
diff --git a/app/comp/moy_ue.py b/app/comp/moy_ue.py
index 24fdbd46849087eb6d2b7c020b83acdf7f95412b..5e88f29e353fa713bce89b8871ddaa17fcbed137 100644
--- a/app/comp/moy_ue.py
+++ b/app/comp/moy_ue.py
@@ -139,9 +139,9 @@ def df_load_modimpl_coefs(
 
     for mod_coef in mod_coefs:
         try:
-            modimpl_coefs_df[mod2impl[mod_coef.module_id]][
-                mod_coef.ue_id
-            ] = mod_coef.coef
+            modimpl_coefs_df.loc[mod_coef.ue_id, mod2impl[mod_coef.module_id]] = (
+                mod_coef.coef
+            )
         except IndexError:
             # il peut y avoir en base des coefs sur des modules ou UE
             # qui ont depuis été retirés de la formation
diff --git a/app/pe/moys/pe_sxtag.py b/app/pe/moys/pe_sxtag.py
index 6ddb1ee9f027b9c0537298e06f2a1bc01f4985f4..6b148cf53bfbaf52681bda6c33fa466685902911 100644
--- a/app/pe/moys/pe_sxtag.py
+++ b/app/pe/moys/pe_sxtag.py
@@ -333,7 +333,7 @@ class SxTag(pe_tabletags.TableTag):
         etud_moy = np.max(set_cube_no_nan, axis=2)
 
         # Fix les max non calculé -1 -> NaN
-        etud_moy[etud_moy < 0] = np.NaN
+        etud_moy[etud_moy < 0] = np.nan
 
         # Le dataFrame
         etud_moy_tag_df = pd.DataFrame(
diff --git a/requirements-3.11.txt b/requirements-3.11.txt
index e50f0cb71e1b3e5dd2ce308e2ba5f5473cdffd93..825c163518627b4c2260bcb985b0f7967d3a510b 100644
--- a/requirements-3.11.txt
+++ b/requirements-3.11.txt
@@ -1,114 +1,116 @@
-alembic==1.13.0
-astroid==3.0.1
+alembic==1.13.2
+astroid==3.2.4
 async-timeout==4.0.3
-attrs==23.1.0
-Babel==2.13.1
-black==23.11.0
-blinker==1.7.0
+attrs==23.2.0
+Babel==2.15.0
+black==24.4.2
+blinker==1.8.2
 Brotli==1.1.0
 cachelib==0.9.0
-certifi==2023.11.17
+certifi==2024.7.4
 cffi==1.16.0
 chardet==5.2.0
 charset-normalizer==3.3.2
 click==8.1.7
 cracklib==2.9.6
-cryptography==41.0.7
+cryptography==43.0.0
 cssselect2==0.7.0
+deepdiff==6.7.1
 Deprecated==1.2.14
-dill==0.3.7
-dnspython==2.4.2
-dominate==2.9.0
-email-validator==2.1.0.post1
+dill==0.3.8
+dnspython==2.6.1
+dominate==2.9.1
+email_validator==2.2.0
 ERAlchemy==1.2.10
 et-xmlfile==1.1.0
-exceptiongroup==1.2.0
-execnet==2.0.2
-flake8==6.1.0
-Flask==3.0.0
+exceptiongroup==1.2.2
+execnet==2.1.1
+flake8==7.1.0
+Flask==3.0.3
 flask-babel==4.0.0
-Flask-Caching==2.1.0
+Flask-Caching==2.3.0
 Flask-HTTPAuth==4.8.0
 Flask-JSON==0.4.0
 Flask-Login==0.6.3
-Flask-Mail==0.9.1
-Flask-Migrate==4.0.5
+Flask-Mail==0.10.0
+Flask-Migrate==4.0.7
 Flask-SQLAlchemy==3.1.1
 Flask-WTF==1.2.1
-fonttools==4.46.0
-gprof2dot==2022.7.29
-greenlet==3.0.1
-gunicorn==21.2.0
+fonttools==4.53.1
+gprof2dot==2024.6.6
+greenlet==3.0.3
+gunicorn==22.0.0
 html5lib==1.1
-icalendar==5.0.11
-idna==3.6
-importlib-metadata==7.0.0
+icalendar==5.0.13
+idna==3.7
+importlib_metadata==8.2.0
 iniconfig==2.0.0
-isort==5.12.0
-itsdangerous==2.1.2
-Jinja2==3.1.2
-lazy-object-proxy==1.9.0
-lxml==4.9.3
-Mako==1.3.0
-MarkupSafe==2.1.3
+isort==5.13.2
+itsdangerous==2.2.0
+Jinja2==3.1.4
+lazy-object-proxy==1.10.0
+lxml==5.2.2
+Mako==1.3.5
+MarkupSafe==2.1.5
 mccabe==0.7.0
-mypy==1.7.1
+mypy==1.11.0
 mypy-extensions==1.0.0
-numpy==1.26.2
-openpyxl==3.1.2
-packaging==23.2
-pandas==2.1.3
-pathspec==0.11.2
-Pillow==10.1.0
-platformdirs==4.1.0
-pluggy==1.3.0
+numpy==2.0.1
+openpyxl==3.1.5
+ordered-set==4.1.0
+packaging==24.1
+pandas==2.2.2
+pathspec==0.12.1
+pillow==10.4.0
+platformdirs==4.2.2
+pluggy==1.5.0
 psycopg2==2.9.9
-puremagic==1.15
+puremagic==1.26
 py==1.11.0
-pycodestyle==2.11.1
-pycparser==2.21
-pydot==1.4.2
-pydyf==0.8.0
-pyflakes==3.1.0
-pygraphviz==1.11
+pycodestyle==2.12.0
+pycparser==2.22
+pydot==3.0.1
+pydyf==0.11.0
+pyflakes==3.2.0
+pygraphviz==1.13
 PyJWT==2.8.0
-pylint==3.0.2
+pylint==3.2.6
 pylint-flask==0.6
 pylint-flask-sqlalchemy==0.2.0
 pylint-plugin-utils==0.8.2
-pyOpenSSL==23.3.0
-pyparsing==3.1.1
-pyphen==0.14.0
-pytest==7.4.3
-pytest-xdist==3.5.0
-python-dateutil==2.8.2
-python-docx==1.1.0
-python-dotenv==1.0.0
+pyOpenSSL==24.2.1
+pyparsing==3.1.2
+pyphen==0.16.0
+pytest==8.3.2
+pytest-xdist==3.6.1
+python-dateutil==2.9.0.post0
+python-docx==1.1.2
+python-dotenv==1.0.1
 python-editor==1.0.4
-pytz==2023.3.post1
+pytz==2024.1
 PyYAML==6.0.1
-redis==5.0.1
-reportlab==4.0.7
-requests==2.31.0
-rq==1.15.1
+redis==5.0.8
+reportlab==4.2.2
+requests==2.32.3
+rq==1.16.2
 six==1.16.0
 snakeviz==2.2.0
-SQLAlchemy==2.0.23
-tinycss2==1.2.1
+SQLAlchemy==2.0.31
+tinycss2==1.3.0
 toml==0.10.2
 tomli==2.0.1
-tomlkit==0.12.3
-tornado==6.4
+tomlkit==0.13.0
+tornado==6.4.1
 tuna==0.5.11
-typing_extensions==4.8.0
-tzdata==2023.3
-urllib3==2.1.0
+typing_extensions==4.12.2
+tzdata==2024.1
+urllib3==2.2.2
 visitor==0.1.3
-weasyprint==60.1
+weasyprint==62.3
 webencodings==0.5.1
-Werkzeug==3.0.1
+Werkzeug==3.0.3
 wrapt==1.16.0
-WTForms==3.1.1
+WTForms==3.1.2
 xmltodict==0.13.0
-zipp==3.17.0
+zipp==3.19.2
 zopfli==0.2.3