Example #1
0
def get_place(id: str,
              request: Request,
              lang: str = None,
              type=None,
              verbosity=DEFAULT_VERBOSITY) -> Place:
    """Main handler that returns the requested place"""
    es = get_elasticsearch()
    verbosity = validate_verbosity(verbosity)
    lang = validate_lang(lang)

    # Handle place from "pages jaunes"
    if id.startswith(pj_source.PLACE_ID_PREFIX):
        pj_place = pj_source.get_place(id)
        log_place_request(pj_place, request.headers)
        return pj_place.load_place(lang, verbosity)

    #  Otherwise handle places from the ES db
    es_place = fetch_es_place(id, es, INDICES, type)

    places = {
        "admin": Admin,
        "street": Street,
        "addr": Address,
        "poi": POI,
    }
    loader = places.get(es_place.get("_type"))

    if loader is None:
        prometheus.exception("FoundPlaceWithWrongType")
        raise Exception("Place with id '{}' has a wrong type: '{}'".format(
            id, es_place[0].get("_type")))

    place = loader(es_place["_source"])
    log_place_request(place, request.headers)
    return place.load_place(lang, verbosity)
Example #2
0
 def _get_value(cls, key):
     try:
         value_stored = cls._connection.get(key)
         return value_stored
     except RedisError as exc:
         prometheus.exception("RedisError")
         raise CacheNotAvailable from exc
Example #3
0
def get_place(id,
              es: Elasticsearch,
              indices: IndexNames,
              headers: Headers,
              lang=None,
              type=None,
              verbosity=DEFAULT_VERBOSITY) -> Place:
    log_custom_headers(id, headers)
    """Main handler that returns the requested place"""
    verbosity = validate_verbosity(verbosity)
    lang = validate_lang(lang)

    if id.startswith(pj_source.PLACE_ID_PREFIX):
        pj_place = pj_source.get_place(id)
        return pj_place.load_place(lang, verbosity)

    es_place = fetch_es_place(id, es, indices, type)

    places = {
        "admin": Admin,
        "street": Street,
        "addr": Address,
        "poi": POI,
    }
    loader = places.get(es_place.get('_type'))

    if loader is None:
        prometheus.exception("FoundPlaceWithWrongType")
        raise Exception("Place with id '{}' has a wrong type: '{}'".format(
            id, es_place[0].get('_type')))

    return loader(es_place['_source']).load_place(lang, verbosity)
Example #4
0
def get_place(id, es: Elasticsearch, indices: IndexNames, settings: Settings, lang=None, type=None, verbosity=DEFAULT_VERBOSITY) -> Place:
    """Main handler that returns the requested place"""
    if verbosity not in VERBOSITY_LEVELS:
        raise BadRequest(
            status_code=400,
            detail={"message": f"verbosity {verbosity} does not belong to the set of possible verbosity values={VERBOSITY_LEVELS}"}
        )

    if not lang:
        lang = settings['DEFAULT_LANGUAGE']
    lang = lang.lower()

    es_place = fetch_es_place(id, es, indices, type)

    places = {
        "admin": Admin,
        "street": Street,
        "addr": Address,
        "poi": POI,
    }

    loader = places.get(es_place[0].get('_type'))

    if loader is None:
        prometheus.exception("FoundPlaceWithWrongType")
        logger.error("The place with the id {} has a wrong type: {}".format(id, es_place[0].get('_type')))
        return None

    return loader.load_place(es_place[0]['_source'], lang, settings, verbosity)
Example #5
0
 def _set_value(cls, key, value, expire=settings["WIKI_CACHE_TIMEOUT"], raise_on_error=False):
     try:
         cls._connection.set(key, value, ex=expire)
     except RedisError:
         prometheus.exception("RedisError")
         if raise_on_error:
             raise
         logging.exception("Got a RedisError")
Example #6
0
File: utils.py Project: Qwant/idunn
def place_from_id(id: str, type=None, follow_redirect=False):
    """
    :param id: place id
    :param type: Optional type to restrict query in Elasticsearch
    :param follow_redirect: if false, RedirectToPlaceId may be raised
    :return: Place
    """
    try:
        namespace, suffix = id.split(":", 1)
    except ValueError as exc:
        raise InvalidPlaceId(id) from exc

    # Handle place from "pages jaunes"
    if namespace == pj_source.PLACE_ID_NAMESPACE:
        return pj_source.get_place(id)

    # Simple latlon place id
    if namespace == Latlon.PLACE_ID_NAMESPACE:
        return Latlon.from_id(id)

    # Otherwise handle places from the ES db
    es = get_elasticsearch()
    try:
        es_place = fetch_es_place(id, es, type)
    except PlaceNotFound as exc:
        if namespace == "addr":
            # A Latlon place can be used as a substitute for a "addr:<lon>;<lat>" id
            # that is not present in the database anymore
            try:
                lon, lat = suffix.split(":", 1)[0].split(";")
                latlon_id = Latlon(lat=lat, lon=lon).get_id()
            except ValueError:
                pass
            else:
                if not follow_redirect:
                    raise RedirectToPlaceId(latlon_id) from exc
                return place_from_id(latlon_id, follow_redirect=False)
        raise

    places = {
        "admin": Admin,
        "street": Street,
        "addr": Address,
        "poi": POI,
    }
    loader = places.get(es_place.get("_type"))

    if loader is None:
        prometheus.exception("FoundPlaceWithWrongType")
        raise Exception(
            f"Place with id '{id}' has a wrong type: '{es_place[0].get('_type')}'"
        )
    return loader(es_place["_source"])
