예제 #1
0
def test_empty_names():
    filter = ResultFilter()
    place_infos = {
        "names": [".", "Niort"],
        "postcodes": ["12345"],
        "place_type": "admin",
    }
    assert filter.check("Niort", **place_infos)
예제 #2
0
def test_match_postcode_only():
    filter = ResultFilter()
    place_infos = {
        "names": ["Niort"],
        "postcodes": ["79000"],
        "place_type": "admin",
    }
    assert filter.check("79000", **place_infos)
    assert not filter.check("79", **place_infos)
예제 #3
0
def test_match_word_prefix():
    filter = ResultFilter(match_word_prefix=True)

    place_infos = {
        "names": ["5 rue Gustave Zédé", "5, Zédéstraße"],
        "postcodes": ["79000"],
        "place_type": "house",
    }

    assert filter.check("5 rue Gust Zédé", **place_infos)
예제 #4
0
def test_match_postcode_by_prefix():
    filter = ResultFilter()
    place_infos = {
        "names": ["Niort"],
        "postcodes": ["79000"],
        "place_type": "admin",
    }
    assert filter.check("Niort 79", **place_infos)
    # At least 2 chars must match
    assert not filter.check("Niort 7", **place_infos)
예제 #5
0
def test_min_matching_words():
    filter = ResultFilter(min_matching_words=3)

    place_infos = {
        "names": ["5 rue Gustave Zédé", "5, Zédéstraße"],
        "postcodes": ["79000"],
        "place_type": "house",
    }

    assert filter.check("5 rue Gustave Eiffel", **place_infos)
    assert not filter.check("5 rue Paul Dupont", **place_infos)
예제 #6
0
def test_rank():
    filter = ResultFilter()

    rennes = {
        "names": ["rue de Paris"],
        "admins": ["Rennes"],
        "place_type": "street",
    }

    paris = {
        "names": ["rue de Rennes"],
        "admins": ["Paris"],
        "place_type": "street",
    }

    assert filter.rank("rue de Rennes, Paris", **paris) > filter.rank(
        "rue de Rennes, Paris", **rennes)

    assert filter.rank("rue de Paris, Rennes", **rennes) > filter.rank(
        "rue de Paris, Rennes", **paris)
예제 #7
0
from idunn.datasources.pages_jaunes import pj_source
from idunn.geocoder.nlu_client import nlu_client, NluClientException
from idunn.geocoder.bragi_client import bragi_client
from idunn.geocoder.models import QueryParams
from idunn.geocoder.models.geocodejson import IntentionType
from idunn.places import place_from_id, Place
from idunn.api.places_list import get_places_bbox_impl, PlacesQueryParam
from idunn.utils import maps_urls
from idunn.utils.regions import get_region_lonlat
from idunn.utils.result_filter import ResultFilter
from idunn.instant_answer import normalize
from .constants import PoiSource
from ..utils.verbosity import Verbosity

logger = logging.getLogger(__name__)
result_filter = ResultFilter()

nlu_allowed_languages = settings["NLU_ALLOWED_LANGUAGES"].split(",")
ia_max_query_length = int(settings["IA_MAX_QUERY_LENGTH"])


class InstantAnswerResult(BaseModel):
    places: List[Place] = Field(
        description="List of relevant places to display on the instant answer. "
        "At most 1 place is returned if no broad intention has been detected.")
    source: Optional[PoiSource] = Field(description=(
        "Data source for the returned place, or data provider for the list of results. This "
        "field is not provided when the instant answer relates to an admnistrative area or an "
        "address."))
    intention_bbox: Optional[Tuple[float, float, float, float]] = Field(
        description=
예제 #8
0
import logging
from fastapi import Body, Depends
from starlette.responses import Response

from idunn import settings
from idunn.api.geocoder import get_autocomplete
from idunn.utils.result_filter import ResultFilter
from idunn.instant_answer import normalize
from ..geocoder.models import ExtraParams, QueryParams

logger = logging.getLogger(__name__)
result_filter = ResultFilter(match_word_prefix=True, min_matching_words=3)

nlu_allowed_languages = settings["NLU_ALLOWED_LANGUAGES"].split(",")


async def search(
    query: QueryParams = Depends(QueryParams), extra: ExtraParams = Body(ExtraParams())
):
    """
    Perform a query which is intended to display a relevant result directly (as
    opposed to `autocomplete` which gives a list of plausible results).

    Similarly to `instant_answer`, the result will need some quality checks.
    """
    # Fetch autocomplete results which will be filtered
    query.q = normalize(query.q)
    if query.q == "":
        return Response(status_code=200, content=build_empty_query_content_response())
    response = await get_autocomplete(query, extra)
예제 #9
0
def test_filter():
    filter = ResultFilter()

    place_infos = {
        "names": ["5 rue Gustave Zédé", "5, Zédéstraße"],
        "postcodes": ["79000"],
        "place_type": "house",
    }

    # Case is ignored
    assert filter.check("5 RuE gustave ZÉDÉ", **place_infos)

    # Extra terms are not allowed
    assert not filter.check("5 rue gustave zédé restaurant", **place_infos)

    # Numbers must match
    assert not filter.check("1 rue gustave zédé", **place_infos)
    assert not filter.check("5 rue gustave zédé 75015", **place_infos)

    # Accents can be omitted
    assert filter.check("5 rue gustave zede", **place_infos)

    # Accents in the request still matter
    assert not filter.check("5 rue güstâve zédé", **place_infos)

    # A single spelling mistake is allowed per word
    assert filter.check("5 ruee gustaev zde", **place_infos)
    assert not filter.check("5 rueee gusteav ze", **place_infos)
    assert not filter.check("5 rue gusteav zede", **place_infos)
    assert not filter.check("5 rue gusta zede", **place_infos)

    # Dashes are ignored
    assert filter.check("5 rue gustave--zede", **place_infos)

    # Bis/Ter/... are ignored in the query
    assert filter.check("5 Bis rue gustave zede", **place_infos)
    assert filter.check("5Ter rue gustave zede", **place_infos)

    # Support some abreviations
    assert filter.check("5 r gustave zédé", **place_infos)
    assert not filter.check("5 u gustave zédé", **place_infos)

    # Either names can match
    assert filter.check("5 zédéstraße", **place_infos)

    # Queries that match a small part of the request are ignored, postcode and
    # admins matter in relevant matching words.
    assert not filter.check("101 dalmatiens",
                            names=["101 rue des dalmatiens"],
                            place_type="address")

    assert filter.check(
        query="Paris 2e",
        names=["2e Arrondissement"],
        admins=["Paris"],
        postcodes=["75002"],
        place_type="admin",
    )