Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Dependencies) Upgrade SQLAlchemy to 1.4 and other requirements (flask 3.0), remove Debian 10 and Python 3.7 support #2751

Merged
merged 70 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
d5e84b2
feat(dependencies) changing requirements, compiling it with python3.9
Pierre-Narcisi Oct 13, 2023
9e19e0d
Swith to flask-login:
TheoLechemia Sep 12, 2023
87fef28
bump TX
TheoLechemia Oct 18, 2023
88a6f6b
bump UH-auth
TheoLechemia Oct 18, 2023
d7f2f4e
Merge branch 'header-auth' of github.com:PnX-SI/GeoNature into feat/u…
Pierre-Narcisi Oct 24, 2023
3434970
Merge branch 'develop' of github.com:PnX-SI/GeoNature into feat/updat…
Pierre-Narcisi Oct 26, 2023
3988f57
merge
Pierre-Narcisi Oct 26, 2023
a04e52b
merge requirement-dev.txt
Pierre-Narcisi Oct 26, 2023
dc99e4d
feat(requirements) fixing a lot of warnings
Pierre-Narcisi Oct 26, 2023
c1cf14f
fix(warning) fixed a lot of warnings
Pierre-Narcisi Nov 2, 2023
c26c413
fix(warning) fixed a lot of warnings
Pierre-Narcisi Nov 2, 2023
aab827a
Merge branch 'feat/update-dependencies' of https://github.com/PnX-SI/…
jacquesfize Nov 2, 2023
107dbbf
test_reports --> drop warnings (85 left)
jacquesfize Nov 2, 2023
3e9955b
fix warnings test_pr_occhab
jacquesfize Nov 3, 2023
c725434
fix(warnings) fix test_gn_common warnings
Pierre-Narcisi Nov 3, 2023
07921bc
fix warnings test_gn_meta.py
jacquesfize Nov 3, 2023
8d6e753
fix warnings test_notifications.py
jacquesfize Nov 3, 2023
ec891b3
fix warnings test_pr_occtax.py
jacquesfize Nov 3, 2023
f09a923
fix warnings test_gn_profiles.py
jacquesfize Nov 3, 2023
51830b6
backref for TSources
jacquesfize Nov 6, 2023
4c20973
fix(sqlalchemy) synthese warnings and errors
Pierre-Narcisi Nov 6, 2023
0561a77
Merge branch 'feat/update-dependencies' of github.com:PnX-SI/GeoNatur…
Pierre-Narcisi Nov 6, 2023
2ca86ce
fix test_validation (OUTER JOIN duplicates du to SyntheseQuery.query…
jacquesfize Nov 6, 2023
91b36b5
fix warnings
Pierre-Narcisi Nov 6, 2023
4c29dc5
Merge branch 'feat/update-dependencies' of github.com:PnX-SI/GeoNatur…
Pierre-Narcisi Nov 6, 2023
cb7d4ab
fix warnings
Pierre-Narcisi Nov 6, 2023
5523bfc
debug occhab due to sqlalchemy 1.4 changes
jacquesfize Nov 6, 2023
9c9d094
fix lint and change commit of submodule
jacquesfize Nov 8, 2023
6138f65
rm TDatasetDetails & TAcquisitionFrameworkDetails
bouttier Nov 12, 2023
ff62534
improve models
bouttier Nov 12, 2023
5710450
check OCCHAB active before importing models
bouttier Nov 12, 2023
66af932
fix tests + translate query to 2.0 SQLA
jacquesfize Nov 13, 2023
d2881ff
move is_already_joined in synthese utils
bouttier Nov 12, 2023
7417dad
fixup! improve models
bouttier Nov 13, 2023
1e16527
fixup! improve models
bouttier Nov 13, 2023
01df218
merge last modification in develop
jacquesfize Nov 13, 2023
dc84b63
add field dataset in the marshmallow schema
jacquesfize Nov 13, 2023
f3d9c60
Drop debian 10 support + fix lint in dataformservice
jacquesfize Nov 13, 2023
3bb9ca5
Update requirements since flask-test now supports flask3
jacquesfize Nov 13, 2023
b679a7e
translate sqla query in gn_commons (admin,repo,route,validation) and …
jacquesfize Nov 14, 2023
e079116
feat(sqlalchemy1.4)gn_profiles query
Pierre-Narcisi Nov 15, 2023
160d444
translate query (2.0 style) and test for gn_meta
jacquesfize Nov 15, 2023
1925c0c
translate query to SQLA 2.0 style in gn_permissions
jacquesfize Nov 15, 2023
a7546c2
include new SQLAlchemy class
jacquesfize Nov 15, 2023
e8da41e
Bump flask
Pierre-Narcisi Nov 16, 2023
7499d11
integration of CustomSelect (meta,synthese,test)
jacquesfize Nov 16, 2023
ce35c73
Merge branch 'feat/update-dependencies' of https://github.com/PnX-SI/…
jacquesfize Nov 16, 2023
ff52964
feat(sqlachemy1.4) occhab
Pierre-Narcisi Nov 16, 2023
ffc740b
fix error caused by CustomSelect + apply review from ellie
jacquesfize Nov 16, 2023
6b05073
Last warnings
Pierre-Narcisi Nov 16, 2023
6bbdf49
fix tests
jacquesfize Nov 16, 2023
d820423
feat(sqlalchemy1.4) starting occtax
Pierre-Narcisi Nov 17, 2023
b682719
fix missing unique() + bad loading with metadata/aquisition_framework
jacquesfize Nov 17, 2023
49852b6
fix error
jacquesfize Nov 17, 2023
1a62a1c
fix lint
jacquesfize Nov 20, 2023
9b544af
Merge branch 'develop' of https://github.com/PnX-SI/GeoNature into fe…
jacquesfize Nov 20, 2023
11fadfe
fix lint
jacquesfize Nov 20, 2023
39ade8e
tests: revert session changes after err requests
bouttier Nov 21, 2023
aacbc3a
occhab: fixes & improved tests
bouttier Nov 21, 2023
e00e237
occtax: avoid modifying sa model when using dump
bouttier Nov 21, 2023
dd6f0d8
(fix) fix errors found while testing GeoNature directly
jacquesfize Nov 22, 2023
a192943
fix error
jacquesfize Nov 23, 2023
f6336c5
Feat/add tests (#2813)
jacquesfize Dec 5, 2023
8b2762c
fix occtax tests
Pierre-Narcisi Dec 6, 2023
8bf303b
split test for install_gn_modules
jacquesfize Dec 6, 2023
1f919c9
Improve occtax tests
Pierre-Narcisi Dec 6, 2023
feac3b0
Merge branch 'feat/update-dependencies' of github.com:PnX-SI/GeoNatur…
Pierre-Narcisi Dec 6, 2023
4234609
fix commands tests
Pierre-Narcisi Dec 6, 2023
124271c
skip test_get_datasets_fields (wait for fix)
jacquesfize Dec 6, 2023
d1cbfaf
test content on gn_meta
jacquesfize Dec 6, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,16 @@ jobs:
strategy:
fail-fast: false
matrix:
debian-version: [ '10', '11', '12' ]
debian-version: ["11", "12"]
include:
- debian-version: '10'
python-version: '3.7'
postgres-version: '11'
postgis-version: '2.5'
- debian-version: '11'
python-version: '3.9'
postgres-version: '13'
postgis-version: '3.2'
- debian-version: '12'
python-version: '3.11'
postgres-version: '15'
postgis-version: '3.3'
- debian-version: "11"
python-version: "3.9"
postgres-version: "13"
postgis-version: "3.2"
- debian-version: "12"
python-version: "3.11"
postgres-version: "15"
postgis-version: "3.3"

name: Debian ${{ matrix.debian-version }}

Expand Down
4 changes: 2 additions & 2 deletions backend/geonature/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from flask_mail import Message
from flask_cors import CORS
from flask_login import current_user
from flask_sqlalchemy import before_models_committed
from flask_sqlalchemy.track_modifications import before_models_committed
from werkzeug.middleware.proxy_fix import ProxyFix
from werkzeug.middleware.shared_data import SharedDataMiddleware
from werkzeug.middleware.dispatcher import DispatcherMiddleware
Expand Down Expand Up @@ -86,7 +86,7 @@ class MyJSONProvider(DefaultJSONProvider):
@staticmethod
def default(o):
if isinstance(o, Row):
return dict(o)
return o._asdict()
return DefaultJSONProvider.default(o)


Expand Down
49 changes: 34 additions & 15 deletions backend/geonature/core/command/create_gn_module.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import importlib
import os
import sys
import subprocess
import site
import importlib
import subprocess
import sys
from pathlib import Path

import pathlib # For testing purposes
import click
import geonature.utils.config
from click import ClickException

from geonature.utils.env import ROOT_DIR
from geonature.utils.module import iter_modules_dist, get_dist_from_code, module_db_upgrade

from geonature.core.command.main import main
import geonature.utils.config
from geonature.utils.config import config
from geonature.utils.command import (
install_frontend_dependencies,
create_frontend_module_config,
build_frontend,
create_frontend_module_config,
install_frontend_dependencies,
)
from geonature.utils.config import config
from geonature.utils.env import ROOT_DIR
from geonature.utils.module import get_dist_from_code, iter_modules_dist, module_db_upgrade


@main.command()
Expand All @@ -30,6 +29,29 @@
@click.option("--build", type=bool, required=False, default=True)
@click.option("--upgrade-db", type=bool, required=False, default=True)
def install_gn_module(x_arg, module_path, module_code, build, upgrade_db):
"""
Command definition to install a GeoNature module

Parameters
----------
x_arg : list
additional arguments
module_path : str
path of the module directory
module_code : str
code of the module, deprecated in future release
build : boolean
is the frontend rebuild
upgrade_db : boolean
migrate the revision associated with the module

Raises
------
ClickException
No module found with the given module code
ClickException
No module code was detected in the code
"""
click.echo("Installation du backend…")
subprocess.run(f"pip install -e '{module_path}'", shell=True, check=True)

Expand All @@ -40,7 +62,7 @@ def install_gn_module(x_arg, module_path, module_code, build, upgrade_db):
if module_code:
# load python package
module_dist = get_dist_from_code(module_code)
if not module_dist:
if not module_dist: # FIXME : technically can't go there...
raise ClickException(f"Aucun module ayant pour code {module_code} n’a été trouvé")
else:
for module_dist in iter_modules_dist():
Expand All @@ -56,7 +78,6 @@ def install_gn_module(x_arg, module_path, module_code, build, upgrade_db):
raise ClickException(
f"Impossible de détecter le code du module, essayez de le spécifier."
)

# symlink module in exernal module directory
module_frontend_path = (module_path / "frontend").resolve()
module_symlink = ROOT_DIR / "frontend" / "external_modules" / module_code.lower()
Expand All @@ -68,7 +89,6 @@ def install_gn_module(x_arg, module_path, module_code, build, upgrade_db):
else:
click.echo(f"Création du lien symbolique {module_symlink} → {module_frontend_path}")
os.symlink(module_frontend_path, module_symlink)

if (Path(module_path) / "frontend" / "package-lock.json").is_file():
click.echo("Installation des dépendances frontend…")
install_frontend_dependencies(module_frontend_path)
Expand All @@ -80,7 +100,6 @@ def install_gn_module(x_arg, module_path, module_code, build, upgrade_db):
click.echo("Rebuild du frontend …")
build_frontend()
click.secho("Rebuild du frontend terminé.", fg="green")

if upgrade_db:
click.echo("Installation / mise à jour de la base de données…")
if not module_db_upgrade(module_dist, x_arg=x_arg):
Expand Down
4 changes: 2 additions & 2 deletions backend/geonature/core/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from flask import current_app, request, json, redirect
from werkzeug.exceptions import Unauthorized, InternalServerError, HTTPException, BadRequest
from werkzeug.urls import url_encode
from urllib.parse import urlencode
from marshmallow.exceptions import ValidationError


Expand Down Expand Up @@ -32,7 +32,7 @@ def handle_unauthenticated_request(e):
next_url = request.full_path
else:
next_url = request.url
query_string = url_encode({"next": next_url})
query_string = urlencode({"next": next_url})
return redirect(f"{base_url}{login_path}?{query_string}")


Expand Down
16 changes: 10 additions & 6 deletions backend/geonature/core/gn_commons/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,20 @@ class BibFieldAdmin(CruvedProtectedMixin, ModelView):
"field_order": {"label": "Ordre"},
"additional_attributes": {"label": "Attribut additionnels"},
"modules": {
"query_factory": lambda: DB.session.query(TModules).filter(
TModules.module_code.in_(
current_app.config["ADDITIONAL_FIELDS"]["IMPLEMENTED_MODULES"]
"query_factory": lambda: DB.session.scalars(
DB.select(TModules).where(
TModules.module_code.in_(
current_app.config["ADDITIONAL_FIELDS"]["IMPLEMENTED_MODULES"]
)
)
)
},
"objects": {
"query_factory": lambda: DB.session.query(PermObject).filter(
PermObject.code_object.in_(
current_app.config["ADDITIONAL_FIELDS"]["IMPLEMENTED_OBJECTS"]
"query_factory": lambda: DB.session.scalars(
DB.select(PermObject).where(
PermObject.code_object.in_(
current_app.config["ADDITIONAL_FIELDS"]["IMPLEMENTED_OBJECTS"]
)
)
)
},
Expand Down
26 changes: 10 additions & 16 deletions backend/geonature/core/gn_commons/medias/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,15 @@
Route permettant de manipuler les fichiers
contenus dans gn_media
"""
import json

from flask import Blueprint, request, current_app, redirect, jsonify
from flask import request, redirect, jsonify
from werkzeug.exceptions import NotFound

from geonature.core.gn_commons.repositories import TMediaRepository, TMediumRepository
from geonature.core.gn_commons.repositories import TMediaRepository
from geonature.core.gn_commons.models import TMedias
from geonature.utils.env import DB
from utils_flask_sqla.response import json_resp, json_resp_accept_empty_list


from geonature.utils.errors import (
GeoNatureError,
GeonatureApiError,
)

from ..routes import routes


Expand All @@ -29,8 +22,9 @@ def get_medias(uuid_attached_row):
.. :quickref: Commons;
"""

res = DB.session.query(TMedias).filter(TMedias.uuid_attached_row == uuid_attached_row).all()

res = DB.session.scalars(
DB.select(TMedias).filter(TMedias.uuid_attached_row == uuid_attached_row)
).all()
return [r.as_dict() for r in (res or [])]


Expand All @@ -41,10 +35,10 @@ def get_media(id_media):
.. :quickref: Commons;
"""

m = TMediaRepository(id_media=id_media).media
if not m:
media = TMediaRepository(id_media=id_media).media
if not media:
raise NotFound
return jsonify(m.as_dict())
return jsonify(media.as_dict())


@routes.route("/media", methods=["POST", "PUT"])
Expand All @@ -59,14 +53,14 @@ def insert_or_update_media(id_media=None):
"""

# gestion des parametres de route

# @TODO utilisé quelque part ?
if request.files:
file = request.files["file"]
else:
file = None

data = {}
# Useful ?
# Useful ? @jacquesfize YES ! -> used when add media when adding a taxon occurrence
if request.form:
formData = dict(request.form)
for key in formData:
Expand Down
9 changes: 4 additions & 5 deletions backend/geonature/core/gn_commons/models/additional_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ class TAdditionalFields(DB.Model):
exportable = DB.Column(DB.Boolean, default=True)
field_order = DB.Column(DB.Integer)
type_widget = DB.relationship("BibWidgets")
bib_nomenclature_type = DB.relationship(
"BibNomenclaturesTypes",
primaryjoin="BibNomenclaturesTypes.mnemonique == TAdditionalFields.code_nomenclature_type",
)
bib_nomenclature_type = DB.relationship("BibNomenclaturesTypes")
additional_attributes = DB.Column(JSONB)
multiselect = DB.Column(DB.Boolean)
api = DB.Column(DB.String)
Expand All @@ -50,7 +47,9 @@ class TAdditionalFields(DB.Model):
secondary=cor_field_module,
)
objects = DB.relationship(PermObject, secondary=cor_field_object)
datasets = DB.relationship(TDatasets, secondary=cor_field_dataset)
datasets = DB.relationship(
TDatasets, secondary=cor_field_dataset, back_populates="additional_fields"
)

def __str__(self):
return f"{self.field_label} ({self.description})"
13 changes: 9 additions & 4 deletions backend/geonature/core/gn_commons/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class TMedias(DB.Model):
id_table_location = DB.Column(
DB.Integer, ForeignKey("gn_commons.bib_tables_location.id_table_location")
)
unique_id_media = DB.Column(UUID(as_uuid=True), default=select([func.uuid_generate_v4()]))
unique_id_media = DB.Column(UUID(as_uuid=True), default=select(func.uuid_generate_v4()))
uuid_attached_row = DB.Column(UUID(as_uuid=True))
title_fr = DB.Column(DB.Unicode)
title_en = DB.Column(DB.Unicode)
Expand Down Expand Up @@ -206,19 +206,24 @@ class TValidations(DB.Model):
nomenclature_valid_status = relationship(
TNomenclatures,
foreign_keys=[id_nomenclature_valid_status],
lazy="joined",
lazy="joined", # FIXME: remove and manually join when needed
)
id_validator = DB.Column(DB.Integer, ForeignKey(User.id_role))
validator_role = DB.relationship(User)
validation_auto = DB.Column(DB.Boolean)
validation_comment = DB.Column(DB.Unicode)
validation_date = DB.Column(DB.TIMESTAMP)
validation_auto = DB.Column(DB.Boolean)
validation_label = DB.relationship(TNomenclatures)
# FIXME: remove and use nomenclature_valid_status
validation_label = DB.relationship(
TNomenclatures,
foreign_keys=[id_nomenclature_valid_status],
overlaps="nomenclature_valid_status", # overlaps expected
)


last_validation_query = (
select([TValidations])
select(TValidations)
.order_by(TValidations.validation_date.desc())
.limit(1)
.alias("last_validation")
Expand Down
Loading