From adce7261ace1b4a21ea49805fb40ba5d50caef89 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Mon, 19 Aug 2024 12:02:33 +0200 Subject: [PATCH] translate UsageError in CLI API commands UsageErrors are handled specially and don't show backtraces unless explicitly requested. We want the same behaviour for errors coming from the API functions. --- src/nominatim_db/clicmd/api.py | 118 +++++++++++++++++++-------------- 1 file changed, 67 insertions(+), 51 deletions(-) diff --git a/src/nominatim_db/clicmd/api.py b/src/nominatim_db/clicmd/api.py index 792443294..dcbbb24bb 100644 --- a/src/nominatim_db/clicmd/api.py +++ b/src/nominatim_db/clicmd/api.py @@ -180,29 +180,32 @@ def run(self, args: NominatimArgs) -> int: raise UsageError(f"Unsupported format '{args.format}'. " 'Use --list-formats to see supported formats.') - with napi.NominatimAPI(args.project_dir) as api: - params: Dict[str, Any] = {'max_results': args.limit + min(args.limit, 10), - 'address_details': True, # needed for display name - 'geometry_output': _get_geometry_output(args), - 'geometry_simplification': args.polygon_threshold, - 'countries': args.countrycodes, - 'excluded': args.exclude_place_ids, - 'viewbox': args.viewbox, - 'bounded_viewbox': args.bounded, - 'locales': _get_locales(args, api.config.DEFAULT_LANGUAGE) - } - - if args.query: - results = api.search(args.query, **params) - else: - results = api.search_address(amenity=args.amenity, - street=args.street, - city=args.city, - county=args.county, - state=args.state, - postalcode=args.postalcode, - country=args.country, - **params) + try: + with napi.NominatimAPI(args.project_dir) as api: + params: Dict[str, Any] = {'max_results': args.limit + min(args.limit, 10), + 'address_details': True, # needed for display name + 'geometry_output': _get_geometry_output(args), + 'geometry_simplification': args.polygon_threshold, + 'countries': args.countrycodes, + 'excluded': args.exclude_place_ids, + 'viewbox': args.viewbox, + 'bounded_viewbox': args.bounded, + 'locales': _get_locales(args, api.config.DEFAULT_LANGUAGE) + } + + if args.query: + results = api.search(args.query, **params) + else: + results = api.search_address(amenity=args.amenity, + street=args.street, + city=args.city, + county=args.county, + state=args.state, + postalcode=args.postalcode, + country=args.country, + **params) + except napi.UsageError as ex: + raise UsageError(ex) from ex if args.dedupe and len(results) > 1: results = deduplicate_results(results, args.limit) @@ -260,15 +263,19 @@ def run(self, args: NominatimArgs) -> int: if args.lat is None or args.lon is None: raise UsageError("lat' and 'lon' parameters are required.") - with napi.NominatimAPI(args.project_dir) as api: - result = api.reverse(napi.Point(args.lon, args.lat), - max_rank=zoom_to_rank(args.zoom or 18), - layers=_get_layers(args, - napi.DataLayer.ADDRESS | napi.DataLayer.POI), - address_details=True, # needed for display name - geometry_output=_get_geometry_output(args), - geometry_simplification=args.polygon_threshold, - locales=_get_locales(args, api.config.DEFAULT_LANGUAGE)) + layers = _get_layers(args, napi.DataLayer.ADDRESS | napi.DataLayer.POI) + + try: + with napi.NominatimAPI(args.project_dir) as api: + result = api.reverse(napi.Point(args.lon, args.lat), + max_rank=zoom_to_rank(args.zoom or 18), + layers=layers, + address_details=True, # needed for display name + geometry_output=_get_geometry_output(args), + geometry_simplification=args.polygon_threshold, + locales=_get_locales(args, api.config.DEFAULT_LANGUAGE)) + except napi.UsageError as ex: + raise UsageError(ex) from ex if args.format == 'debug': print(loglib.get_and_disable()) @@ -324,12 +331,15 @@ def run(self, args: NominatimArgs) -> int: places = [napi.OsmID(o[0], int(o[1:])) for o in args.ids] - with napi.NominatimAPI(args.project_dir) as api: - results = api.lookup(places, - address_details=True, # needed for display name - geometry_output=_get_geometry_output(args), - geometry_simplification=args.polygon_threshold or 0.0, - locales=_get_locales(args, api.config.DEFAULT_LANGUAGE)) + try: + with napi.NominatimAPI(args.project_dir) as api: + results = api.lookup(places, + address_details=True, # needed for display name + geometry_output=_get_geometry_output(args), + geometry_simplification=args.polygon_threshold or 0.0, + locales=_get_locales(args, api.config.DEFAULT_LANGUAGE)) + except napi.UsageError as ex: + raise UsageError(ex) from ex if args.format == 'debug': print(loglib.get_and_disable()) @@ -411,17 +421,20 @@ def run(self, args: NominatimArgs) -> int: raise UsageError('One of the arguments --node/-n --way/-w ' '--relation/-r --place_id/-p is required/') - with napi.NominatimAPI(args.project_dir) as api: - locales = _get_locales(args, api.config.DEFAULT_LANGUAGE) - result = api.details(place, - address_details=args.addressdetails, - linked_places=args.linkedplaces, - parented_places=args.hierarchy, - keywords=args.keywords, - geometry_output=napi.GeometryFormat.GEOJSON - if args.polygon_geojson - else napi.GeometryFormat.NONE, - locales=locales) + try: + with napi.NominatimAPI(args.project_dir) as api: + locales = _get_locales(args, api.config.DEFAULT_LANGUAGE) + result = api.details(place, + address_details=args.addressdetails, + linked_places=args.linkedplaces, + parented_places=args.hierarchy, + keywords=args.keywords, + geometry_output=napi.GeometryFormat.GEOJSON + if args.polygon_geojson + else napi.GeometryFormat.NONE, + locales=locales) + except napi.UsageError as ex: + raise UsageError(ex) from ex if args.format == 'debug': print(loglib.get_and_disable()) @@ -466,8 +479,11 @@ def run(self, args: NominatimArgs) -> int: raise UsageError(f"Unsupported format '{args.format}'. " 'Use --list-formats to see supported formats.') - with napi.NominatimAPI(args.project_dir) as api: - status = api.status() + try: + with napi.NominatimAPI(args.project_dir) as api: + status = api.status() + except napi.UsageError as ex: + raise UsageError(ex) from ex if args.format == 'debug': print(loglib.get_and_disable())