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)
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
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)
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)
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")
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"])
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'])
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"])
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})
def on_error(self, response: http.Response): prometheus.exception("unhandled_error") logging.getLogger('idunn.error').exception( "An unhandled error was raised")
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
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")
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)
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)