From f0c09f46eb4598ad93b5635f5ce63e289a5df75c Mon Sep 17 00:00:00 2001 From: Pierre Narcisi Date: Tue, 2 Apr 2024 16:54:21 +0200 Subject: [PATCH 1/3] Feat(areas) add a param too remove geom from query --- src/ref_geo/routes.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/ref_geo/routes.py b/src/ref_geo/routes.py index 9444ff5..749d536 100644 --- a/src/ref_geo/routes.py +++ b/src/ref_geo/routes.py @@ -6,7 +6,7 @@ import sqlalchemy as sa from sqlalchemy import func, select, asc, desc from sqlalchemy.sql import text -from sqlalchemy.orm import joinedload, undefer +from sqlalchemy.orm import joinedload, undefer, defer from werkzeug.exceptions import BadRequest from ref_geo.env import db @@ -182,6 +182,10 @@ def get_areas(): # change all args in a list of value params = {key: request.args.getlist(key) for key, value in request.args.items()} + # allow to format response + output_format = request.args.get("format", default="", type=str) + + marsh_params = dict(as_geojson=output_format == "geojson") query = ( select(LAreas) .options(joinedload("area_type").load_only("type_code")) @@ -213,20 +217,26 @@ def get_areas(): if "area_name" in params: query = query.where(LAreas.area_name.ilike("%{}%".format(params.get("area_name")[0]))) - limit = int(params.get("limit")[0]) if params.get("limit") else 100 + without_geom = False + if "without_geom" in params: + without_geom = params.get("without_geom")[0] + query = query.options(defer("geom")) + marsh_params["exclude"] = ["geom"] - # allow to format response - format = request.args.get("format", default="", type=str) + limit = int(params.get("limit")[0]) if params.get("limit") else 100 fields = {"area_type.type_code"} - if format == "geojson": + if output_format == "geojson" and not without_geom: fields |= {"+geom_4326"} query = query.options(undefer("geom_4326")) areas = db.session.scalars(query.limit(limit)).unique().all() - response = AreaSchema(only=fields, as_geojson=format == "geojson").dump(areas, many=True) - if format == "geojson": + marsh_params["only"] = fields + + response = AreaSchema(**marsh_params).dump(areas, many=True) + + if output_format == "geojson": # retro-compat: return a list of Features instead of the FeatureCollection response = response["features"] return response From ad7348d0afbf9b3a96cc174dd24512c2813f2775 Mon Sep 17 00:00:00 2001 From: Pierre Narcisi Date: Wed, 3 Apr 2024 10:43:01 +0200 Subject: [PATCH 2/3] Feat(areas) clean code --- src/ref_geo/routes.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/ref_geo/routes.py b/src/ref_geo/routes.py index 749d536..460354c 100644 --- a/src/ref_geo/routes.py +++ b/src/ref_geo/routes.py @@ -173,6 +173,7 @@ def get_municipalities(): return jsonify(MunicipalitySchema().dump(municipalities, many=True)) +# FIXME: Transform to post and change the post /areas @routes.route("/areas", methods=["GET"]) def get_areas(): """ @@ -180,12 +181,12 @@ def get_areas(): .. :quickref: Ref Geo; """ # change all args in a list of value - params = {key: request.args.getlist(key) for key, value in request.args.items()} + params = request.args # allow to format response output_format = request.args.get("format", default="", type=str) - marsh_params = dict(as_geojson=output_format == "geojson") + marsh_params = dict(as_geojson=(output_format == "geojson")) query = ( select(LAreas) .options(joinedload("area_type").load_only("type_code")) @@ -193,7 +194,7 @@ def get_areas(): ) if "enable" in params: - enable_param = params["enable"][0].lower() + enable_param = params["enable"].lower() accepted_enable_values = ["true", "false", "all"] if enable_param not in accepted_enable_values: response = { @@ -209,17 +210,18 @@ def get_areas(): query = query.where(LAreas.enable == True) if "id_type" in params: - query = query.where(LAreas.id_type.in_(params["id_type"])) + query = query.where(LAreas.id_type.in_(params.getlist("id_type"))) if "type_code" in params: - query = query.where(LAreas.area_type.has(BibAreasTypes.type_code.in_(params["type_code"]))) + query = query.where( + LAreas.area_type.has(BibAreasTypes.type_code.in_(params.getlist("type_code"))) + ) if "area_name" in params: - query = query.where(LAreas.area_name.ilike("%{}%".format(params.get("area_name")[0]))) + query = query.where(LAreas.area_name.ilike("%{}%".format(params.get("area_name")))) - without_geom = False - if "without_geom" in params: - without_geom = params.get("without_geom")[0] + without_geom = params.get("without_geom", False, lambda x: x == "true") + if without_geom: query = query.options(defer("geom")) marsh_params["exclude"] = ["geom"] From 75ecd59986b574d5c28742fd6d9b00e57b34e38b Mon Sep 17 00:00:00 2001 From: Pierre Narcisi Date: Wed, 3 Apr 2024 10:53:38 +0200 Subject: [PATCH 3/3] Feat(ares) add tests --- src/ref_geo/tests/test_ref_geo.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ref_geo/tests/test_ref_geo.py b/src/ref_geo/tests/test_ref_geo.py index e0ac3da..d490445 100644 --- a/src/ref_geo/tests/test_ref_geo.py +++ b/src/ref_geo/tests/test_ref_geo.py @@ -296,6 +296,21 @@ def test_get_areas_area_name(self): assert response.status_code == 200 assert response.json[0]["area_name"] == CITY + def test_get_without_geom(self): + response = self.client.get( + url_for("ref_geo.get_areas"), query_string={"without_geom": "false"} + ) + assert response.status_code == 200 + for area in response.json: + assert "geom" in area + + response = self.client.get( + url_for("ref_geo.get_areas"), query_string={"without_geom": "true"} + ) + assert response.status_code == 200 + for area in response.json: + assert not "geom" in area + def test_get_areas_as_geojson(self, area_commune): """ This test can't try to get only one commune