From c38040001c15e3aea105089c5b4640948368c314 Mon Sep 17 00:00:00 2001 From: Elodie MORIN Date: Tue, 6 Oct 2026 17:07:31 +0200 Subject: [PATCH 1/7] chore: upgrade Django v4.2 --- .../api/schema/nodes/annotation_campaign.py | 5 + backend/settings/development.py | 4 + backend/settings/production.py | 1 + poetry.lock | 98 +++++++++---------- pyproject.toml | 18 ++-- 5 files changed, 68 insertions(+), 58 deletions(-) diff --git a/backend/api/schema/nodes/annotation_campaign.py b/backend/api/schema/nodes/annotation_campaign.py index 1b2952c37..8385430ae 100644 --- a/backend/api/schema/nodes/annotation_campaign.py +++ b/backend/api/schema/nodes/annotation_campaign.py @@ -89,6 +89,7 @@ def resolve_labels_with_acoustic_features(self: AnnotationCampaign, info): def resolve_spectrograms_count(self: AnnotationCampaign, info): return ( Spectrogram.objects.filter(analysis__annotation_campaigns=self) + .order_by() .distinct() .count() ) @@ -108,6 +109,7 @@ def resolve_queryset(cls, queryset: QuerySet, info: GraphQLResolveInfo): AnnotationFileRange.objects.filter( annotation_phase__annotation_campaign_id=OuterRef("pk"), ) + .order_by() .annotate(sum=Func(F("files_count"), function="Sum")) .values("sum") ), @@ -119,6 +121,7 @@ def resolve_queryset(cls, queryset: QuerySet, info: GraphQLResolveInfo): annotation_phase__annotation_campaign_id=OuterRef("pk"), annotator_id=info.context.user.id, ) + .order_by() .annotate(sum=Func(F("files_count"), function="Sum")) .values("sum") ), @@ -129,6 +132,7 @@ def resolve_queryset(cls, queryset: QuerySet, info: GraphQLResolveInfo): annotation_phase__annotation_campaign_id=OuterRef("pk"), status=AnnotationTask.Status.FINISHED, ) + .order_by() .annotate(count=Func(F("id"), function="count")) .values("count") ), @@ -138,6 +142,7 @@ def resolve_queryset(cls, queryset: QuerySet, info: GraphQLResolveInfo): status=AnnotationTask.Status.FINISHED, annotator_id=info.context.user.id, ) + .order_by() .annotate(count=Func(F("id"), function="count")) .values("count") ), diff --git a/backend/settings/development.py b/backend/settings/development.py index 05e1c7cd0..939c01382 100644 --- a/backend/settings/development.py +++ b/backend/settings/development.py @@ -16,6 +16,10 @@ DEBUG = True ALLOWED_HOSTS = [] +CSRF_TRUSTED_ORIGINS = [ + "http://localhost:8000", + "http://localhost:5173", +] # Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases diff --git a/backend/settings/production.py b/backend/settings/production.py index 82cac360e..2ac2e6cce 100644 --- a/backend/settings/production.py +++ b/backend/settings/production.py @@ -17,6 +17,7 @@ # Prod settings SECRET_KEY = os.environ["SECRET_KEY"] ALLOWED_HOSTS = [os.environ["OSMOSE_HOST"]] +CSRF_TRUSTED_ORIGINS = [os.environ["OSMOSE_HOST"]] # Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases diff --git a/poetry.lock b/poetry.lock index 746fcf98c..7ec06142f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -809,20 +809,20 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "django" -version = "3.2.25" -description = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design." +version = "4.2.30" +description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" groups = ["main", "dev"] files = [ - {file = "Django-3.2.25-py3-none-any.whl", hash = "sha256:a52ea7fcf280b16f7b739cec38fa6d3f8953a5456986944c3ca97e79882b4e38"}, - {file = "Django-3.2.25.tar.gz", hash = "sha256:7ca38a78654aee72378594d63e51636c04b8e28574f5505dff630895b5472777"}, + {file = "django-4.2.30-py3-none-any.whl", hash = "sha256:4d07aaf1c62f9984842b67c2874ebbf7056a17be253860299b93ae1881faad65"}, + {file = "django-4.2.30.tar.gz", hash = "sha256:4ebc7a434e3819db6cf4b399fb5b3f536310a30e8486f08b66886840be84b37c"}, ] [package.dependencies] -asgiref = ">=3.3.2,<4" -pytz = "*" -sqlparse = ">=0.2.2" +asgiref = ">=3.6.0,<4" +sqlparse = ">=0.3.1" +tzdata = {version = "*", markers = "sys_platform == \"win32\""} [package.extras] argon2 = ["argon2-cffi (>=19.1.0)"] @@ -890,20 +890,19 @@ description = "Extended class for Django usage" optional = false python-versions = ">=3.9,<4.0" groups = ["main"] -files = [ - {file = "django_extension-0.1.4.tar.gz", hash = "sha256:dc35da7551d051efc75846df4a510e14660c9c4f2de269a6733b7274b2f6a976"}, -] +files = [] +develop = true [package.dependencies] -Django = ">=3.2,<4.0" -djangorestframework = ">=3.12.4,<4.0.0" -graphene-django = ">=3.2.3,<4.0.0" -graphene-django-optimizer = ">=0.10.0,<0.11.0" +Django = ">=4.2,<4.3" +djangorestframework = "^3.15" +graphene-django = "^3.2.3" +graphene-django-optimizer = "^0.10.0" graphene-django-pagination = {url = "https://github.com/instruct-br/graphene-django-pagination/archive/master.zip"} [package.source] -type = "url" -url = "https://github.com/Project-OSmOSE/django-extension/releases/download/v0.1.4/django_extension-0.1.4.tar.gz" +type = "directory" +url = "../django-extension" [[package]] name = "django-filter" @@ -1061,27 +1060,28 @@ django = ">=3.0" [[package]] name = "djangorestframework-simplejwt" -version = "4.8.0" +version = "5.5.1" description = "A minimal JSON Web Token authentication plugin for Django REST Framework" optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "djangorestframework_simplejwt-4.8.0-py3-none-any.whl", hash = "sha256:6f09f97cb015265e85d1d02dc6bfc299c72c231eecbe261c5bee5c6b2867f2b4"}, - {file = "djangorestframework_simplejwt-4.8.0.tar.gz", hash = "sha256:153c973c5c154baf566be431de8527c2bd62557fde7373ebcb0f02b73b28e07a"}, + {file = "djangorestframework_simplejwt-5.5.1-py3-none-any.whl", hash = "sha256:2c30f3707053d384e9f315d11c2daccfcb548d4faa453111ca19a542b732e469"}, + {file = "djangorestframework_simplejwt-5.5.1.tar.gz", hash = "sha256:e72c5572f51d7803021288e2057afcbd03f17fe11d484096f40a460abc76e87f"}, ] [package.dependencies] -django = "*" -djangorestframework = "*" -pyjwt = ">=2,<3" +django = ">=4.2" +djangorestframework = ">=3.14" +pyjwt = ">=1.7.1" [package.extras] -dev = ["Sphinx (>=1.6.5,<2)", "cryptography", "flake8", "ipython", "isort", "pep8", "pytest", "pytest-cov", "pytest-django", "pytest-watch", "pytest-xdist", "python-jose (==3.0.0)", "sphinx-rtd-theme (>=0.1.9)", "tox", "twine", "wheel"] -doc = ["Sphinx (>=1.6.5,<2)", "sphinx-rtd-theme (>=0.1.9)"] -lint = ["flake8", "isort", "pep8"] -python-jose = ["python-jose (==3.0.0)"] -test = ["cryptography", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "tox"] +crypto = ["cryptography (>=3.3.1)"] +dev = ["Sphinx", "cryptography", "freezegun", "ipython", "pre-commit", "pytest", "pytest-cov", "pytest-django", "pytest-watch", "pytest-xdist", "python-jose (==3.3.0)", "pyupgrade", "ruff", "sphinx_rtd_theme (>=0.1.9)", "tox", "twine", "wheel", "yesqa"] +doc = ["Sphinx", "sphinx_rtd_theme (>=0.1.9)"] +lint = ["pre-commit", "pyupgrade", "ruff", "yesqa"] +python-jose = ["python-jose (==3.3.0)"] +test = ["cryptography", "freezegun", "pytest", "pytest-cov", "pytest-django", "pytest-xdist", "tox"] [[package]] name = "djangorestframework-stubs" @@ -2244,28 +2244,27 @@ description = "PAM acquisition metadata" optional = false python-versions = ">=3.9,<4.0" groups = ["main"] -files = [ - {file = "v0.6.4.tar.gz", hash = "sha256:559f30114d507f36893b356c220cecc8d549f8f62c022609b44e69cb22ce2c3f"}, -] +files = [] +develop = true [package.dependencies] -Django = ">=3.2,<4.0" -django-admin-multiple-choice-list-filter = ">=0.1.1,<0.2.0" -django-better-admin-arrayfield = ">=1.4.2,<2.0.0" -django-durationwidget = ">=1.0.5,<2.0.0" -django-extension = {url = "https://github.com/Project-OSmOSE/django-extension/releases/download/v0.1.4/django_extension-0.1.4.tar.gz"} +Django = ">=4.2,<4.3" +django-admin-multiple-choice-list-filter = "^0.1.1" +django-better-admin-arrayfield = "^1.4.2" +django-durationwidget = "^1.0.5" +django-extension = {path = "../django-extension", develop = true} django-filter = ">=2" -django-model-prefix = ">=1.1.0,<2.0.0" -djangorestframework = ">=3.15.1,<4.0.0" -graphene-django = ">=3.2.3,<4.0.0" -graphene-django-optimizer = ">=0.10.0,<0.11.0" +django-model-prefix = "^1.1.0" +djangorestframework = "^3.15" +graphene-django = "^3.2.3" +graphene-django-optimizer = "^0.10.0" graphene-django-pagination = {url = "https://github.com/instruct-br/graphene-django-pagination/archive/master.zip"} -psycopg2-binary = ">=2.8.6,<3.0.0" -python-dotenv = ">=1.0.1,<2.0.0" +psycopg2-binary = "^2.9.10" +python-dotenv = "^1.0.1" [package.source] -type = "url" -url = "https://github.com/PAM-Standardization/metadatax/archive/refs/tags/v0.6.4.tar.gz" +type = "directory" +url = "../metadatax" [[package]] name = "mistune" @@ -3203,7 +3202,7 @@ version = "2026.1.post1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" -groups = ["main", "dev"] +groups = ["main"] files = [ {file = "pytz-2026.1.post1-py2.py3-none-any.whl", hash = "sha256:f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a"}, {file = "pytz-2026.1.post1.tar.gz", hash = "sha256:3378dde6a0c3d26719182142c56e60c7f9af7e968076f31aae569d72a0358ee1"}, @@ -3969,11 +3968,12 @@ version = "2025.2" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" -groups = ["main"] +groups = ["main", "dev"] files = [ {file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"}, {file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"}, ] +markers = {dev = "sys_platform == \"win32\""} [[package]] name = "uri-template" @@ -4090,5 +4090,5 @@ brotli = ["brotli"] [metadata] lock-version = "2.1" -python-versions = "^3.12" -content-hash = "cbac94afa9731d96e9824a11a77d861dcdbe981db9445a6adb84814cc75a5be1" +python-versions = ">=3.12,<4.0" +content-hash = "e37781899ba590ec644fa00783db529328ae4e39ffe3fb4c0e4cdb55440b5232" diff --git a/pyproject.toml b/pyproject.toml index 37a567ce8..7e751319b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,12 +7,12 @@ package-mode = false license = "MIT" [tool.poetry.dependencies] -python = "^3.12" -Django = "^3.2" -djangorestframework = "^3.12.4" -djangorestframework-simplejwt = "^4.6.0" +python = ">=3.12,<4.0" +Django = ">=4.2,<4.3" +djangorestframework = "^3.15" +djangorestframework-simplejwt = "^5.3" gunicorn = "^20.1.0" -psycopg2-binary = "^2.8.6" +psycopg2-binary = "^2.9.10" drf-spectacular = "^0.26.0" django-tinymce = "^3.6.1" python-dateutil = ">=2.4" @@ -26,10 +26,10 @@ graphene-django-optimizer = "^0.10.0" django-graphene-auth = "^1.1.1" django-seed = "^0.3.1" djangorestframework-stubs = "^3.16.7" -#django-extension = {path = "../django-extension", develop = true} -django-extension = { url = "https://github.com/Project-OSmOSE/django-extension/releases/download/v0.1.4/django_extension-0.1.4.tar.gz" } -#metadatax = {path = "../metadatax", develop=true} -metadatax = {url = "https://github.com/PAM-Standardization/metadatax/archive/refs/tags/v0.6.4.tar.gz"} +django-extension = {path = "../django-extension", develop = true} +#django-extension = { url = "https://github.com/Project-OSmOSE/django-extension/releases/download/v0.1.4/django_extension-0.1.4.tar.gz" } +metadatax = {path = "../metadatax", develop=true} +#metadatax = {url = "https://github.com/PAM-Standardization/metadatax/archive/refs/tags/v0.6.4.tar.gz"} legacy-cgi = "^2.6.4" [tool.poetry.group.dev.dependencies] From c67c4df843c216a79c819825bc2aa43664c5bc83 Mon Sep 17 00:00:00 2001 From: Elodie MORIN Date: Tue, 6 Oct 2026 17:40:37 +0200 Subject: [PATCH 2/7] chore: upgrade Django v5.2 --- .../schema/annotation/update_annotations.py | 8 ++ backend/settings/base.py | 11 ++- poetry.lock | 99 ++++++------------- pyproject.toml | 12 +-- 4 files changed, 51 insertions(+), 79 deletions(-) diff --git a/backend/api/tests/schema/annotation/update_annotations.py b/backend/api/tests/schema/annotation/update_annotations.py index adef6b362..12591f179 100644 --- a/backend/api/tests/schema/annotation/update_annotations.py +++ b/backend/api/tests/schema/annotation/update_annotations.py @@ -24,6 +24,14 @@ field } } + + _debug { + exceptions { + excType + message + stack + } + } } """ BASE_VARIABLES = { diff --git a/backend/settings/base.py b/backend/settings/base.py index fd36ca543..d6538784d 100644 --- a/backend/settings/base.py +++ b/backend/settings/base.py @@ -113,10 +113,6 @@ USE_I18N = True -USE_L10N = True - -USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.2/howto/static-files/ @@ -194,3 +190,10 @@ "MIDDLEWARE": ["graphene_django.debug.middleware.DjangoDebugMiddleware"], "TESTING_ENDPOINT": "/api/graphql/public", } + +STORAGES = { + "default": {"BACKEND": "django.core.files.storage.FileSystemStorage"}, + "staticfiles": { + "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage" + }, +} diff --git a/poetry.lock b/poetry.lock index 7ec06142f..450ee1fa3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -48,45 +48,6 @@ files = [ [package.dependencies] argon2-cffi-bindings = "*" -[[package]] -name = "argon2-cffi-bindings" -version = "21.2.0" -description = "Low-level CFFI bindings for Argon2" -optional = false -python-versions = ">=3.6" -groups = ["main"] -markers = "python_version >= \"3.14\"" -files = [ - {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, - {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, -] - -[package.dependencies] -cffi = ">=1.0.1" - -[package.extras] -dev = ["cogapp", "pre-commit", "pytest", "wheel"] -tests = ["pytest"] - [[package]] name = "argon2-cffi-bindings" version = "25.1.0" @@ -94,7 +55,6 @@ description = "Low-level CFFI bindings for Argon2" optional = false python-versions = ">=3.9" groups = ["main"] -markers = "python_version < \"3.14\"" files = [ {file = "argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f"}, {file = "argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b"}, @@ -809,18 +769,18 @@ profile = ["gprof2dot (>=2022.7.29)"] [[package]] name = "django" -version = "4.2.30" +version = "5.2.18" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main", "dev"] files = [ - {file = "django-4.2.30-py3-none-any.whl", hash = "sha256:4d07aaf1c62f9984842b67c2874ebbf7056a17be253860299b93ae1881faad65"}, - {file = "django-4.2.30.tar.gz", hash = "sha256:4ebc7a434e3819db6cf4b399fb5b3f536310a30e8486f08b66886840be84b37c"}, + {file = "django-5.2.18-py3-none-any.whl", hash = "sha256:92ed81d500be6408ecd704d7bd1366c534f30427bffcc63c5fefb129561aec7c"}, + {file = "django-5.2.18.tar.gz", hash = "sha256:461c5dd06d2ea16bd5ca37d3f46e4def1d6b0fe7588c6f4e2119517bb0af8b2d"}, ] [package.dependencies] -asgiref = ">=3.6.0,<4" +asgiref = ">=3.8.1" sqlparse = ">=0.3.1" tzdata = {version = "*", markers = "sys_platform == \"win32\""} @@ -854,18 +814,18 @@ files = [ [[package]] name = "django-debug-toolbar" -version = "4.3.0" +version = "5.2.0" description = "A configurable set of panels that display various debug information about the current request/response." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "django_debug_toolbar-4.3.0-py3-none-any.whl", hash = "sha256:e09b7dcb8417b743234dfc57c95a7c1d1d87a88844abd13b4c5387f807b31bf6"}, - {file = "django_debug_toolbar-4.3.0.tar.gz", hash = "sha256:0b0dddee5ea29b9cb678593bc0d7a6d76b21d7799cb68e091a2148341a80f3c4"}, + {file = "django_debug_toolbar-5.2.0-py3-none-any.whl", hash = "sha256:15627f4c2836a9099d795e271e38e8cf5204ccd79d5dbcd748f8a6c284dcd195"}, + {file = "django_debug_toolbar-5.2.0.tar.gz", hash = "sha256:9e7f0145e1a1b7d78fcc3b53798686170a5b472d9cf085d88121ff823e900821"}, ] [package.dependencies] -django = ">=3.2.4" +django = ">=4.2.9" sqlparse = ">=0.2" [[package]] @@ -888,14 +848,14 @@ name = "django-extension" version = "0.1.4" description = "Extended class for Django usage" optional = false -python-versions = ">=3.9,<4.0" +python-versions = ">=3.12,<3.14" groups = ["main"] files = [] develop = true [package.dependencies] -Django = ">=4.2,<4.3" -djangorestframework = "^3.15" +Django = ">=5.2,<5.3" +djangorestframework = "^3.16" graphene-django = "^3.2.3" graphene-django-optimizer = "^0.10.0" graphene-django-pagination = {url = "https://github.com/instruct-br/graphene-django-pagination/archive/master.zip"} @@ -1045,18 +1005,18 @@ django = ">=3.2" [[package]] name = "djangorestframework" -version = "3.15.1" +version = "3.18.1" description = "Web APIs for Django, made easy." optional = false -python-versions = ">=3.6" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "djangorestframework-3.15.1-py3-none-any.whl", hash = "sha256:3ccc0475bce968608cf30d07fb17d8e52d1d7fc8bfe779c905463200750cbca6"}, - {file = "djangorestframework-3.15.1.tar.gz", hash = "sha256:f88fad74183dfc7144b2756d0d2ac716ea5b4c7c9840995ac3bfd8ec034333c1"}, + {file = "djangorestframework-3.18.1-py3-none-any.whl", hash = "sha256:f1409d698967aaf82d5d98d76b549c8fba8bd92ebd0d83d24454508f72168dc2"}, + {file = "djangorestframework-3.18.1.tar.gz", hash = "sha256:605d79fa2ec2f02905492e5ea13d903c2d842d0b4c915a57f7bf02ab9f3c91dd"}, ] [package.dependencies] -django = ">=3.0" +django = ">=5.2" [[package]] name = "djangorestframework-simplejwt" @@ -1376,23 +1336,24 @@ graphql-core = ">=3.2,<3.3" [[package]] name = "gunicorn" -version = "20.1.0" +version = "23.0.0" description = "WSGI HTTP Server for UNIX" optional = false -python-versions = ">=3.5" +python-versions = ">=3.7" groups = ["main"] files = [ - {file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, - {file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"}, + {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, + {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, ] [package.dependencies] -setuptools = ">=3.0" +packaging = "*" [package.extras] -eventlet = ["eventlet (>=0.24.1)"] +eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] gevent = ["gevent (>=1.4.0)"] setproctitle = ["setproctitle"] +testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] tornado = ["tornado (>=0.2)"] [[package]] @@ -2242,20 +2203,20 @@ name = "metadatax" version = "0.6.4" description = "PAM acquisition metadata" optional = false -python-versions = ">=3.9,<4.0" +python-versions = ">=3.12,<3.14" groups = ["main"] files = [] develop = true [package.dependencies] -Django = ">=4.2,<4.3" +Django = ">=5.2,<5.3" django-admin-multiple-choice-list-filter = "^0.1.1" django-better-admin-arrayfield = "^1.4.2" django-durationwidget = "^1.0.5" django-extension = {path = "../django-extension", develop = true} django-filter = ">=2" django-model-prefix = "^1.1.0" -djangorestframework = "^3.15" +djangorestframework = "^3.16" graphene-django = "^3.2.3" graphene-django-optimizer = "^0.10.0" graphene-django-pagination = {url = "https://github.com/instruct-br/graphene-django-pagination/archive/master.zip"} @@ -4090,5 +4051,5 @@ brotli = ["brotli"] [metadata] lock-version = "2.1" -python-versions = ">=3.12,<4.0" -content-hash = "e37781899ba590ec644fa00783db529328ae4e39ffe3fb4c0e4cdb55440b5232" +python-versions = ">=3.12,<3.14" +content-hash = "ab43c76ff47e9a3f21b9434cfa833c346397359b39b959bb9e1f0ccb9750d865" diff --git a/pyproject.toml b/pyproject.toml index 7e751319b..f4ce68890 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,11 +7,11 @@ package-mode = false license = "MIT" [tool.poetry.dependencies] -python = ">=3.12,<4.0" -Django = ">=4.2,<4.3" -djangorestframework = "^3.15" -djangorestframework-simplejwt = "^5.3" -gunicorn = "^20.1.0" +python = ">=3.12,<3.14" +Django = ">=5.2,<5.3" +djangorestframework = "^3.16" +djangorestframework-simplejwt = "^5.5" +gunicorn = "^23.0" psycopg2-binary = "^2.9.10" drf-spectacular = "^0.26.0" django-tinymce = "^3.6.1" @@ -38,7 +38,7 @@ coverage = { extras = ["toml"], version = "^6.3" } black = "^22.10.0" pylint = "3.3.7" pylint-django = "2.6.1" -django-debug-toolbar = "^4.0.0" +django-debug-toolbar = "^5.0" faker = "^19.3.1" freezegun = "^1.2.2" django-seed = "^0.3.1" From 332b80f0c118c084a4663df9a1871e577eca2e07 Mon Sep 17 00:00:00 2001 From: Elodie MORIN Date: Tue, 6 Oct 2026 17:44:56 +0200 Subject: [PATCH 3/7] chore: Handle deprecated CheckConstraint --- backend/api/migrations/0001_v3_0.py | 10 +++++----- backend/api/migrations/0012_archive_constraints.py | 6 +++--- .../0013_rename_annotation_frequency_limits.py | 2 +- backend/api/models/annotation/annotation.py | 4 ++-- backend/api/models/annotation/annotation_campaign.py | 2 +- backend/api/models/annotation/annotation_phase.py | 2 +- backend/api/models/data/dataset.py | 2 +- backend/api/models/data/spectrogram.py | 2 +- backend/api/models/data/spectrogram_analysis.py | 2 +- 9 files changed, 16 insertions(+), 16 deletions(-) diff --git a/backend/api/migrations/0001_v3_0.py b/backend/api/migrations/0001_v3_0.py index 7cd4b9f91..f02b02e93 100644 --- a/backend/api/migrations/0001_v3_0.py +++ b/backend/api/migrations/0001_v3_0.py @@ -1224,7 +1224,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="spectrogramanalysis", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( ("legacy", True), models.Q(("data_duration__isnull", False), ("legacy", False)), _connector="OR", @@ -1235,14 +1235,14 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="spectrogram", constraint=models.CheckConstraint( - check=models.Q(("start__lt", django.db.models.expressions.F("end"))), + condition=models.Q(("start__lt", django.db.models.expressions.F("end"))), name="start is lower than end", ), ), migrations.AddConstraint( model_name="legacyspectrogramconfiguration", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( models.Q( ("linear_frequency_scale__isnull", True), ("multi_linear_frequency_scale__isnull", False), @@ -1302,7 +1302,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="annotation", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( models.Q( ("annotator__isnull", True), ("detector_configuration__isnull", False), @@ -1319,7 +1319,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="annotation", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( models.Q( ("end_frequency__isnull", True), ("end_time__isnull", True), diff --git a/backend/api/migrations/0012_archive_constraints.py b/backend/api/migrations/0012_archive_constraints.py index d09239b60..9f647823d 100644 --- a/backend/api/migrations/0012_archive_constraints.py +++ b/backend/api/migrations/0012_archive_constraints.py @@ -13,7 +13,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="annotationcampaign", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( models.Q( ("archived", True), ("archived_at__isnull", False), @@ -32,7 +32,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="annotationphase", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( models.Q( ("archived", True), ("archived_at__isnull", False), @@ -51,7 +51,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="dataset", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( models.Q( ("archived", True), ("archived_at__isnull", False), diff --git a/backend/api/migrations/0013_rename_annotation_frequency_limits.py b/backend/api/migrations/0013_rename_annotation_frequency_limits.py index 90b3af88c..6b10d28e6 100644 --- a/backend/api/migrations/0013_rename_annotation_frequency_limits.py +++ b/backend/api/migrations/0013_rename_annotation_frequency_limits.py @@ -27,7 +27,7 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="annotation", constraint=models.CheckConstraint( - check=models.Q( + condition=models.Q( models.Q( ("end_time__isnull", True), ("max_frequency__isnull", True), diff --git a/backend/api/models/annotation/annotation.py b/backend/api/models/annotation/annotation.py index c1d8f4cf1..506cd0694 100644 --- a/backend/api/models/annotation/annotation.py +++ b/backend/api/models/annotation/annotation.py @@ -101,7 +101,7 @@ class Meta: constraints = [ models.CheckConstraint( name="require_user_or_detector", - check=( + condition=( models.Q( annotator__isnull=True, detector_configuration__isnull=False ) @@ -112,7 +112,7 @@ class Meta: ), models.CheckConstraint( name="Annotation type", - check=( + condition=( models.Q( type="W", start_time__isnull=True, diff --git a/backend/api/models/annotation/annotation_campaign.py b/backend/api/models/annotation/annotation_campaign.py index 3d01ba59d..9c6ad4526 100644 --- a/backend/api/models/annotation/annotation_campaign.py +++ b/backend/api/models/annotation/annotation_campaign.py @@ -66,7 +66,7 @@ class Meta: constraints = [ CheckConstraint( name="campaign_archive_info", - check=Q( + condition=Q( archived=True, archived_at__isnull=False, archived_by__isnull=False ) | Q(archived=False, archived_at__isnull=True, archived_by__isnull=True), diff --git a/backend/api/models/annotation/annotation_phase.py b/backend/api/models/annotation/annotation_phase.py index 11e271a32..0387741be 100644 --- a/backend/api/models/annotation/annotation_phase.py +++ b/backend/api/models/annotation/annotation_phase.py @@ -60,7 +60,7 @@ class Meta: constraints = [ CheckConstraint( name="phase_archive_info", - check=Q( + condition=Q( archived=True, archived_at__isnull=False, archived_by__isnull=False ) | Q(archived=False, archived_at__isnull=True, archived_by__isnull=True), diff --git a/backend/api/models/data/dataset.py b/backend/api/models/data/dataset.py index 6458b5c5e..099481800 100644 --- a/backend/api/models/data/dataset.py +++ b/backend/api/models/data/dataset.py @@ -52,7 +52,7 @@ class Meta: constraints = [ CheckConstraint( name="dataset_archive_info", - check=Q( + condition=Q( archived=True, archived_at__isnull=False, archived_by__isnull=False ) | Q(archived=False, archived_at__isnull=True, archived_by__isnull=True), diff --git a/backend/api/models/data/spectrogram.py b/backend/api/models/data/spectrogram.py index a80aa12e6..d18d170c5 100644 --- a/backend/api/models/data/spectrogram.py +++ b/backend/api/models/data/spectrogram.py @@ -47,7 +47,7 @@ class Meta: ordering = ("start", "id") constraints = [ models.CheckConstraint( - name="start is lower than end", check=Q(start__lt=F("end")) + name="start is lower than end", condition=Q(start__lt=F("end")) ) ] diff --git a/backend/api/models/data/spectrogram_analysis.py b/backend/api/models/data/spectrogram_analysis.py index f35cd757c..e2988e35f 100644 --- a/backend/api/models/data/spectrogram_analysis.py +++ b/backend/api/models/data/spectrogram_analysis.py @@ -23,7 +23,7 @@ class Meta: constraints = [ CheckConstraint( name="spectrogram_analysis_legacy", - check=Q(legacy=True) | Q(legacy=False, data_duration__isnull=False), + condition=Q(legacy=True) | Q(legacy=False, data_duration__isnull=False), ) ] ordering = ("-created_at",) From 9baeffa69d4d098d2d78ef6e1db468784a82a729 Mon Sep 17 00:00:00 2001 From: Elodie MORIN Date: Tue, 6 Oct 2026 18:00:59 +0200 Subject: [PATCH 4/7] chore: install django-extension & metadatax from git --- poetry.lock | 50 ++++++++++++++++++++++++++------------------------ pyproject.toml | 8 ++++---- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/poetry.lock b/poetry.lock index 450ee1fa3..c99b8f905 100644 --- a/poetry.lock +++ b/poetry.lock @@ -845,24 +845,25 @@ Django = ">=1.11" [[package]] name = "django-extension" -version = "0.1.4" +version = "1.0.0" description = "Extended class for Django usage" optional = false python-versions = ">=3.12,<3.14" groups = ["main"] -files = [] -develop = true +files = [ + {file = "v1.0.0.tar.gz", hash = "sha256:1544a8a74ecf74fc91b45956d340738f5e33c2e972b717e0ce968afbcbf2e899"}, +] [package.dependencies] Django = ">=5.2,<5.3" -djangorestframework = "^3.16" -graphene-django = "^3.2.3" -graphene-django-optimizer = "^0.10.0" +djangorestframework = ">=3.16,<4.0" +graphene-django = ">=3.2.3,<4.0.0" +graphene-django-optimizer = ">=0.10.0,<0.11.0" graphene-django-pagination = {url = "https://github.com/instruct-br/graphene-django-pagination/archive/master.zip"} [package.source] -type = "directory" -url = "../django-extension" +type = "url" +url = "https://github.com/Project-OSmOSE/django-extension/archive/refs/tags/v1.0.0.tar.gz" [[package]] name = "django-filter" @@ -2200,32 +2201,33 @@ files = [ [[package]] name = "metadatax" -version = "0.6.4" +version = "1.0.0" description = "PAM acquisition metadata" optional = false python-versions = ">=3.12,<3.14" groups = ["main"] -files = [] -develop = true +files = [ + {file = "v1.0.0.tar.gz", hash = "sha256:f84e06c9efba3df3a121405451b18a9cc2ba94a419ed21d3f27b3e4e3594cba1"}, +] [package.dependencies] Django = ">=5.2,<5.3" -django-admin-multiple-choice-list-filter = "^0.1.1" -django-better-admin-arrayfield = "^1.4.2" -django-durationwidget = "^1.0.5" -django-extension = {path = "../django-extension", develop = true} +django-admin-multiple-choice-list-filter = ">=0.1.1,<0.2.0" +django-better-admin-arrayfield = ">=1.4.2,<2.0.0" +django-durationwidget = ">=1.0.5,<2.0.0" +django-extension = {url = "https://github.com/Project-OSmOSE/django-extension/archive/refs/tags/v1.0.0.tar.gz"} django-filter = ">=2" -django-model-prefix = "^1.1.0" -djangorestframework = "^3.16" -graphene-django = "^3.2.3" -graphene-django-optimizer = "^0.10.0" +django-model-prefix = ">=1.1.0,<2.0.0" +djangorestframework = ">=3.16,<4.0" +graphene-django = ">=3.2.3,<4.0.0" +graphene-django-optimizer = ">=0.10.0,<0.11.0" graphene-django-pagination = {url = "https://github.com/instruct-br/graphene-django-pagination/archive/master.zip"} -psycopg2-binary = "^2.9.10" -python-dotenv = "^1.0.1" +psycopg2-binary = ">=2.9.10,<3.0.0" +python-dotenv = ">=1.0.1,<2.0.0" [package.source] -type = "directory" -url = "../metadatax" +type = "url" +url = "https://github.com/PAM-Standardization/metadatax/archive/refs/tags/v1.0.0.tar.gz" [[package]] name = "mistune" @@ -4052,4 +4054,4 @@ brotli = ["brotli"] [metadata] lock-version = "2.1" python-versions = ">=3.12,<3.14" -content-hash = "ab43c76ff47e9a3f21b9434cfa833c346397359b39b959bb9e1f0ccb9750d865" +content-hash = "653cc78cced0947f9cac529cc91080503e7132c133ba5360fee78ac1e4711648" diff --git a/pyproject.toml b/pyproject.toml index f4ce68890..9aa53a7c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,10 +26,10 @@ graphene-django-optimizer = "^0.10.0" django-graphene-auth = "^1.1.1" django-seed = "^0.3.1" djangorestframework-stubs = "^3.16.7" -django-extension = {path = "../django-extension", develop = true} -#django-extension = { url = "https://github.com/Project-OSmOSE/django-extension/releases/download/v0.1.4/django_extension-0.1.4.tar.gz" } -metadatax = {path = "../metadatax", develop=true} -#metadatax = {url = "https://github.com/PAM-Standardization/metadatax/archive/refs/tags/v0.6.4.tar.gz"} +#django-extension = {path = "../django-extension", develop = true} +django-extension = { url = "https://github.com/Project-OSmOSE/django-extension/archive/refs/tags/v1.0.0.tar.gz" } +#metadatax = {path = "../metadatax", develop=true} +metadatax = {url = "https://github.com/PAM-Standardization/metadatax/archive/refs/tags/v1.0.0.tar.gz"} legacy-cgi = "^2.6.4" [tool.poetry.group.dev.dependencies] From 799a1465a942e545defee2218260dddff974da23 Mon Sep 17 00:00:00 2001 From: Elodie MORIN Date: Tue, 6 Oct 2026 18:04:39 +0200 Subject: [PATCH 5/7] black --- backend/api/migrations/0001_v3_0.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/backend/api/migrations/0001_v3_0.py b/backend/api/migrations/0001_v3_0.py index f02b02e93..d7fad91cd 100644 --- a/backend/api/migrations/0001_v3_0.py +++ b/backend/api/migrations/0001_v3_0.py @@ -1,11 +1,8 @@ # Generated by Django 3.2.25 on 2026-02-02 15:11 -from datetime import datetime - import django.contrib.postgres.fields import django.core.validators import django.utils.timezone -import tinymce.models from django.conf import settings from django.db import migrations, models @@ -1235,7 +1232,9 @@ class Migration(migrations.Migration): migrations.AddConstraint( model_name="spectrogram", constraint=models.CheckConstraint( - condition=models.Q(("start__lt", django.db.models.expressions.F("end"))), + condition=models.Q( + ("start__lt", django.db.models.expressions.F("end")) + ), name="start is lower than end", ), ), From 49803288b698ad1342aa6c6f21a8d41fc7cc3b82 Mon Sep 17 00:00:00 2001 From: Elodie MORIN Date: Thu, 8 Oct 2026 09:52:10 +0200 Subject: [PATCH 6/7] text(backend.storages): fix tests --- backend/storage/resolvers/_model.py | 19 ++++++++++++++----- .../schema/queries/spectrogram_paths.py | 14 ++++++++------ backend/storage/tests/schema/__init__.py | 1 + .../storage/tests/schema/spectrogram_paths.py | 6 ++---- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/backend/storage/resolvers/_model.py b/backend/storage/resolvers/_model.py index 69c8bb478..6b871f2a8 100644 --- a/backend/storage/resolvers/_model.py +++ b/backend/storage/resolvers/_model.py @@ -27,14 +27,20 @@ def _get_all_analysis_for_dataset( ) -> list[SpectrogramAnalysis | FailedItem]: analysis = [] - for a in dataset.spectrogram_analysis.all(): - if exists(join(dataset.path, a.path)): - analysis.append(a) + if dataset.pk: + # Not initialized datasets has neither pk nor spectrogram_analysis relations + for a in dataset.spectrogram_analysis.all(): + if exists(join(dataset.path, a.path)): + analysis.append(a) for a in super()._get_all_analysis_for_dataset( dataset=dataset, detailed=detailed ): - if not dataset.spectrogram_analysis.filter(path=a.path).exists(): + if ( + not dataset.pk + or not dataset.spectrogram_analysis.filter(path=a.path).exists() + ): + # Not initialized datasets has neither pk nor spectrogram_analysis relations analysis.append(a) return analysis @@ -42,7 +48,10 @@ def _get_all_analysis_for_dataset( def _get_analysis( self, dataset: Dataset, relative_path: str, detailed: bool = False ) -> SpectrogramAnalysis | FailedItem: - if dataset.spectrogram_analysis.filter(path=relative_path).exists(): + if ( + dataset.pk + and dataset.spectrogram_analysis.filter(path=relative_path).exists() + ): return dataset.spectrogram_analysis.get(path=relative_path) return super()._get_analysis( dataset=dataset, relative_path=relative_path, detailed=detailed diff --git a/backend/storage/schema/queries/spectrogram_paths.py b/backend/storage/schema/queries/spectrogram_paths.py index 01504f80d..4149f0cbd 100644 --- a/backend/storage/schema/queries/spectrogram_paths.py +++ b/backend/storage/schema/queries/spectrogram_paths.py @@ -1,5 +1,5 @@ import graphene -from django.shortcuts import get_object_or_404 +from django_extension.schema.errors import NotFoundError from django_extension.schema.permissions import GraphQLResolve, GraphQLPermissions from backend.api.models import ( @@ -22,11 +22,13 @@ def __init__(self, audio_path, spectrogram_path): @GraphQLResolve(permission=GraphQLPermissions.AUTHENTICATED) def resolve_paths(root, info, spectrogram_id: int, analysis_id: int): - relation: SpectrogramAnalysisRelation = get_object_or_404( - SpectrogramAnalysisRelation, - spectrogram_id=spectrogram_id, - analysis_id=analysis_id, - ) + try: + relation: SpectrogramAnalysisRelation = SpectrogramAnalysisRelation.objects.get( + spectrogram_id=spectrogram_id, + analysis_id=analysis_id, + ) + except SpectrogramAnalysisRelation.DoesNotExist: + raise NotFoundError resolver = Resolver(join(relation.analysis.dataset.path, relation.analysis.path)) paths = resolver.get_spectrogram_paths(relation=relation) diff --git a/backend/storage/tests/schema/__init__.py b/backend/storage/tests/schema/__init__.py index 184dbd4c9..c9ca9ba2a 100644 --- a/backend/storage/tests/schema/__init__.py +++ b/backend/storage/tests/schema/__init__.py @@ -1,3 +1,4 @@ from .browse import BrowseTestCase from .search import SearchTestCase from .import_dataset import ImportDatasetTestCase +from .spectrogram_paths import SpectrogramPathsTestCase diff --git a/backend/storage/tests/schema/spectrogram_paths.py b/backend/storage/tests/schema/spectrogram_paths.py index ed463eccc..46f8804d8 100644 --- a/backend/storage/tests/schema/spectrogram_paths.py +++ b/backend/storage/tests/schema/spectrogram_paths.py @@ -5,7 +5,7 @@ from django.test import override_settings from django_extension.tests import ExtendedTestCase -from backend.api.models import Spectrogram, SpectrogramAnalysis +from backend.api.models import SpectrogramAnalysis from backend.aplose.models import User from .import_dataset import ( QUERY as IMPORT_QUERY, @@ -50,9 +50,7 @@ def test_connected_empty_user(self): ) self.assertResponseHasErrors(response) content = json.loads(response.content) - self.assertEqual( - content["errors"][0]["message"], "No Spectrogram matches the given query." - ) + self.assertEqual(content["errors"][0]["message"], "Not found") @override_settings(DATASET_EXPORT_PATH=GOOD, VOLUMES_ROOT=VOLUMES_ROOT) def test(self): From b1cac54cd3e80efe94bf48ce00f5bb6e9a77fa51 Mon Sep 17 00:00:00 2001 From: Elodie MORIN Date: Thu, 8 Oct 2026 09:53:56 +0200 Subject: [PATCH 7/7] text(backend.storages): fix tests --- backend/storage/schema/queries/spectrogram_paths.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/storage/schema/queries/spectrogram_paths.py b/backend/storage/schema/queries/spectrogram_paths.py index 4149f0cbd..5c5e1419b 100644 --- a/backend/storage/schema/queries/spectrogram_paths.py +++ b/backend/storage/schema/queries/spectrogram_paths.py @@ -27,8 +27,8 @@ def resolve_paths(root, info, spectrogram_id: int, analysis_id: int): spectrogram_id=spectrogram_id, analysis_id=analysis_id, ) - except SpectrogramAnalysisRelation.DoesNotExist: - raise NotFoundError + except SpectrogramAnalysisRelation.DoesNotExist as e: + raise NotFoundError from e resolver = Resolver(join(relation.analysis.dataset.path, relation.analysis.path)) paths = resolver.get_spectrogram_paths(relation=relation)