Пример #1
0
def _process_street_single(request):
    """Procesa una request GET para consultar datos de calles.
    En caso de ocurrir un error de parseo, se retorna una respuesta HTTP 400.

    Args:
        request (flask.Request): Request GET de flask.

    Raises:
        data.DataConnectionException: En caso de ocurrir un error de
            conexión con la capa de manejo de datos.

    Returns:
        flask.Response: respuesta HTTP

    """
    try:
        qs_params = params.PARAMS_STREETS.parse_get_params(request.args)
    except params.ParameterParsingException as e:
        return formatter.create_param_error_response_single(e.errors, e.fmt)

    query, fmt = _build_street_query_format(qs_params)

    if fmt[N.FORMAT] == 'shp':
        query['fields'] += (N.GEOM, )

    es = get_elasticsearch()
    search = data.StreetsSearch(query)
    data.ElasticsearchSearch.run_searches(es, [search])

    query_result = QueryResult.from_entity_list(search.result.hits,
                                                search.result.total,
                                                search.result.offset)

    return formatter.create_ok_response(N.STREETS, query_result, fmt)
Пример #2
0
    def get_query_result(self, params):
        """Retorna los resultados de la búsqueda de direcciones. Este método
        debe ser invocado luego de haber recorrido todo el iterador obtenido
        con 'planner_steps'.

        Se utiliza la longitud de los resultados encontrados como 'total', y
        0 como 'offset'. Esto se debe a que ninguna de las búsquedas ejecutadas
        representa correctamente el total de resultados posibles que existen (
        ya que gran parte del procesamiento se hace localmente, combinando
        resultados de las mismas).

        Args:
            params (dict): Parámetros recibidos que generaron la consulta.

        Returns:
            QueryResult: Resultados de la búsqueda de direcciones.

        """
        if not self._between_hits:
            return QueryResult.empty(params)

        # TODO: Revisar total y offset
        return QueryResult.from_entity_list(self._between_hits,
                                            params,
                                            len(self._between_hits),
                                            0)
Пример #3
0
def _process_entity_bulk(request, name, param_parser, key_translations):
    """Procesa una request POST para consultar datos de una lista de entidades.
    En caso de ocurrir un error de parseo, se retorna una respuesta HTTP 400.

    Args:
        request (flask.Request): Request POST de flask.
        name (str): Nombre de la entidad.
        param_parser (ParameterSet): Objeto utilizado para parsear los
            parámetros.
        key_translations (dict): Traducciones de keys a utilizar para convertir
            los diccionarios de parámetros del usuario a una lista de
            diccionarios representando las queries a Elasticsearch.

    Raises:
        data.DataConnectionException: En caso de ocurrir un error de
            conexión con la capa de manejo de datos.

    Returns:
        flask.Response: respuesta HTTP

    """
    try:
        body_params = param_parser.parse_post_params(request.args,
                                                     request.json, name)
    except params.ParametersParseException as e:
        return formatter.create_param_error_response_bulk(e.errors)

    queries = []
    formats = []
    for parsed_params in body_params:
        # Construir query a partir de parámetros
        query = utils.translate_keys(parsed_params.values,
                                     key_translations,
                                     ignore=[N.FLATTEN, N.FORMAT])

        # Construir reglas de formato a partir de parámetros
        fmt = {
            key: parsed_params.values[key]
            for key in [N.FLATTEN, N.FIELDS] if key in parsed_params.values
        }

        queries.append(query)
        formats.append(fmt)

    es = get_elasticsearch()
    search_class = data.entity_search_class(name)
    searches = [search_class(query) for query in queries]

    data.ElasticsearchSearch.run_searches(es, searches)

    query_results = [
        QueryResult.from_entity_list(search.result.hits,
                                     params.received_values(),
                                     search.result.total, search.result.offset)
        for search, params in zip(searches, body_params)
    ]

    return formatter.create_ok_response_bulk(name, query_results, formats)
Пример #4
0
def _process_entity_single(request, name, param_parser, key_translations):
    """Procesa una request GET para consultar datos de una entidad.
    En caso de ocurrir un error de parseo, se retorna una respuesta HTTP 400.

    Args:
        request (flask.Request): Request GET de flask.
        name (str): Nombre de la entidad.
        param_parser (ParameterSet): Objeto utilizado para parsear los
            parámetros.
        key_translations (dict): Traducciones de keys a utilizar para convertir
            el diccionario de parámetros del usuario a un diccionario
            representando una query a Elasticsearch.

    Raises:
        data.DataConnectionException: En caso de ocurrir un error de
            conexión con la capa de manejo de datos.

    Returns:
        flask.Response: respuesta HTTP

    """
    try:
        qs_params = param_parser.parse_get_params(request.args)
    except params.ParametersParseException as e:
        return formatter.create_param_error_response_single(e.errors, e.fmt)

    # Construir query a partir de parámetros
    query = utils.translate_keys(qs_params.values,
                                 key_translations,
                                 ignore=[N.FLATTEN, N.FORMAT])

    # Construir reglas de formato a partir de parámetros
    fmt = {
        key: qs_params.values[key]
        for key in [N.FLATTEN, N.FIELDS, N.FORMAT] if key in qs_params.values
    }

    if fmt[N.FORMAT] == 'shp':
        query['fields'] += (N.GEOM, )

    es = get_elasticsearch()
    search_class = data.entity_search_class(name)
    search = search_class(query)

    data.ElasticsearchSearch.run_searches(es, [search])

    query_result = QueryResult.from_entity_list(search.result.hits,
                                                qs_params.received_values(),
                                                search.result.total,
                                                search.result.offset)

    return formatter.create_ok_response(name, query_result, fmt)