Example #7
0
def get_closest_place(lat: float, lon: float, es: Elasticsearch):
    es_addr = fetch_closest(lat,
                            lon,
                            es=es,
                            max_distance=MAX_DISTANCE_IN_METERS)

    places = {
        "addr": Address,
        "street": Street,
    }
    loader = places.get(es_addr.get('_type'))

    if loader is None:
        prometheus.exception("FoundPlaceWithWrongType")
        raise Exception(
            "Closest address to '{}:{}' has a wrong type: '{}'".format(
                lat, lon, es_addr.get('_type')))

    return loader(es_addr['_source'])
Example #8
0
def get_closest_place(lat: float, lon: float, es=None):
    if es is None:
        es = get_elasticsearch()
    es_addr = fetch_closest(lat, lon, es=es, max_distance=MAX_DISTANCE_IN_METERS)

    places = {
        "addr": Address,
        "street": Street,
    }
    loader = places.get(es_addr.get("_type"))

    if loader is None:
        logger.warning("Found a place with the wrong type")
        prometheus.exception("FoundPlaceWithWrongType")
        raise HTTPException(
            status_code=404,
            detail=f"Closest address to '{lat}:{lon}' has a wrong type: '{es_addr.get('_type')}'",
        )

    return loader(es_addr["_source"])
Example #9
0
 def on_error(self, request: http.Request):
     prometheus.exception("unhandled_error")
     logging.getLogger('idunn.error')\
         .exception("An unhandled error was raised.", extra={'url': request.url})
Example #10
0
 def on_error(self, response: http.Response):
     prometheus.exception("unhandled_error")
     logging.getLogger('idunn.error').exception(
         "An unhandled error was raised")
Example #11
0
 def wrapped_f(*args, **kwargs):
     try:
         with cls.get_rate_limiter().limit(client="idunn"):
             return f(*args, **kwargs)
     except pybreaker.CircuitBreakerError:
         prometheus.exception("CircuitBreakerError")
         logger.error(
             "Got CircuitBreakerError in %s",
             f.__name__,
             exc_info=True,
         )
     except HTTPError:
         prometheus.exception("HTTPError")
         logger.warning("Got HTTP error in %s",
                        f.__name__,
                        exc_info=True)
     except Timeout:
         prometheus.exception("RequestsTimeout")
         logger.warning("External API timed out in %s",
                        f.__name__,
                        exc_info=True)
     except RequestException:
         prometheus.exception("RequestException")
         logger.error("Got Request exception in %s",
                      f.__name__,
                      exc_info=True)
     except TooManyRequestsException:
         prometheus.exception("TooManyRequests")
         logger.warning("Got TooManyRequests in %s",
                        f.__name__,
                        exc_info=True)
     except RedisError:
         prometheus.exception("RedisError")
         logger.warning("Got redis ConnectionError in %s",
                        f.__name__,
                        exc_info=True)
     return None
Example #12
0
 def set_value(cls, key, json_result):
     try:
         cls._connection.set(key, json_result, ex=cls._expire)
     except RedisError:
         prometheus.exception("RedisError")
         logging.exception("Got a RedisError")
Example #13
0
 def wrapped_f(*args, **kwargs):
     breaker = cls.get_breaker()
     try:
         return WikipediaLimiter.request(breaker(f))(*args, **kwargs)
     except pybreaker.CircuitBreakerError:
         prometheus.exception("CircuitBreakerError")
         logger.error("Got CircuitBreakerError in {}".format(
             f.__name__),
                      exc_info=True)
     except HTTPError:
         prometheus.exception("HTTPError")
         logger.warning("Got HTTP error in {}".format(f.__name__),
                        exc_info=True)
     except Timeout:
         prometheus.exception("RequestsTimeout")
         logger.warning("External API timed out in {}".format(
             f.__name__),
                        exc_info=True)
     except RequestException:
         prometheus.exception("RequestException")
         logger.error("Got Request exception in {}".format(f.__name__),
                      exc_info=True)
     except TooManyRequests:
         prometheus.exception("TooManyRequests")
         logger.warning("Got TooManyRequests{}".format(f.__name__),
                        exc_info=True)
     except RedisConnectionError:
         prometheus.exception("RedisConnectionError")
         logger.warning("Got redis ConnectionError{}".format(
             f.__name__),
                        exc_info=True)
     except TimeoutError:
         prometheus.exception("RedisTimeoutError")
         logger.warning("Got redis TimeoutError{}".format(f.__name__),
                        exc_info=True)
Example #14
0
async def handle_errors(request: Request, exception):
    """
    overrides the default error handler defined in ServerErrorMiddleware
    """
    prometheus.exception("unhandled_error")
    return PlainTextResponse("Internal Server Error", status_code=500)