]> git.openstreetmap.org Git - nominatim.git/blob - src/nominatim_api/core.py
introduce parameter for saving query statistics
[nominatim.git] / src / nominatim_api / core.py
1 # SPDX-License-Identifier: GPL-3.0-or-later
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2025 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Implementation of classes for API access via libraries.
9 """
10 from typing import Mapping, Optional, Any, AsyncIterator, Dict, Sequence, List, \
11                    Union, Tuple, cast
12 import asyncio
13 import sys
14 import contextlib
15 from pathlib import Path
16
17 if sys.version_info >= (3, 11):
18     from asyncio import timeout_at
19 else:
20     from async_timeout import timeout_at
21
22 import sqlalchemy as sa
23 import sqlalchemy.ext.asyncio as sa_asyncio
24
25 from .errors import UsageError
26 from .sql.sqlalchemy_schema import SearchTables
27 from .sql.async_core_library import PGCORE_LIB, PGCORE_ERROR
28 from .config import Configuration
29 from .sql import sqlite_functions, sqlalchemy_functions  # noqa
30 from .connection import SearchConnection
31 from .status import get_status, StatusResult
32 from .lookup import get_places, get_detailed_place
33 from .reverse import ReverseGeocoder
34 from .timeout import Timeout
35 from . import search as nsearch
36 from . import types as ntyp
37 from .results import DetailedResult, ReverseResult, SearchResults
38
39
40 class NominatimAPIAsync:
41     """ The main frontend to the Nominatim database implements the
42         functions for lookup, forward and reverse geocoding using
43         asynchronous functions.
44
45         This class shares most of the functions with its synchronous
46         version. There are some additional functions or parameters,
47         which are documented below.
48
49         This class should usually be used as a context manager in 'with' context.
50     """
51     def __init__(self, project_dir: Optional[Union[str, Path]] = None,
52                  environ: Optional[Mapping[str, str]] = None,
53                  loop: Optional[asyncio.AbstractEventLoop] = None) -> None:
54         """ Initiate a new frontend object with synchronous API functions.
55
56             Parameters:
57               project_dir: Path to the
58                   [project directory](../admin/Import.md#creating-the-project-directory)
59                   of the local Nominatim installation.
60               environ: Mapping of [configuration parameters](../customize/Settings.md).
61                   When set, replaces any configuration via environment variables.
62                   Settings in this mapping also have precedence over any
63                   parameters found in the `.env` file of the project directory.
64               loop: The asyncio event loop that will be used when calling
65                   functions. Only needed, when a custom event loop is used
66                   and the Python version is 3.9 or earlier.
67         """
68         self.config = Configuration(project_dir, environ)
69         self.query_timeout = self.config.get_int('QUERY_TIMEOUT') \
70             if self.config.QUERY_TIMEOUT else None
71         self.request_timeout = self.config.get_int('REQUEST_TIMEOUT') \
72             if self.config.REQUEST_TIMEOUT else None
73         self.reverse_restrict_to_country_area = self.config.get_bool('SEARCH_WITHIN_COUNTRIES')
74         self.server_version = 0
75
76         if sys.version_info >= (3, 10):
77             self._engine_lock = asyncio.Lock()
78         else:
79             self._engine_lock = asyncio.Lock(loop=loop)
80         self._engine: Optional[sa_asyncio.AsyncEngine] = None
81         self._tables: Optional[SearchTables] = None
82         self._property_cache: Dict[str, Any] = {'DB:server_version': 0}
83
84     async def setup_database(self) -> None:
85         """ Set up the SQL engine and connections.
86
87             This function will be implicitly called when the database is
88             accessed for the first time. You may also call it explicitly to
89             avoid that the first call is delayed by the setup.
90         """
91         async with self._engine_lock:
92             if self._engine:
93                 return
94
95             extra_args: Dict[str, Any] = {'future': True,
96                                           'echo': self.config.get_bool('DEBUG_SQL')}
97
98             if self.config.get_int('API_POOL_SIZE') == 0:
99                 extra_args['poolclass'] = sa.pool.NullPool
100             else:
101                 extra_args['poolclass'] = sa.pool.AsyncAdaptedQueuePool
102                 extra_args['max_overflow'] = 0
103                 extra_args['pool_size'] = self.config.get_int('API_POOL_SIZE')
104
105             is_sqlite = self.config.DATABASE_DSN.startswith('sqlite:')
106
107             if is_sqlite:
108                 params = dict((p.split('=', 1)
109                               for p in self.config.DATABASE_DSN[7:].split(';')))
110                 dburl = sa.engine.URL.create('sqlite+aiosqlite',
111                                              database=params.get('dbname'))
112
113                 if not ('NOMINATIM_DATABASE_RW' in self.config.environ
114                         and self.config.get_bool('DATABASE_RW')) \
115                    and not Path(params.get('dbname', '')).is_file():
116                     raise UsageError(f"SQlite database '{params.get('dbname')}' does not exist.")
117             else:
118                 dsn = self.config.get_database_params()
119                 query = {k: str(v) for k, v in dsn.items()
120                          if k not in ('user', 'password', 'dbname', 'host', 'port')}
121
122                 dburl = sa.engine.URL.create(
123                            f'postgresql+{PGCORE_LIB}',
124                            database=cast(str, dsn.get('dbname')),
125                            username=cast(str, dsn.get('user')),
126                            password=cast(str, dsn.get('password')),
127                            host=cast(str, dsn.get('host')),
128                            port=int(cast(str, dsn['port'])) if 'port' in dsn else None,
129                            query=query)
130
131             engine = sa_asyncio.create_async_engine(dburl, **extra_args)
132
133             if is_sqlite:
134                 server_version = 0
135
136                 @sa.event.listens_for(engine.sync_engine, "connect")
137                 def _on_sqlite_connect(dbapi_con: Any, _: Any) -> None:
138                     dbapi_con.run_async(lambda conn: conn.enable_load_extension(True))
139                     sqlite_functions.install_custom_functions(dbapi_con)
140                     cursor = dbapi_con.cursor()
141                     cursor.execute("SELECT load_extension('mod_spatialite')")
142                     cursor.execute('SELECT SetDecimalPrecision(7)')
143                     dbapi_con.run_async(lambda conn: conn.enable_load_extension(False))
144             else:
145                 try:
146                     async with engine.begin() as conn:
147                         result = await conn.scalar(sa.text('SHOW server_version_num'))
148                         server_version = int(result)
149                         await conn.execute(sa.text("SET jit_above_cost TO '-1'"))
150                         await conn.execute(sa.text(
151                                 "SET max_parallel_workers_per_gather TO '0'"))
152                 except (PGCORE_ERROR, sa.exc.OperationalError):
153                     server_version = 0
154
155                 @sa.event.listens_for(engine.sync_engine, "connect")
156                 def _on_connect(dbapi_con: Any, _: Any) -> None:
157                     cursor = dbapi_con.cursor()
158                     cursor.execute("SET jit_above_cost TO '-1'")
159                     cursor.execute("SET max_parallel_workers_per_gather TO '0'")
160
161             self._property_cache['DB:server_version'] = server_version
162
163             self._tables = SearchTables(sa.MetaData())
164             self._engine = engine
165
166     async def close(self) -> None:
167         """ Close all active connections to the database. The NominatimAPIAsync
168             object remains usable after closing. If a new API functions is
169             called, new connections are created.
170         """
171         if self._engine is not None:
172             await self._engine.dispose()
173
174     async def __aenter__(self) -> 'NominatimAPIAsync':
175         return self
176
177     async def __aexit__(self, *_: Any) -> None:
178         await self.close()
179
180     @contextlib.asynccontextmanager
181     async def begin(self, abs_timeout: Optional[float] = None) -> AsyncIterator[SearchConnection]:
182         """ Create a new connection with automatic transaction handling.
183
184             This function may be used to get low-level access to the database.
185             Refer to the documentation of SQLAlchemy for details how to use
186             the connection object.
187
188             You may optionally give an absolute timeout until when to wait
189             for a connection to become available.
190         """
191         if self._engine is None:
192             await self.setup_database()
193
194         assert self._engine is not None
195         assert self._tables is not None
196
197         async with timeout_at(abs_timeout), self._engine.begin() as conn:
198             yield SearchConnection(conn, self._tables, self._property_cache, self.config)
199
200     async def status(self) -> StatusResult:
201         """ Return the status of the database.
202         """
203         timeout = Timeout(self.request_timeout)
204         try:
205             async with self.begin(abs_timeout=timeout.abs) as conn:
206                 conn.set_query_timeout(self.query_timeout)
207                 status = await get_status(conn)
208         except (PGCORE_ERROR, sa.exc.OperationalError):
209             return StatusResult(700, 'Database connection failed')
210
211         return status
212
213     async def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
214         """ Get detailed information about a place in the database.
215
216             Returns None if there is no entry under the given ID.
217         """
218         timeout = Timeout(self.request_timeout)
219         details = ntyp.LookupDetails.from_kwargs(params)
220         with details.query_stats as qs:
221             async with self.begin(abs_timeout=timeout.abs) as conn:
222                 qs.log_time('start_query')
223                 conn.set_query_timeout(self.query_timeout)
224                 if details.keywords:
225                     await nsearch.make_query_analyzer(conn)
226                 return await get_detailed_place(conn, place, details)
227
228     async def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
229         """ Get simple information about a list of places.
230
231             Returns a list of place information for all IDs that were found.
232         """
233         timeout = Timeout(self.request_timeout)
234         details = ntyp.LookupDetails.from_kwargs(params)
235         with details.query_stats as qs:
236             async with self.begin(abs_timeout=timeout.abs) as conn:
237                 qs.log_time('start_query')
238                 conn.set_query_timeout(self.query_timeout)
239                 if details.keywords:
240                     await nsearch.make_query_analyzer(conn)
241                 return await get_places(conn, places, details)
242
243     async def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
244         """ Find a place by its coordinates. Also known as reverse geocoding.
245
246             Returns the closest result that can be found or None if
247             no place matches the given criteria.
248         """
249         # The following negation handles NaN correctly. Don't change.
250         if not abs(coord[0]) <= 180 or not abs(coord[1]) <= 90:
251             # There are no results to be expected outside valid coordinates.
252             return None
253
254         timeout = Timeout(self.request_timeout)
255         details = ntyp.ReverseDetails.from_kwargs(params)
256         with details.query_stats as qs:
257             async with self.begin(abs_timeout=timeout.abs) as conn:
258                 qs.log_time('start_query')
259                 conn.set_query_timeout(self.query_timeout)
260                 if details.keywords:
261                     await nsearch.make_query_analyzer(conn)
262                 geocoder = ReverseGeocoder(conn, details,
263                                            self.reverse_restrict_to_country_area)
264                 return await geocoder.lookup(coord)
265
266     async def search(self, query: str, **params: Any) -> SearchResults:
267         """ Find a place by free-text search. Also known as forward geocoding.
268         """
269         timeout = Timeout(self.request_timeout)
270         details = ntyp.SearchDetails.from_kwargs(params)
271         with details.query_stats as qs:
272             query = query.strip()
273             if not query:
274                 raise UsageError('Nothing to search for.')
275
276             async with self.begin(abs_timeout=timeout.abs) as conn:
277                 qs.log_time('start_query')
278                 conn.set_query_timeout(self.query_timeout)
279                 geocoder = nsearch.ForwardGeocoder(conn, details, timeout)
280                 phrases = [nsearch.Phrase(nsearch.PHRASE_ANY, p.strip()) for p in query.split(',')]
281                 return await geocoder.lookup(phrases)
282
283     async def search_address(self, amenity: Optional[str] = None,
284                              street: Optional[str] = None,
285                              city: Optional[str] = None,
286                              county: Optional[str] = None,
287                              state: Optional[str] = None,
288                              country: Optional[str] = None,
289                              postalcode: Optional[str] = None,
290                              **params: Any) -> SearchResults:
291         """ Find an address using structured search.
292         """
293         timeout = Timeout(self.request_timeout)
294         details = ntyp.SearchDetails.from_kwargs(params)
295         with details.query_stats as qs:
296             phrases: List[nsearch.Phrase] = []
297
298             if amenity:
299                 phrases.append(nsearch.Phrase(nsearch.PHRASE_AMENITY, amenity))
300             if street:
301                 phrases.append(nsearch.Phrase(nsearch.PHRASE_STREET, street))
302             if city:
303                 phrases.append(nsearch.Phrase(nsearch.PHRASE_CITY, city))
304             if county:
305                 phrases.append(nsearch.Phrase(nsearch.PHRASE_COUNTY, county))
306             if state:
307                 phrases.append(nsearch.Phrase(nsearch.PHRASE_STATE, state))
308             if postalcode:
309                 phrases.append(nsearch.Phrase(nsearch.PHRASE_POSTCODE, postalcode))
310             if country:
311                 phrases.append(nsearch.Phrase(nsearch.PHRASE_COUNTRY, country))
312
313             if not phrases:
314                 raise UsageError('Nothing to search for.')
315
316             if amenity or street:
317                 details.restrict_min_max_rank(26, 30)
318             elif city:
319                 details.restrict_min_max_rank(13, 25)
320             elif county:
321                 details.restrict_min_max_rank(10, 12)
322             elif state:
323                 details.restrict_min_max_rank(5, 9)
324             elif postalcode:
325                 details.restrict_min_max_rank(5, 11)
326             else:
327                 details.restrict_min_max_rank(4, 4)
328
329             if details.layers is None:
330                 details.layers = ntyp.DataLayer.ADDRESS
331                 if amenity:
332                     details.layers |= ntyp.DataLayer.POI
333
334         async with self.begin(abs_timeout=timeout.abs) as conn:
335             qs.log_time('start_query')
336             conn.set_query_timeout(self.query_timeout)
337             geocoder = nsearch.ForwardGeocoder(conn, details, timeout)
338             return await geocoder.lookup(phrases)
339
340     async def search_category(self, categories: List[Tuple[str, str]],
341                               near_query: Optional[str] = None,
342                               **params: Any) -> SearchResults:
343         """ Find an object of a certain category near another place.
344             The near place may either be given as an unstructured search
345             query in itself or as coordinates.
346         """
347         timeout = Timeout(self.request_timeout)
348         details = ntyp.SearchDetails.from_kwargs(params)
349         with details.query_stats as qs:
350             if not categories:
351                 return SearchResults()
352
353             async with self.begin(abs_timeout=timeout.abs) as conn:
354                 qs.log_time('start_query')
355                 conn.set_query_timeout(self.query_timeout)
356                 if near_query:
357                     phrases = [nsearch.Phrase(nsearch.PHRASE_ANY, p) for p in near_query.split(',')]
358                 else:
359                     phrases = []
360                     if details.keywords:
361                         await nsearch.make_query_analyzer(conn)
362
363                 geocoder = nsearch.ForwardGeocoder(conn, details, timeout)
364                 return await geocoder.lookup_pois(categories, phrases)
365
366
367 class NominatimAPI:
368     """ This class provides a thin synchronous wrapper around the asynchronous
369         Nominatim functions. It creates its own event loop and runs each
370         synchronous function call to completion using that loop.
371
372         This class should usually be used as a context manager in 'with' context.
373     """
374
375     def __init__(self, project_dir: Optional[Union[str, Path]] = None,
376                  environ: Optional[Mapping[str, str]] = None) -> None:
377         """ Initiate a new frontend object with synchronous API functions.
378
379             Parameters:
380               project_dir: Path to the
381                   [project directory](../admin/Import.md#creating-the-project-directory)
382                   of the local Nominatim installation.
383               environ: Mapping of [configuration parameters](../customize/Settings.md).
384                   When set, replaces any configuration via environment variables.
385                   Settings in this mapping also have precedence over any
386                   parameters found in the `.env` file of the project directory.
387         """
388         self._loop = asyncio.new_event_loop()
389         self._async_api = NominatimAPIAsync(project_dir, environ, loop=self._loop)
390
391     def close(self) -> None:
392         """ Close all active connections to the database.
393
394             This function also closes the asynchronous worker loop making
395             the NominatimAPI object unusable.
396         """
397         if not self._loop.is_closed():
398             self._loop.run_until_complete(self._async_api.close())
399             self._loop.close()
400
401     def __enter__(self) -> 'NominatimAPI':
402         return self
403
404     def __exit__(self, *_: Any) -> None:
405         self.close()
406
407     @property
408     def config(self) -> Configuration:
409         """ Provide read-only access to the [configuration](Configuration.md)
410             used by the API.
411         """
412         return self._async_api.config
413
414     def status(self) -> StatusResult:
415         """ Return the status of the database as a dataclass object
416             with the fields described below.
417
418             Returns:
419               status(int): A status code as described on the status page.
420               message(str): Either 'OK' or a human-readable message of the
421                   problem encountered.
422               software_version(tuple): A tuple with the version of the
423                   Nominatim library consisting of (major, minor, patch, db-patch)
424                   version.
425               database_version(tuple): A tuple with the version of the library
426                   which was used for the import or last migration.
427                   Also consists of (major, minor, patch, db-patch).
428               data_updated(datetime): Timestamp with the age of the data.
429         """
430         return self._loop.run_until_complete(self._async_api.status())
431
432     def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
433         """ Get detailed information about a place in the database.
434
435             The result is a dataclass object with the fields described below
436             or `None` if the place could not be found in the database.
437
438             Parameters:
439               place: Description of the place to look up. See
440                      [Place identification](Input-Parameter-Types.md#place-identification)
441                      for the various ways to reference a place.
442
443             Other parameters:
444               geometry_output (enum): Add the full geometry of the place to the result.
445                 Multiple formats may be selected. Note that geometries can become
446                 quite large. (Default: none)
447               geometry_simplification (float): Simplification factor to use on
448                 the geometries before returning them. The factor expresses
449                 the tolerance in degrees from which the geometry may differ.
450                 Topology is preserved. (Default: 0.0)
451               address_details (bool): Add detailed information about the places
452                 that make up the address of the requested object. (Default: False)
453               linked_places (bool): Add detailed information about the places
454                 that link to the result. (Default: False)
455               parented_places (bool): Add detailed information about all places
456                 for which the requested object is a parent, i.e. all places for
457                 which the object provides the address details.
458                 Only POI places can have parents. (Default: False)
459               keywords (bool): Add detailed information about the search terms
460                 used for this place.
461
462             Returns:
463               source_table (enum): Data source of the place. See below for possible values.
464               category (tuple): A tuple of two strings with the primary OSM tag
465                   and value.
466               centroid (Point): Point position of the place.
467               place_id (Optional[int]): Internal ID of the place. This ID may differ
468                   for the same place between different installations.
469               parent_place_id (Optional(int]): Internal ID of the parent of this
470                   place. Only meaning full for POI-like objects (places with a
471                   rank_address of 30).
472               linked_place_id (Optional[int]): Internal ID of the place this object
473                   links to. When this ID is set then there is no guarantee that
474                   the rest of the result information is complete.
475               admin_level (int): Value of the `admin_level` OSM tag. Only meaningful
476                   for administrative boundary objects.
477               indexed_date (datetime): Timestamp when the place was last updated.
478               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
479               names (Optional[dict]): Dictionary of names of the place. Keys are
480                   usually the corresponding OSM tag keys.
481               address (Optional[dict]): Dictionary of address parts directly
482                   attributed to the place. Keys are usually the corresponding
483                   OSM tag keys with the `addr:` prefix removed.
484               extratags (Optional[dict]): Dictionary of additional attributes for
485                   the place. Usually OSM tag keys and values.
486               housenumber (Optional[str]): House number of the place, normalised
487                   for lookup. To get the house number in its original spelling,
488                   use `address['housenumber']`.
489               postcode (Optional[str]): Computed postcode for the place. To get
490                   directly attributed postcodes, use `address['postcode']` instead.
491               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
492                   The string has the format <language code>:<wikipedia title>.
493               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
494               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
495               importance (Optional[float]): Relative importance of the place. This is a measure
496                   how likely the place will be searched for.
497               country_code (Optional[str]): Country the feature is in as
498                   ISO 3166-1 alpha-2 country code.
499               address_rows (Optional[AddressLines]): List of places that make up the
500                   computed address. `None` when `address_details` parameter was False.
501               linked_rows (Optional[AddressLines]): List of places that link to the object.
502                   `None` when `linked_places` parameter was False.
503               parented_rows (Optional[AddressLines]): List of direct children of the place.
504                   `None` when `parented_places` parameter was False.
505               name_keywords (Optional[WordInfos]): List of search words for the name of
506                    the place. `None` when `keywords` parameter is set to False.
507               address_keywords (Optional[WordInfos]): List of search word for the address of
508                    the place. `None` when `keywords` parameter is set to False.
509               geometry (dict): Dictionary containing the full geometry of the place
510                    in the formats requested in the `geometry_output` parameter.
511         """
512         return self._loop.run_until_complete(self._async_api.details(place, **params))
513
514     def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
515         """ Get simple information about a list of places.
516
517             Returns a list of place information for all IDs that were found.
518             Each result is a dataclass with the fields detailed below.
519
520             Parameters:
521               places: List of descriptions of the place to look up. See
522                       [Place identification](Input-Parameter-Types.md#place-identification)
523                       for the various ways to reference a place.
524
525             Other parameters:
526               geometry_output (enum): Add the full geometry of the place to the result.
527                 Multiple formats may be selected. Note that geometries can become
528                 quite large. (Default: none)
529               geometry_simplification (float): Simplification factor to use on
530                 the geometries before returning them. The factor expresses
531                 the tolerance in degrees from which the geometry may differ.
532                 Topology is preserved. (Default: 0.0)
533               address_details (bool): Add detailed information about the places
534                 that make up the address of the requested object. (Default: False)
535               linked_places (bool): Add detailed information about the places
536                 that link to the result. (Default: False)
537               parented_places (bool): Add detailed information about all places
538                 for which the requested object is a parent, i.e. all places for
539                 which the object provides the address details.
540                 Only POI places can have parents. (Default: False)
541               keywords (bool): Add detailed information about the search terms
542                 used for this place.
543
544             Returns:
545               source_table (enum): Data source of the place. See below for possible values.
546               category (tuple): A tuple of two strings with the primary OSM tag
547                   and value.
548               centroid (Point): Point position of the place.
549               place_id (Optional[int]): Internal ID of the place. This ID may differ
550                   for the same place between different installations.
551               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
552               names (Optional[dict]): Dictionary of names of the place. Keys are
553                   usually the corresponding OSM tag keys.
554               address (Optional[dict]): Dictionary of address parts directly
555                   attributed to the place. Keys are usually the corresponding
556                   OSM tag keys with the `addr:` prefix removed.
557               extratags (Optional[dict]): Dictionary of additional attributes for
558                   the place. Usually OSM tag keys and values.
559               housenumber (Optional[str]): House number of the place, normalised
560                   for lookup. To get the house number in its original spelling,
561                   use `address['housenumber']`.
562               postcode (Optional[str]): Computed postcode for the place. To get
563                   directly attributed postcodes, use `address['postcode']` instead.
564               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
565                   The string has the format <language code>:<wikipedia title>.
566               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
567               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
568               importance (Optional[float]): Relative importance of the place. This is a measure
569                   how likely the place will be searched for.
570               country_code (Optional[str]): Country the feature is in as
571                   ISO 3166-1 alpha-2 country code.
572               address_rows (Optional[AddressLines]): List of places that make up the
573                   computed address. `None` when `address_details` parameter was False.
574               linked_rows (Optional[AddressLines]): List of places that link to the object.
575                   `None` when `linked_places` parameter was False.
576               parented_rows (Optional[AddressLines]): List of direct children of the place.
577                   `None` when `parented_places` parameter was False.
578               name_keywords (Optional[WordInfos]): List of search words for the name of
579                    the place. `None` when `keywords` parameter is set to False.
580               address_keywords (Optional[WordInfos]): List of search word for the address of
581                    the place. `None` when `keywords` parameter is set to False.
582               bbox (Bbox): Bounding box of the full geometry of the place.
583                    If the place is a single point, then the size of the bounding
584                    box is guessed according to the type of place.
585               geometry (dict): Dictionary containing the full geometry of the place
586                    in the formats requested in the `geometry_output` parameter.
587         """
588         return self._loop.run_until_complete(self._async_api.lookup(places, **params))
589
590     def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
591         """ Find a place by its coordinates. Also known as reverse geocoding.
592
593             Returns the closest result that can be found or `None` if
594             no place matches the given criteria. The result is a dataclass
595             with the fields as detailed below.
596
597             Parameters:
598               coord: Coordinate to lookup the place for as a Point
599                      or a tuple (x, y). Must be in WGS84 projection.
600
601             Other parameters:
602               max_rank (int): Highest address rank to return. Can be used to
603                 restrict search to streets or settlements.
604               layers (enum): Defines the kind of data to take into account.
605                 See description of layers below. (Default: addresses and POIs)
606               geometry_output (enum): Add the full geometry of the place to the result.
607                 Multiple formats may be selected. Note that geometries can become
608                 quite large. (Default: none)
609               geometry_simplification (float): Simplification factor to use on
610                 the geometries before returning them. The factor expresses
611                 the tolerance in degrees from which the geometry may differ.
612                 Topology is preserved. (Default: 0.0)
613               address_details (bool): Add detailed information about the places
614                 that make up the address of the requested object. (Default: False)
615               linked_places (bool): Add detailed information about the places
616                 that link to the result. (Default: False)
617               parented_places (bool): Add detailed information about all places
618                 for which the requested object is a parent, i.e. all places for
619                 which the object provides the address details.
620                 Only POI places can have parents. (Default: False)
621               keywords (bool): Add detailed information about the search terms
622                 used for this place.
623
624             Returns:
625               source_table (enum): Data source of the place. See below for possible values.
626               category (tuple): A tuple of two strings with the primary OSM tag
627                   and value.
628               centroid (Point): Point position of the place.
629               place_id (Optional[int]): Internal ID of the place. This ID may differ
630                   for the same place between different installations.
631               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
632               names (Optional[dict]): Dictionary of names of the place. Keys are
633                   usually the corresponding OSM tag keys.
634               address (Optional[dict]): Dictionary of address parts directly
635                   attributed to the place. Keys are usually the corresponding
636                   OSM tag keys with the `addr:` prefix removed.
637               extratags (Optional[dict]): Dictionary of additional attributes for
638                   the place. Usually OSM tag keys and values.
639               housenumber (Optional[str]): House number of the place, normalised
640                   for lookup. To get the house number in its original spelling,
641                   use `address['housenumber']`.
642               postcode (Optional[str]): Computed postcode for the place. To get
643                   directly attributed postcodes, use `address['postcode']` instead.
644               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
645                   The string has the format <language code>:<wikipedia title>.
646               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
647               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
648               importance (Optional[float]): Relative importance of the place. This is a measure
649                   how likely the place will be searched for.
650               country_code (Optional[str]): Country the feature is in as
651                   ISO 3166-1 alpha-2 country code.
652               address_rows (Optional[AddressLines]): List of places that make up the
653                   computed address. `None` when `address_details` parameter was False.
654               linked_rows (Optional[AddressLines]): List of places that link to the object.
655                   `None` when `linked_places` parameter was False.
656               parented_rows (Optional[AddressLines]): List of direct children of the place.
657                   `None` when `parented_places` parameter was False.
658               name_keywords (Optional[WordInfos]): List of search words for the name of
659                    the place. `None` when `keywords` parameter is set to False.
660               address_keywords (Optional[WordInfos]): List of search word for the address of
661                    the place. `None` when `keywords` parameter is set to False.
662               bbox (Bbox): Bounding box of the full geometry of the place.
663                    If the place is a single point, then the size of the bounding
664                    box is guessed according to the type of place.
665               geometry (dict): Dictionary containing the full geometry of the place
666                    in the formats requested in the `geometry_output` parameter.
667               distance (Optional[float]): Distance in degree from the input point.
668         """
669         return self._loop.run_until_complete(self._async_api.reverse(coord, **params))
670
671     def search(self, query: str, **params: Any) -> SearchResults:
672         """ Find a place by free-text search. Also known as forward geocoding.
673
674             Parameters:
675               query: Free-form text query searching for a place.
676
677             Other parameters:
678               max_results (int): Maximum number of results to return. The
679                 actual number of results may be less. (Default: 10)
680               min_rank (int): Lowest permissible rank for the result.
681                 For addressable places this is the minimum
682                 [address rank](../customize/Ranking.md#address-rank). For all
683                 other places the [search rank](../customize/Ranking.md#search-rank)
684                 is used.
685               max_rank (int): Highest permissible rank for the result. See min_rank above.
686               layers (enum): Defines the kind of data to take into account.
687                 See [layers section](Input-Parameter-Types.md#layers) for details.
688                 (Default: addresses and POIs)
689               countries (list[str]): Restrict search to countries with the given
690                 ISO 3166-1 alpha-2 country code. An empty list (the default)
691                 disables this filter.
692               excluded (list[int]): A list of internal IDs of places to exclude
693                 from the search.
694               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
695               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
696                 as a filter and return only results within the bounding box.
697               near (Optional[Point]): Focus search around the given point and
698                 return results ordered by distance to the given point.
699               near_radius (Optional[float]): Restrict results to results within
700                 the given distance in degrees of `near` point. Ignored, when
701                 `near` is not set.
702               categories (list[tuple]): Restrict search to places of the given
703                 categories. The category is the main OSM tag assigned to each
704                 place. An empty list (the default) disables this filter.
705               geometry_output (enum): Add the full geometry of the place to the result.
706                 Multiple formats may be selected. Note that geometries can become
707                 quite large. (Default: none)
708               geometry_simplification (float): Simplification factor to use on
709                 the geometries before returning them. The factor expresses
710                 the tolerance in degrees from which the geometry may differ.
711                 Topology is preserved. (Default: 0.0)
712               address_details (bool): Add detailed information about the places
713                 that make up the address of the requested object. (Default: False)
714               linked_places (bool): Add detailed information about the places
715                 that link to the result. (Default: False)
716               parented_places (bool): Add detailed information about all places
717                 for which the requested object is a parent, i.e. all places for
718                 which the object provides the address details.
719                 Only POI places can have parents. (Default: False)
720               keywords (bool): Add detailed information about the search terms
721                 used for this place.
722
723             Returns:
724               source_table (enum): Data source of the place. See below for possible values.
725               category (tuple): A tuple of two strings with the primary OSM tag
726                   and value.
727               centroid (Point): Point position of the place.
728               place_id (Optional[int]): Internal ID of the place. This ID may differ
729                   for the same place between different installations.
730               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
731               names (Optional[dict]): Dictionary of names of the place. Keys are
732                   usually the corresponding OSM tag keys.
733               address (Optional[dict]): Dictionary of address parts directly
734                   attributed to the place. Keys are usually the corresponding
735                   OSM tag keys with the `addr:` prefix removed.
736               extratags (Optional[dict]): Dictionary of additional attributes for
737                   the place. Usually OSM tag keys and values.
738               housenumber (Optional[str]): House number of the place, normalised
739                   for lookup. To get the house number in its original spelling,
740                   use `address['housenumber']`.
741               postcode (Optional[str]): Computed postcode for the place. To get
742                   directly attributed postcodes, use `address['postcode']` instead.
743               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
744                   The string has the format <language code>:<wikipedia title>.
745               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
746               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
747               importance (Optional[float]): Relative importance of the place. This is a measure
748                   how likely the place will be searched for.
749               country_code (Optional[str]): Country the feature is in as
750                   ISO 3166-1 alpha-2 country code.
751               address_rows (Optional[AddressLines]): List of places that make up the
752                   computed address. `None` when `address_details` parameter was False.
753               linked_rows (Optional[AddressLines]): List of places that link to the object.
754                   `None` when `linked_places` parameter was False.
755               parented_rows (Optional[AddressLines]): List of direct children of the place.
756                   `None` when `parented_places` parameter was False.
757               name_keywords (Optional[WordInfos]): List of search words for the name of
758                    the place. `None` when `keywords` parameter is set to False.
759               address_keywords (Optional[WordInfos]): List of search word for the address of
760                    the place. `None` when `keywords` parameter is set to False.
761               bbox (Bbox): Bounding box of the full geometry of the place.
762                    If the place is a single point, then the size of the bounding
763                    box is guessed according to the type of place.
764               geometry (dict): Dictionary containing the full geometry of the place
765                    in the formats requested in the `geometry_output` parameter.
766         """
767         return self._loop.run_until_complete(
768                    self._async_api.search(query, **params))
769
770     def search_address(self, amenity: Optional[str] = None,
771                        street: Optional[str] = None,
772                        city: Optional[str] = None,
773                        county: Optional[str] = None,
774                        state: Optional[str] = None,
775                        country: Optional[str] = None,
776                        postalcode: Optional[str] = None,
777                        **params: Any) -> SearchResults:
778         """ Find an address using structured search.
779
780             Parameters:
781               amenity: Name of a POI.
782               street: Street and optionally housenumber of the address. If the address
783                 does not have a street, then the place the housenumber references to.
784               city: Postal city of the address.
785               county: County equivalent of the address. Does not exist in all
786                 jurisdictions.
787               state: State or province of the address.
788               country: Country with its full name or its ISO 3166-1 alpha-2 country code.
789                 Do not use together with the country_code filter.
790               postalcode: Post code or ZIP for the place.
791
792             Other parameters:
793               max_results (int): Maximum number of results to return. The
794                 actual number of results may be less. (Default: 10)
795               min_rank (int): Lowest permissible rank for the result.
796                 For addressable places this is the minimum
797                 [address rank](../customize/Ranking.md#address-rank). For all
798                 other places the [search rank](../customize/Ranking.md#search-rank)
799                 is used.
800               max_rank (int): Highest permissible rank for the result. See min_rank above.
801               layers (enum): Defines the kind of data to take into account.
802                 See [layers section](Input-Parameter-Types.md#layers) for details.
803                 (Default: addresses and POIs)
804               countries (list[str]): Restrict search to countries with the given
805                 ISO 3166-1 alpha-2 country code. An empty list (the default)
806                 disables this filter. Do not use, when the country parameter
807                 is used.
808               excluded (list[int]): A list of internal IDs of places to exclude
809                 from the search.
810               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
811               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
812                 as a filter and return only results within the bounding box.
813               near (Optional[Point]): Focus search around the given point and
814                 return results ordered by distance to the given point.
815               near_radius (Optional[float]): Restrict results to results within
816                 the given distance in degrees of `near` point. Ignored, when
817                 `near` is not set.
818               categories (list[tuple]): Restrict search to places of the given
819                 categories. The category is the main OSM tag assigned to each
820                 place. An empty list (the default) disables this filter.
821               geometry_output (enum): Add the full geometry of the place to the result.
822                 Multiple formats may be selected. Note that geometries can become
823                 quite large. (Default: none)
824               geometry_simplification (float): Simplification factor to use on
825                 the geometries before returning them. The factor expresses
826                 the tolerance in degrees from which the geometry may differ.
827                 Topology is preserved. (Default: 0.0)
828               address_details (bool): Add detailed information about the places
829                 that make up the address of the requested object. (Default: False)
830               linked_places (bool): Add detailed information about the places
831                 that link to the result. (Default: False)
832               parented_places (bool): Add detailed information about all places
833                 for which the requested object is a parent, i.e. all places for
834                 which the object provides the address details.
835                 Only POI places can have parents. (Default: False)
836               keywords (bool): Add detailed information about the search terms
837                 used for this place.
838
839             Returns:
840               source_table (enum): Data source of the place. See below for possible values.
841               category (tuple): A tuple of two strings with the primary OSM tag
842                   and value.
843               centroid (Point): Point position of the place.
844               place_id (Optional[int]): Internal ID of the place. This ID may differ
845                   for the same place between different installations.
846               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
847               names (Optional[dict]): Dictionary of names of the place. Keys are
848                   usually the corresponding OSM tag keys.
849               address (Optional[dict]): Dictionary of address parts directly
850                   attributed to the place. Keys are usually the corresponding
851                   OSM tag keys with the `addr:` prefix removed.
852               extratags (Optional[dict]): Dictionary of additional attributes for
853                   the place. Usually OSM tag keys and values.
854               housenumber (Optional[str]): House number of the place, normalised
855                   for lookup. To get the house number in its original spelling,
856                   use `address['housenumber']`.
857               postcode (Optional[str]): Computed postcode for the place. To get
858                   directly attributed postcodes, use `address['postcode']` instead.
859               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
860                   The string has the format <language code>:<wikipedia title>.
861               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
862               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
863               importance (Optional[float]): Relative importance of the place. This is a measure
864                   how likely the place will be searched for.
865               country_code (Optional[str]): Country the feature is in as
866                   ISO 3166-1 alpha-2 country code.
867               address_rows (Optional[AddressLines]): List of places that make up the
868                   computed address. `None` when `address_details` parameter was False.
869               linked_rows (Optional[AddressLines]): List of places that link to the object.
870                   `None` when `linked_places` parameter was False.
871               parented_rows (Optional[AddressLines]): List of direct children of the place.
872                   `None` when `parented_places` parameter was False.
873               name_keywords (Optional[WordInfos]): List of search words for the name of
874                    the place. `None` when `keywords` parameter is set to False.
875               address_keywords (Optional[WordInfos]): List of search word for the address of
876                    the place. `None` when `keywords` parameter is set to False.
877               bbox (Bbox): Bounding box of the full geometry of the place.
878                    If the place is a single point, then the size of the bounding
879                    box is guessed according to the type of place.
880               geometry (dict): Dictionary containing the full geometry of the place
881                    in the formats requested in the `geometry_output` parameter.
882         """
883         return self._loop.run_until_complete(
884                    self._async_api.search_address(amenity, street, city, county,
885                                                   state, country, postalcode, **params))
886
887     def search_category(self, categories: List[Tuple[str, str]],
888                         near_query: Optional[str] = None,
889                         **params: Any) -> SearchResults:
890         """ Find an object of a certain category near another place.
891
892             The near place may either be given as an unstructured search
893             query in itself or as a geographic area through the
894             viewbox or near parameters.
895
896             Parameters:
897               categories: Restrict search to places of the given
898                 categories. The category is the main OSM tag assigned to each
899                 place.
900               near_query: Optional free-text query to define the are to
901                 restrict search to.
902
903             Other parameters:
904               max_results (int): Maximum number of results to return. The
905                 actual number of results may be less. (Default: 10)
906               min_rank (int): Lowest permissible rank for the result.
907                 For addressable places this is the minimum
908                 [address rank](../customize/Ranking.md#address-rank). For all
909                 other places the [search rank](../customize/Ranking.md#search-rank)
910                 is used.
911               max_rank (int): Highest permissible rank for the result. See min_rank above.
912               layers (enum): Defines the kind of data to take into account.
913                 See [layers section](Input-Parameter-Types.md#layers) for details.
914                 (Default: addresses and POIs)
915               countries (list[str]): Restrict search to countries with the given
916                 ISO 3166-1 alpha-2 country code. An empty list (the default)
917                 disables this filter.
918               excluded (list[int]): A list of internal IDs of places to exclude
919                 from the search.
920               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
921               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
922                 as a filter and return only results within the bounding box.
923               near (Optional[Point]): Focus search around the given point and
924                 return results ordered by distance to the given point.
925               near_radius (Optional[float]): Restrict results to results within
926                 the given distance in degrees of `near` point. Ignored, when
927                 `near` is not set.
928               geometry_output (enum): Add the full geometry of the place to the result.
929                 Multiple formats may be selected. Note that geometries can become
930                 quite large. (Default: none)
931               geometry_simplification (float): Simplification factor to use on
932                 the geometries before returning them. The factor expresses
933                 the tolerance in degrees from which the geometry may differ.
934                 Topology is preserved. (Default: 0.0)
935               address_details (bool): Add detailed information about the places
936                 that make up the address of the requested object. (Default: False)
937               linked_places (bool): Add detailed information about the places
938                 that link to the result. (Default: False)
939               parented_places (bool): Add detailed information about all places
940                 for which the requested object is a parent, i.e. all places for
941                 which the object provides the address details.
942                 Only POI places can have parents. (Default: False)
943               keywords (bool): Add detailed information about the search terms
944                 used for this place.
945
946             Returns:
947               source_table (enum): Data source of the place. See below for possible values.
948               category (tuple): A tuple of two strings with the primary OSM tag
949                   and value.
950               centroid (Point): Point position of the place.
951               place_id (Optional[int]): Internal ID of the place. This ID may differ
952                   for the same place between different installations.
953               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
954               names (Optional[dict]): Dictionary of names of the place. Keys are
955                   usually the corresponding OSM tag keys.
956               address (Optional[dict]): Dictionary of address parts directly
957                   attributed to the place. Keys are usually the corresponding
958                   OSM tag keys with the `addr:` prefix removed.
959               extratags (Optional[dict]): Dictionary of additional attributes for
960                   the place. Usually OSM tag keys and values.
961               housenumber (Optional[str]): House number of the place, normalised
962                   for lookup. To get the house number in its original spelling,
963                   use `address['housenumber']`.
964               postcode (Optional[str]): Computed postcode for the place. To get
965                   directly attributed postcodes, use `address['postcode']` instead.
966               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
967                   The string has the format <language code>:<wikipedia title>.
968               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
969               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
970               importance (Optional[float]): Relative importance of the place. This is a measure
971                   how likely the place will be searched for.
972               country_code (Optional[str]): Country the feature is in as
973                   ISO 3166-1 alpha-2 country code.
974               address_rows (Optional[AddressLines]): List of places that make up the
975                   computed address. `None` when `address_details` parameter was False.
976               linked_rows (Optional[AddressLines]): List of places that link to the object.
977                   `None` when `linked_places` parameter was False.
978               parented_rows (Optional[AddressLines]): List of direct children of the place.
979                   `None` when `parented_places` parameter was False.
980               name_keywords (Optional[WordInfos]): List of search words for the name of
981                    the place. `None` when `keywords` parameter is set to False.
982               address_keywords (Optional[WordInfos]): List of search word for the address of
983                    the place. `None` when `keywords` parameter is set to False.
984               bbox (Bbox): Bounding box of the full geometry of the place.
985                    If the place is a single point, then the size of the bounding
986                    box is guessed according to the type of place.
987               geometry (dict): Dictionary containing the full geometry of the place
988                    in the formats requested in the `geometry_output` parameter.
989         """
990         return self._loop.run_until_complete(
991                    self._async_api.search_category(categories, near_query, **params))