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)
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)
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)
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)
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)
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) ]
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)
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)
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)