Пример #5
0
    def get_query_result(self):
        """Retorna los resultados de la búsqueda de direcciones. Este método
        debe ser invocado luego de haber recorrido todo el iterador obtenido
        con 'planner_steps'.

        Returns:
            QueryResult: Resultados de la búsqueda de direcciones.

        """
        address_hits = self._build_address_hits()
        return QueryResult.from_entity_list(address_hits,
                                            self._elasticsearch_result.total,
                                            self._elasticsearch_result.offset)
Пример #6
0
def run_street_queries(es, params_list, queries, formats):
    """Punto de entrada del módulo 'street.py'. Toma una lista de consultas de
    calles y las ejecuta, devolviendo los resultados QueryResult.

    Args:
        es (Elasticsearch): Conexión a Elasticsearch.
        params_list (list): Lista de ParametersParseResult.
        queries (list): Lista de búsquedas, generadas a partir de
            'params_list'.
        formats (list): Lista de parámetros de formato de cada búsqueda, en
            forma de diccionario.

    Returns:
        list: Lista de QueryResult, una por cada búsqueda.

    """

    searches = []
    for query, fmt in zip(queries, formats):
        processed_query = query.copy()

        if N.FULL_NAME in fmt[N.FIELDS]:
            # La nomenclatura incluye el nombre de la provincia y del depto.,
            # agregar esos campos a la query para luego poder extraer sus
            # nombres.
            processed_query['fields'] += (N.STATE, N.DEPT)

        searches.append(data.StreetsSearch(processed_query))

    data.ElasticsearchSearch.run_searches(es, searches)

    for search, fmt in zip(searches, formats):
        if N.FULL_NAME in fmt[N.FIELDS]:
            # Agregar nomenclatura a cada hit del resultado.
            for hit in search.result.hits:
                full_name = '{}, {}, {}'.format(hit[N.NAME],
                                                hit[N.DEPT][N.NAME],
                                                hit[N.STATE][N.NAME])
                hit[N.FULL_NAME] = full_name

    return [
        QueryResult.from_entity_list(search.result.hits,
                                     params.received_values(),
                                     search.result.total, search.result.offset)
        for search, params in zip(searches, params_list)
    ]
Пример #7
0
    def get_query_result(self):
        """Retorna los resultados de la búsqueda de direcciones. Este método
        debe ser invocado luego de haber recorrido todo el iterador obtenido
        con 'planner_steps'.

        Se utiliza el 'total' y 'offset' de la búsqueda #3 (intersecciones)
        como metadatos de los resultados.

        Returns:
            QueryResult: Resultados de la búsqueda de direcciones.

        """
        if not self._intersection_hits:
            return QueryResult.empty()

        return QueryResult.from_entity_list(self._intersection_hits,
                                            self._intersections_result.total,
                                            self._intersections_result.offset)
Пример #8
0
    def get_query_result(self, params):
        """Retorna los resultados de la búsqueda de direcciones. Este método
        debe ser invocado luego de haber recorrido todo el iterador obtenido
        con 'planner_steps'.

        Args:
            params (dict): Parámetros recibidos que generaron la consulta.

        Returns:
            QueryResult: Resultados de la búsqueda de direcciones.

        """
        if not self._elasticsearch_result:
            return QueryResult.empty(params)

        address_hits = self._build_address_hits()
        return QueryResult.from_entity_list(address_hits,
                                            params,
                                            self._elasticsearch_result.total,
                                            self._elasticsearch_result.offset)
Пример #9
0
def _process_street_bulk(request):
    """Procesa una request POST para consultar datos de calles.
    En caso de ocurrir un error de parseo, se retorna una respuesta HTTP 400.

    Args:
        request (flask.Request): Request POST de flask.

    Raises:
        data.DataConnectionException: En caso de ocurrir un error de
            conexión con la capa de manejo de datos.

    Returns:
        flask.Response: respuesta HTTP

    """
    try:
        body_params = params.PARAMS_STREETS.parse_post_params(
            request.args, request.json, N.STREETS)
    except params.ParameterParsingException as e:
        return formatter.create_param_error_response_bulk(e.errors)

    queries = []
    formats = []
    for parsed_params in body_params:
        query, fmt = _build_street_query_format(parsed_params)
        queries.append(query)
        formats.append(fmt)

    es = get_elasticsearch()
    searches = [data.StreetsSearch(query) for query in queries]

    data.ElasticsearchSearch.run_searches(es, searches)

    query_results = [
        QueryResult.from_entity_list(search.result.hits, search.result.total,
                                     search.result.offset)
        for search in searches
    ]

    return formatter.create_ok_response_bulk(N.STREETS, query_results, formats)