Skip to content

Commit

Permalink
feat(profil_precision): add filter profil_precisions in api
Browse files Browse the repository at this point in the history
  • Loading branch information
hlecuyer committed Nov 20, 2024
1 parent a75b885 commit 8cd7122
Show file tree
Hide file tree
Showing 13 changed files with 245 additions and 13 deletions.
2 changes: 1 addition & 1 deletion api/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ After running the main dag:
source .venv/bin/activate

# Launch command to import the Admin Express database
python src/data_inclusion/api/cli.py import_admin_express
python src/data_inclusion/api/cli.py import_communes

# Launch command to import data
python src/data_inclusion/api/cli.py load_inclusion_data
Expand Down
15 changes: 12 additions & 3 deletions api/requirements/dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ colorama==0.4.6
# via tox
cryptography==43.0.3
# via data-inclusion-api (setup.py)
data-inclusion-schema==0.17.0
data-inclusion-schema==0.20.0.dev1
# via data-inclusion-api (setup.py)
distlib==0.3.9
# via virtualenv
Expand Down Expand Up @@ -128,6 +128,8 @@ pandas==2.2.3
# via
# data-inclusion-api (setup.py)
# geopandas
pendulum==3.0.0
# via data-inclusion-schema
platformdirs==4.3.6
# via
# tox
Expand Down Expand Up @@ -172,7 +174,10 @@ pyproj==3.7.0
pyproject-api==1.8.0
# via tox
python-dateutil==2.9.0.post0
# via pandas
# via
# pandas
# pendulum
# time-machine
python-dotenv==1.0.1
# via
# data-inclusion-api (setup.py)
Expand Down Expand Up @@ -212,6 +217,8 @@ sqlparse==0.5.1
# via fastapi-debug-toolbar
starlette==0.41.2
# via fastapi
time-machine==2.16.0
# via pendulum
tox==4.23.2
# via data-inclusion-api (setup.py)
tqdm==4.66.6
Expand All @@ -226,7 +233,9 @@ typing-extensions==4.12.2
# pydantic-core
# sqlalchemy
tzdata==2024.2
# via pandas
# via
# pandas
# pendulum
urllib3==2.2.3
# via
# minio
Expand Down
15 changes: 12 additions & 3 deletions api/requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ click==8.1.7
# uvicorn
cryptography==43.0.3
# via data-inclusion-api (setup.py)
data-inclusion-schema==0.17.0
data-inclusion-schema==0.20.0.dev1
# via data-inclusion-api (setup.py)
dnspython==2.7.0
# via email-validator
Expand Down Expand Up @@ -102,6 +102,8 @@ pandas==2.2.3
# via
# data-inclusion-api (setup.py)
# geopandas
pendulum==3.0.0
# via data-inclusion-schema
psycopg2==2.9.10
# via data-inclusion-api (setup.py)
pyarrow==18.0.0
Expand All @@ -128,7 +130,10 @@ pyogrio==0.10.0
pyproj==3.7.0
# via geopandas
python-dateutil==2.9.0.post0
# via pandas
# via
# pandas
# pendulum
# time-machine
python-dotenv==1.0.1
# via
# data-inclusion-api (setup.py)
Expand Down Expand Up @@ -162,6 +167,8 @@ sqlalchemy==2.0.36
# geoalchemy2
starlette==0.41.2
# via fastapi
time-machine==2.16.0
# via pendulum
tqdm==4.66.6
# via data-inclusion-api (setup.py)
typing-extensions==4.12.2
Expand All @@ -174,7 +181,9 @@ typing-extensions==4.12.2
# pydantic-core
# sqlalchemy
tzdata==2024.2
# via pandas
# via
# pandas
# pendulum
urllib3==2.2.3
# via
# minio
Expand Down
12 changes: 10 additions & 2 deletions api/requirements/test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ click==8.1.7
# uvicorn
cryptography==43.0.3
# via data-inclusion-api (setup.py)
data-inclusion-schema==0.17.0
data-inclusion-schema==0.20.0.dev1
# via data-inclusion-api (setup.py)
dnspython==2.7.0
# via email-validator
Expand Down Expand Up @@ -117,6 +117,8 @@ pandas==2.2.3
# via
# data-inclusion-api (setup.py)
# geopandas
pendulum==3.0.0
# via data-inclusion-schema
pluggy==1.5.0
# via pytest
psycopg2==2.9.10
Expand Down Expand Up @@ -163,6 +165,8 @@ python-dateutil==2.9.0.post0
# via
# faker
# pandas
# pendulum
# time-machine
python-dotenv==1.0.1
# via
# data-inclusion-api (setup.py)
Expand Down Expand Up @@ -201,6 +205,8 @@ starlette==0.41.2
# via fastapi
syrupy==4.7.2
# via data-inclusion-api (setup.py)
time-machine==2.16.0
# via pendulum
tqdm==4.66.6
# via data-inclusion-api (setup.py)
typing-extensions==4.12.2
Expand All @@ -214,7 +220,9 @@ typing-extensions==4.12.2
# pydantic-core
# sqlalchemy
tzdata==2024.2
# via pandas
# via
# pandas
# pendulum
urllib3==2.2.3
# via
# minio
Expand Down
2 changes: 1 addition & 1 deletion api/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"sqlalchemy",
"tqdm",
"uvicorn[standard]",
"data-inclusion-schema==0.17.0",
"data-inclusion-schema==0.20.0-dev1",
],
extras_require={
"test": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""add profils_precisions field in service
Revision ID: c947102bb23f
Revises: 68fe052dc63c
Create Date: 2024-10-28 17:22:23.374004
"""

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects.postgresql import TSVECTOR

# revision identifiers, used by Alembic.
revision = "c947102bb23f"
down_revision = "68fe052dc63c"
branch_labels = None
depends_on = None


def upgrade() -> None:
op.add_column(
"api__services",
sa.Column(
"profils_precisions",
sa.String(),
nullable=True,
),
)
# can't use ARRAY_TO_STRING mutable function in a generation expression.
# So it must be overiden by an immutable function
op.execute("""
CREATE OR REPLACE FUNCTION generate_profils_precisions(
profils_precisions TEXT,
profils TEXT[]
)
RETURNS TSVECTOR AS $$
BEGIN
RETURN to_tsvector(
'french',
COALESCE(profils_precisions, '') ||
' '||
COALESCE(ARRAY_TO_STRING(profils, ' '), '')
);
END;
$$ LANGUAGE plpgsql IMMUTABLE;
""")
op.add_column(
"api__services",
sa.Column(
"searchable_index_profils_precisions",
TSVECTOR(),
sa.Computed(
"generate_profils_precisions(profils_precisions, profils)",
persisted=True,
),
),
)
op.create_index(
"ix_api__services_searchable_index_profils_precisions",
"api__services",
["searchable_index_profils_precisions"],
postgresql_using="gin",
)


def downgrade() -> None:
op.drop_column("api__services", "searchable_index_profils_precisions")
op.drop_column("api__services", "profils_precisions")
12 changes: 12 additions & 0 deletions api/src/data_inclusion/api/inclusion_data/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from datetime import date

import sqlalchemy as sqla
from sqlalchemy import Computed
from sqlalchemy.dialects.postgresql import TSVECTOR
from sqlalchemy.orm import Mapped, mapped_column, relationship

from data_inclusion.api.core.db import Base
Expand Down Expand Up @@ -92,6 +94,16 @@ class Service(Base):
presentation_resume: Mapped[str | None]
prise_rdv: Mapped[str | None]
profils: Mapped[list[str] | None]
profils_precisions: Mapped[str | None]
# generate_profils_precisions is a function that generates
# a TSVECTOR from profils_precisions and profils
# cf: 20241028_172223_c947102bb23f_add_profils_autres_field_in_service.py
searchable_index_profils_precisions: Mapped[str | None] = mapped_column(
TSVECTOR,
Computed(
"generate_profils_precisions(profils_precisions, profils)", persisted=True
),
)
recurrence: Mapped[str | None]
source: Mapped[str]
structure_id: Mapped[str]
Expand Down
10 changes: 10 additions & 0 deletions api/src/data_inclusion/api/inclusion_data/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,15 @@ def search_services_endpoint(
"""
),
] = None,
profils_precisions: Annotated[
Optional[str],
fastapi.Query(
description="""Une recherche elargie sur les profils.
Chaque résultat renvoyé correspond a la recherche fulltext sur
ce champs.
"""
),
] = None,
types: Annotated[
Optional[list[di_schema.TypologieService]],
fastapi.Query(
Expand Down Expand Up @@ -420,6 +429,7 @@ def search_services_endpoint(
frais=frais,
modes_accueil=modes_accueil,
profils=profils,
profils_precisions=profils_precisions,
types=types,
search_point=search_point,
include_outdated=inclure_suspendus,
Expand Down
19 changes: 18 additions & 1 deletion api/src/data_inclusion/api/inclusion_data/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import geoalchemy2
import sqlalchemy as sqla
from sqlalchemy import orm
from sqlalchemy import func, orm

import fastapi

Expand Down Expand Up @@ -137,6 +137,17 @@ def filter_services_by_profils(
)


def filter_services_by_profils_precisions(
query: sqla.Select,
profils_precisions: str,
):
return query.filter(
models.Service.searchable_index_profils_precisions.bool_op("@@")(
func.websearch_to_tsquery("french", profils_precisions)
)
)


def filter_services_by_types(
query: sqla.Select,
types: list[di_schema.TypologieService],
Expand Down Expand Up @@ -265,6 +276,7 @@ def filter_services(
thematiques: list[di_schema.Thematique] | None = None,
frais: list[di_schema.Frais] | None = None,
profils: list[di_schema.Profil] | None = None,
profils_precisions: str | None = None,
modes_accueil: list[di_schema.ModeAccueil] | None = None,
types: list[di_schema.TypologieService] | None = None,
include_outdated: bool | None = False,
Expand Down Expand Up @@ -292,6 +304,9 @@ def filter_services(
if not include_outdated:
query = filter_outdated_services(query)

if profils_precisions is not None:
query = filter_services_by_profils_precisions(query, profils_precisions)

return query


Expand Down Expand Up @@ -354,6 +369,7 @@ def search_services(
frais: list[di_schema.Frais] | None = None,
modes_accueil: list[di_schema.ModeAccueil] | None = None,
profils: list[di_schema.Profil] | None = None,
profils_precisions: str | None = None,
types: list[di_schema.TypologieService] | None = None,
search_point: str | None = None,
include_outdated: bool | None = False,
Expand Down Expand Up @@ -454,6 +470,7 @@ def search_services(
thematiques=thematiques,
frais=frais,
profils=profils,
profils_precisions=profils_precisions,
modes_accueil=modes_accueil,
types=types,
include_outdated=include_outdated,
Expand Down
Loading

0 comments on commit 8cd7122

Please sign in to comment.