]> git.openstreetmap.org Git - nominatim.git/blob - src/nominatim_api/core.py
apply request timeout also while waiting for a connection from pool
[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         async with self.begin(abs_timeout=timeout.abs) as conn:
221             conn.set_query_timeout(self.query_timeout)
222             if details.keywords:
223                 await nsearch.make_query_analyzer(conn)
224             return await get_detailed_place(conn, place, details)
225
226     async def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
227         """ Get simple information about a list of places.
228
229             Returns a list of place information for all IDs that were found.
230         """
231         timeout = Timeout(self.request_timeout)
232         details = ntyp.LookupDetails.from_kwargs(params)
233         async with self.begin(abs_timeout=timeout.abs) as conn:
234             conn.set_query_timeout(self.query_timeout)
235             if details.keywords:
236                 await nsearch.make_query_analyzer(conn)
237             return await get_places(conn, places, details)
238
239     async def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
240         """ Find a place by its coordinates. Also known as reverse geocoding.
241
242             Returns the closest result that can be found or None if
243             no place matches the given criteria.
244         """
245         # The following negation handles NaN correctly. Don't change.
246         if not abs(coord[0]) <= 180 or not abs(coord[1]) <= 90:
247             # There are no results to be expected outside valid coordinates.
248             return None
249
250         timeout = Timeout(self.request_timeout)
251         details = ntyp.ReverseDetails.from_kwargs(params)
252         async with self.begin(abs_timeout=timeout.abs) as conn:
253             conn.set_query_timeout(self.query_timeout)
254             if details.keywords:
255                 await nsearch.make_query_analyzer(conn)
256             geocoder = ReverseGeocoder(conn, details,
257                                        self.reverse_restrict_to_country_area)
258             return await geocoder.lookup(coord)
259
260     async def search(self, query: str, **params: Any) -> SearchResults:
261         """ Find a place by free-text search. Also known as forward geocoding.
262         """
263         query = query.strip()
264         if not query:
265             raise UsageError('Nothing to search for.')
266
267         timeout = Timeout(self.request_timeout)
268         async with self.begin(abs_timeout=timeout.abs) as conn:
269             conn.set_query_timeout(self.query_timeout)
270             geocoder = nsearch.ForwardGeocoder(conn, ntyp.SearchDetails.from_kwargs(params),
271                                                timeout)
272             phrases = [nsearch.Phrase(nsearch.PHRASE_ANY, p.strip()) for p in query.split(',')]
273             return await geocoder.lookup(phrases)
274
275     async def search_address(self, amenity: Optional[str] = None,
276                              street: Optional[str] = None,
277                              city: Optional[str] = None,
278                              county: Optional[str] = None,
279                              state: Optional[str] = None,
280                              country: Optional[str] = None,
281                              postalcode: Optional[str] = None,
282                              **params: Any) -> SearchResults:
283         """ Find an address using structured search.
284         """
285         timeout = Timeout(self.request_timeout)
286         async with self.begin(abs_timeout=timeout.abs) as conn:
287             conn.set_query_timeout(self.query_timeout)
288             details = ntyp.SearchDetails.from_kwargs(params)
289
290             phrases: List[nsearch.Phrase] = []
291
292             if amenity:
293                 phrases.append(nsearch.Phrase(nsearch.PHRASE_AMENITY, amenity))
294             if street:
295                 phrases.append(nsearch.Phrase(nsearch.PHRASE_STREET, street))
296             if city:
297                 phrases.append(nsearch.Phrase(nsearch.PHRASE_CITY, city))
298             if county:
299                 phrases.append(nsearch.Phrase(nsearch.PHRASE_COUNTY, county))
300             if state:
301                 phrases.append(nsearch.Phrase(nsearch.PHRASE_STATE, state))
302             if postalcode:
303                 phrases.append(nsearch.Phrase(nsearch.PHRASE_POSTCODE, postalcode))
304             if country:
305                 phrases.append(nsearch.Phrase(nsearch.PHRASE_COUNTRY, country))
306
307             if not phrases:
308                 raise UsageError('Nothing to search for.')
309
310             if amenity or street:
311                 details.restrict_min_max_rank(26, 30)
312             elif city:
313                 details.restrict_min_max_rank(13, 25)
314             elif county:
315                 details.restrict_min_max_rank(10, 12)
316             elif state:
317                 details.restrict_min_max_rank(5, 9)
318             elif postalcode:
319                 details.restrict_min_max_rank(5, 11)
320             else:
321                 details.restrict_min_max_rank(4, 4)
322
323             if details.layers is None:
324                 details.layers = ntyp.DataLayer.ADDRESS
325                 if amenity:
326                     details.layers |= ntyp.DataLayer.POI
327
328             geocoder = nsearch.ForwardGeocoder(conn, details, timeout)
329             return await geocoder.lookup(phrases)
330
331     async def search_category(self, categories: List[Tuple[str, str]],
332                               near_query: Optional[str] = None,
333                               **params: Any) -> SearchResults:
334         """ Find an object of a certain category near another place.
335             The near place may either be given as an unstructured search
336             query in itself or as coordinates.
337         """
338         if not categories:
339             return SearchResults()
340
341         timeout = Timeout(self.request_timeout)
342         details = ntyp.SearchDetails.from_kwargs(params)
343         async with self.begin(abs_timeout=timeout.abs) as conn:
344             conn.set_query_timeout(self.query_timeout)
345             if near_query:
346                 phrases = [nsearch.Phrase(nsearch.PHRASE_ANY, p) for p in near_query.split(',')]
347             else:
348                 phrases = []
349                 if details.keywords:
350                     await nsearch.make_query_analyzer(conn)
351
352             geocoder = nsearch.ForwardGeocoder(conn, details, timeout)
353             return await geocoder.lookup_pois(categories, phrases)
354
355
356 class NominatimAPI:
357     """ This class provides a thin synchronous wrapper around the asynchronous
358         Nominatim functions. It creates its own event loop and runs each
359         synchronous function call to completion using that loop.
360
361         This class should usually be used as a context manager in 'with' context.
362     """
363
364     def __init__(self, project_dir: Optional[Union[str, Path]] = None,
365                  environ: Optional[Mapping[str, str]] = None) -> None:
366         """ Initiate a new frontend object with synchronous API functions.
367
368             Parameters:
369               project_dir: Path to the
370                   [project directory](../admin/Import.md#creating-the-project-directory)
371                   of the local Nominatim installation.
372               environ: Mapping of [configuration parameters](../customize/Settings.md).
373                   When set, replaces any configuration via environment variables.
374                   Settings in this mapping also have precedence over any
375                   parameters found in the `.env` file of the project directory.
376         """
377         self._loop = asyncio.new_event_loop()
378         self._async_api = NominatimAPIAsync(project_dir, environ, loop=self._loop)
379
380     def close(self) -> None:
381         """ Close all active connections to the database.
382
383             This function also closes the asynchronous worker loop making
384             the NominatimAPI object unusable.
385         """
386         if not self._loop.is_closed():
387             self._loop.run_until_complete(self._async_api.close())
388             self._loop.close()
389
390     def __enter__(self) -> 'NominatimAPI':
391         return self
392
393     def __exit__(self, *_: Any) -> None:
394         self.close()
395
396     @property
397     def config(self) -> Configuration:
398         """ Provide read-only access to the [configuration](Configuration.md)
399             used by the API.
400         """
401         return self._async_api.config
402
403     def status(self) -> StatusResult:
404         """ Return the status of the database as a dataclass object
405             with the fields described below.
406
407             Returns:
408               status(int): A status code as described on the status page.
409               message(str): Either 'OK' or a human-readable message of the
410                   problem encountered.
411               software_version(tuple): A tuple with the version of the
412                   Nominatim library consisting of (major, minor, patch, db-patch)
413                   version.
414               database_version(tuple): A tuple with the version of the library
415                   which was used for the import or last migration.
416                   Also consists of (major, minor, patch, db-patch).
417               data_updated(datetime): Timestamp with the age of the data.
418         """
419         return self._loop.run_until_complete(self._async_api.status())
420
421     def details(self, place: ntyp.PlaceRef, **params: Any) -> Optional[DetailedResult]:
422         """ Get detailed information about a place in the database.
423
424             The result is a dataclass object with the fields described below
425             or `None` if the place could not be found in the database.
426
427             Parameters:
428               place: Description of the place to look up. See
429                      [Place identification](Input-Parameter-Types.md#place-identification)
430                      for the various ways to reference a place.
431
432             Other parameters:
433               geometry_output (enum): Add the full geometry of the place to the result.
434                 Multiple formats may be selected. Note that geometries can become
435                 quite large. (Default: none)
436               geometry_simplification (float): Simplification factor to use on
437                 the geometries before returning them. The factor expresses
438                 the tolerance in degrees from which the geometry may differ.
439                 Topology is preserved. (Default: 0.0)
440               address_details (bool): Add detailed information about the places
441                 that make up the address of the requested object. (Default: False)
442               linked_places (bool): Add detailed information about the places
443                 that link to the result. (Default: False)
444               parented_places (bool): Add detailed information about all places
445                 for which the requested object is a parent, i.e. all places for
446                 which the object provides the address details.
447                 Only POI places can have parents. (Default: False)
448               keywords (bool): Add detailed information about the search terms
449                 used for this place.
450
451             Returns:
452               source_table (enum): Data source of the place. See below for possible values.
453               category (tuple): A tuple of two strings with the primary OSM tag
454                   and value.
455               centroid (Point): Point position of the place.
456               place_id (Optional[int]): Internal ID of the place. This ID may differ
457                   for the same place between different installations.
458               parent_place_id (Optional(int]): Internal ID of the parent of this
459                   place. Only meaning full for POI-like objects (places with a
460                   rank_address of 30).
461               linked_place_id (Optional[int]): Internal ID of the place this object
462                   links to. When this ID is set then there is no guarantee that
463                   the rest of the result information is complete.
464               admin_level (int): Value of the `admin_level` OSM tag. Only meaningful
465                   for administrative boundary objects.
466               indexed_date (datetime): Timestamp when the place was last updated.
467               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
468               names (Optional[dict]): Dictionary of names of the place. Keys are
469                   usually the corresponding OSM tag keys.
470               address (Optional[dict]): Dictionary of address parts directly
471                   attributed to the place. Keys are usually the corresponding
472                   OSM tag keys with the `addr:` prefix removed.
473               extratags (Optional[dict]): Dictionary of additional attributes for
474                   the place. Usually OSM tag keys and values.
475               housenumber (Optional[str]): House number of the place, normalised
476                   for lookup. To get the house number in its original spelling,
477                   use `address['housenumber']`.
478               postcode (Optional[str]): Computed postcode for the place. To get
479                   directly attributed postcodes, use `address['postcode']` instead.
480               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
481                   The string has the format <language code>:<wikipedia title>.
482               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
483               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
484               importance (Optional[float]): Relative importance of the place. This is a measure
485                   how likely the place will be searched for.
486               country_code (Optional[str]): Country the feature is in as
487                   ISO 3166-1 alpha-2 country code.
488               address_rows (Optional[AddressLines]): List of places that make up the
489                   computed address. `None` when `address_details` parameter was False.
490               linked_rows (Optional[AddressLines]): List of places that link to the object.
491                   `None` when `linked_places` parameter was False.
492               parented_rows (Optional[AddressLines]): List of direct children of the place.
493                   `None` when `parented_places` parameter was False.
494               name_keywords (Optional[WordInfos]): List of search words for the name of
495                    the place. `None` when `keywords` parameter is set to False.
496               address_keywords (Optional[WordInfos]): List of search word for the address of
497                    the place. `None` when `keywords` parameter is set to False.
498               geometry (dict): Dictionary containing the full geometry of the place
499                    in the formats requested in the `geometry_output` parameter.
500         """
501         return self._loop.run_until_complete(self._async_api.details(place, **params))
502
503     def lookup(self, places: Sequence[ntyp.PlaceRef], **params: Any) -> SearchResults:
504         """ Get simple information about a list of places.
505
506             Returns a list of place information for all IDs that were found.
507             Each result is a dataclass with the fields detailed below.
508
509             Parameters:
510               places: List of descriptions of the place to look up. See
511                       [Place identification](Input-Parameter-Types.md#place-identification)
512                       for the various ways to reference a place.
513
514             Other parameters:
515               geometry_output (enum): Add the full geometry of the place to the result.
516                 Multiple formats may be selected. Note that geometries can become
517                 quite large. (Default: none)
518               geometry_simplification (float): Simplification factor to use on
519                 the geometries before returning them. The factor expresses
520                 the tolerance in degrees from which the geometry may differ.
521                 Topology is preserved. (Default: 0.0)
522               address_details (bool): Add detailed information about the places
523                 that make up the address of the requested object. (Default: False)
524               linked_places (bool): Add detailed information about the places
525                 that link to the result. (Default: False)
526               parented_places (bool): Add detailed information about all places
527                 for which the requested object is a parent, i.e. all places for
528                 which the object provides the address details.
529                 Only POI places can have parents. (Default: False)
530               keywords (bool): Add detailed information about the search terms
531                 used for this place.
532
533             Returns:
534               source_table (enum): Data source of the place. See below for possible values.
535               category (tuple): A tuple of two strings with the primary OSM tag
536                   and value.
537               centroid (Point): Point position of the place.
538               place_id (Optional[int]): Internal ID of the place. This ID may differ
539                   for the same place between different installations.
540               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
541               names (Optional[dict]): Dictionary of names of the place. Keys are
542                   usually the corresponding OSM tag keys.
543               address (Optional[dict]): Dictionary of address parts directly
544                   attributed to the place. Keys are usually the corresponding
545                   OSM tag keys with the `addr:` prefix removed.
546               extratags (Optional[dict]): Dictionary of additional attributes for
547                   the place. Usually OSM tag keys and values.
548               housenumber (Optional[str]): House number of the place, normalised
549                   for lookup. To get the house number in its original spelling,
550                   use `address['housenumber']`.
551               postcode (Optional[str]): Computed postcode for the place. To get
552                   directly attributed postcodes, use `address['postcode']` instead.
553               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
554                   The string has the format <language code>:<wikipedia title>.
555               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
556               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
557               importance (Optional[float]): Relative importance of the place. This is a measure
558                   how likely the place will be searched for.
559               country_code (Optional[str]): Country the feature is in as
560                   ISO 3166-1 alpha-2 country code.
561               address_rows (Optional[AddressLines]): List of places that make up the
562                   computed address. `None` when `address_details` parameter was False.
563               linked_rows (Optional[AddressLines]): List of places that link to the object.
564                   `None` when `linked_places` parameter was False.
565               parented_rows (Optional[AddressLines]): List of direct children of the place.
566                   `None` when `parented_places` parameter was False.
567               name_keywords (Optional[WordInfos]): List of search words for the name of
568                    the place. `None` when `keywords` parameter is set to False.
569               address_keywords (Optional[WordInfos]): List of search word for the address of
570                    the place. `None` when `keywords` parameter is set to False.
571               bbox (Bbox): Bounding box of the full geometry of the place.
572                    If the place is a single point, then the size of the bounding
573                    box is guessed according to the type of place.
574               geometry (dict): Dictionary containing the full geometry of the place
575                    in the formats requested in the `geometry_output` parameter.
576         """
577         return self._loop.run_until_complete(self._async_api.lookup(places, **params))
578
579     def reverse(self, coord: ntyp.AnyPoint, **params: Any) -> Optional[ReverseResult]:
580         """ Find a place by its coordinates. Also known as reverse geocoding.
581
582             Returns the closest result that can be found or `None` if
583             no place matches the given criteria. The result is a dataclass
584             with the fields as detailed below.
585
586             Parameters:
587               coord: Coordinate to lookup the place for as a Point
588                      or a tuple (x, y). Must be in WGS84 projection.
589
590             Other parameters:
591               max_rank (int): Highest address rank to return. Can be used to
592                 restrict search to streets or settlements.
593               layers (enum): Defines the kind of data to take into account.
594                 See description of layers below. (Default: addresses and POIs)
595               geometry_output (enum): Add the full geometry of the place to the result.
596                 Multiple formats may be selected. Note that geometries can become
597                 quite large. (Default: none)
598               geometry_simplification (float): Simplification factor to use on
599                 the geometries before returning them. The factor expresses
600                 the tolerance in degrees from which the geometry may differ.
601                 Topology is preserved. (Default: 0.0)
602               address_details (bool): Add detailed information about the places
603                 that make up the address of the requested object. (Default: False)
604               linked_places (bool): Add detailed information about the places
605                 that link to the result. (Default: False)
606               parented_places (bool): Add detailed information about all places
607                 for which the requested object is a parent, i.e. all places for
608                 which the object provides the address details.
609                 Only POI places can have parents. (Default: False)
610               keywords (bool): Add detailed information about the search terms
611                 used for this place.
612
613             Returns:
614               source_table (enum): Data source of the place. See below for possible values.
615               category (tuple): A tuple of two strings with the primary OSM tag
616                   and value.
617               centroid (Point): Point position of the place.
618               place_id (Optional[int]): Internal ID of the place. This ID may differ
619                   for the same place between different installations.
620               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
621               names (Optional[dict]): Dictionary of names of the place. Keys are
622                   usually the corresponding OSM tag keys.
623               address (Optional[dict]): Dictionary of address parts directly
624                   attributed to the place. Keys are usually the corresponding
625                   OSM tag keys with the `addr:` prefix removed.
626               extratags (Optional[dict]): Dictionary of additional attributes for
627                   the place. Usually OSM tag keys and values.
628               housenumber (Optional[str]): House number of the place, normalised
629                   for lookup. To get the house number in its original spelling,
630                   use `address['housenumber']`.
631               postcode (Optional[str]): Computed postcode for the place. To get
632                   directly attributed postcodes, use `address['postcode']` instead.
633               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
634                   The string has the format <language code>:<wikipedia title>.
635               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
636               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
637               importance (Optional[float]): Relative importance of the place. This is a measure
638                   how likely the place will be searched for.
639               country_code (Optional[str]): Country the feature is in as
640                   ISO 3166-1 alpha-2 country code.
641               address_rows (Optional[AddressLines]): List of places that make up the
642                   computed address. `None` when `address_details` parameter was False.
643               linked_rows (Optional[AddressLines]): List of places that link to the object.
644                   `None` when `linked_places` parameter was False.
645               parented_rows (Optional[AddressLines]): List of direct children of the place.
646                   `None` when `parented_places` parameter was False.
647               name_keywords (Optional[WordInfos]): List of search words for the name of
648                    the place. `None` when `keywords` parameter is set to False.
649               address_keywords (Optional[WordInfos]): List of search word for the address of
650                    the place. `None` when `keywords` parameter is set to False.
651               bbox (Bbox): Bounding box of the full geometry of the place.
652                    If the place is a single point, then the size of the bounding
653                    box is guessed according to the type of place.
654               geometry (dict): Dictionary containing the full geometry of the place
655                    in the formats requested in the `geometry_output` parameter.
656               distance (Optional[float]): Distance in degree from the input point.
657         """
658         return self._loop.run_until_complete(self._async_api.reverse(coord, **params))
659
660     def search(self, query: str, **params: Any) -> SearchResults:
661         """ Find a place by free-text search. Also known as forward geocoding.
662
663             Parameters:
664               query: Free-form text query searching for a place.
665
666             Other parameters:
667               max_results (int): Maximum number of results to return. The
668                 actual number of results may be less. (Default: 10)
669               min_rank (int): Lowest permissible rank for the result.
670                 For addressable places this is the minimum
671                 [address rank](../customize/Ranking.md#address-rank). For all
672                 other places the [search rank](../customize/Ranking.md#search-rank)
673                 is used.
674               max_rank (int): Highest permissible rank for the result. See min_rank above.
675               layers (enum): Defines the kind of data to take into account.
676                 See [layers section](Input-Parameter-Types.md#layers) for details.
677                 (Default: addresses and POIs)
678               countries (list[str]): Restrict search to countries with the given
679                 ISO 3166-1 alpha-2 country code. An empty list (the default)
680                 disables this filter.
681               excluded (list[int]): A list of internal IDs of places to exclude
682                 from the search.
683               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
684               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
685                 as a filter and return only results within the bounding box.
686               near (Optional[Point]): Focus search around the given point and
687                 return results ordered by distance to the given point.
688               near_radius (Optional[float]): Restrict results to results within
689                 the given distance in degrees of `near` point. Ignored, when
690                 `near` is not set.
691               categories (list[tuple]): Restrict search to places of the given
692                 categories. The category is the main OSM tag assigned to each
693                 place. An empty list (the default) disables this filter.
694               geometry_output (enum): Add the full geometry of the place to the result.
695                 Multiple formats may be selected. Note that geometries can become
696                 quite large. (Default: none)
697               geometry_simplification (float): Simplification factor to use on
698                 the geometries before returning them. The factor expresses
699                 the tolerance in degrees from which the geometry may differ.
700                 Topology is preserved. (Default: 0.0)
701               address_details (bool): Add detailed information about the places
702                 that make up the address of the requested object. (Default: False)
703               linked_places (bool): Add detailed information about the places
704                 that link to the result. (Default: False)
705               parented_places (bool): Add detailed information about all places
706                 for which the requested object is a parent, i.e. all places for
707                 which the object provides the address details.
708                 Only POI places can have parents. (Default: False)
709               keywords (bool): Add detailed information about the search terms
710                 used for this place.
711
712             Returns:
713               source_table (enum): Data source of the place. See below for possible values.
714               category (tuple): A tuple of two strings with the primary OSM tag
715                   and value.
716               centroid (Point): Point position of the place.
717               place_id (Optional[int]): Internal ID of the place. This ID may differ
718                   for the same place between different installations.
719               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
720               names (Optional[dict]): Dictionary of names of the place. Keys are
721                   usually the corresponding OSM tag keys.
722               address (Optional[dict]): Dictionary of address parts directly
723                   attributed to the place. Keys are usually the corresponding
724                   OSM tag keys with the `addr:` prefix removed.
725               extratags (Optional[dict]): Dictionary of additional attributes for
726                   the place. Usually OSM tag keys and values.
727               housenumber (Optional[str]): House number of the place, normalised
728                   for lookup. To get the house number in its original spelling,
729                   use `address['housenumber']`.
730               postcode (Optional[str]): Computed postcode for the place. To get
731                   directly attributed postcodes, use `address['postcode']` instead.
732               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
733                   The string has the format <language code>:<wikipedia title>.
734               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
735               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
736               importance (Optional[float]): Relative importance of the place. This is a measure
737                   how likely the place will be searched for.
738               country_code (Optional[str]): Country the feature is in as
739                   ISO 3166-1 alpha-2 country code.
740               address_rows (Optional[AddressLines]): List of places that make up the
741                   computed address. `None` when `address_details` parameter was False.
742               linked_rows (Optional[AddressLines]): List of places that link to the object.
743                   `None` when `linked_places` parameter was False.
744               parented_rows (Optional[AddressLines]): List of direct children of the place.
745                   `None` when `parented_places` parameter was False.
746               name_keywords (Optional[WordInfos]): List of search words for the name of
747                    the place. `None` when `keywords` parameter is set to False.
748               address_keywords (Optional[WordInfos]): List of search word for the address of
749                    the place. `None` when `keywords` parameter is set to False.
750               bbox (Bbox): Bounding box of the full geometry of the place.
751                    If the place is a single point, then the size of the bounding
752                    box is guessed according to the type of place.
753               geometry (dict): Dictionary containing the full geometry of the place
754                    in the formats requested in the `geometry_output` parameter.
755         """
756         return self._loop.run_until_complete(
757                    self._async_api.search(query, **params))
758
759     def search_address(self, amenity: Optional[str] = None,
760                        street: Optional[str] = None,
761                        city: Optional[str] = None,
762                        county: Optional[str] = None,
763                        state: Optional[str] = None,
764                        country: Optional[str] = None,
765                        postalcode: Optional[str] = None,
766                        **params: Any) -> SearchResults:
767         """ Find an address using structured search.
768
769             Parameters:
770               amenity: Name of a POI.
771               street: Street and optionally housenumber of the address. If the address
772                 does not have a street, then the place the housenumber references to.
773               city: Postal city of the address.
774               county: County equivalent of the address. Does not exist in all
775                 jurisdictions.
776               state: State or province of the address.
777               country: Country with its full name or its ISO 3166-1 alpha-2 country code.
778                 Do not use together with the country_code filter.
779               postalcode: Post code or ZIP for the place.
780
781             Other parameters:
782               max_results (int): Maximum number of results to return. The
783                 actual number of results may be less. (Default: 10)
784               min_rank (int): Lowest permissible rank for the result.
785                 For addressable places this is the minimum
786                 [address rank](../customize/Ranking.md#address-rank). For all
787                 other places the [search rank](../customize/Ranking.md#search-rank)
788                 is used.
789               max_rank (int): Highest permissible rank for the result. See min_rank above.
790               layers (enum): Defines the kind of data to take into account.
791                 See [layers section](Input-Parameter-Types.md#layers) for details.
792                 (Default: addresses and POIs)
793               countries (list[str]): Restrict search to countries with the given
794                 ISO 3166-1 alpha-2 country code. An empty list (the default)
795                 disables this filter. Do not use, when the country parameter
796                 is used.
797               excluded (list[int]): A list of internal IDs of places to exclude
798                 from the search.
799               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
800               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
801                 as a filter and return only results within the bounding box.
802               near (Optional[Point]): Focus search around the given point and
803                 return results ordered by distance to the given point.
804               near_radius (Optional[float]): Restrict results to results within
805                 the given distance in degrees of `near` point. Ignored, when
806                 `near` is not set.
807               categories (list[tuple]): Restrict search to places of the given
808                 categories. The category is the main OSM tag assigned to each
809                 place. An empty list (the default) disables this filter.
810               geometry_output (enum): Add the full geometry of the place to the result.
811                 Multiple formats may be selected. Note that geometries can become
812                 quite large. (Default: none)
813               geometry_simplification (float): Simplification factor to use on
814                 the geometries before returning them. The factor expresses
815                 the tolerance in degrees from which the geometry may differ.
816                 Topology is preserved. (Default: 0.0)
817               address_details (bool): Add detailed information about the places
818                 that make up the address of the requested object. (Default: False)
819               linked_places (bool): Add detailed information about the places
820                 that link to the result. (Default: False)
821               parented_places (bool): Add detailed information about all places
822                 for which the requested object is a parent, i.e. all places for
823                 which the object provides the address details.
824                 Only POI places can have parents. (Default: False)
825               keywords (bool): Add detailed information about the search terms
826                 used for this place.
827
828             Returns:
829               source_table (enum): Data source of the place. See below for possible values.
830               category (tuple): A tuple of two strings with the primary OSM tag
831                   and value.
832               centroid (Point): Point position of the place.
833               place_id (Optional[int]): Internal ID of the place. This ID may differ
834                   for the same place between different installations.
835               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
836               names (Optional[dict]): Dictionary of names of the place. Keys are
837                   usually the corresponding OSM tag keys.
838               address (Optional[dict]): Dictionary of address parts directly
839                   attributed to the place. Keys are usually the corresponding
840                   OSM tag keys with the `addr:` prefix removed.
841               extratags (Optional[dict]): Dictionary of additional attributes for
842                   the place. Usually OSM tag keys and values.
843               housenumber (Optional[str]): House number of the place, normalised
844                   for lookup. To get the house number in its original spelling,
845                   use `address['housenumber']`.
846               postcode (Optional[str]): Computed postcode for the place. To get
847                   directly attributed postcodes, use `address['postcode']` instead.
848               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
849                   The string has the format <language code>:<wikipedia title>.
850               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
851               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
852               importance (Optional[float]): Relative importance of the place. This is a measure
853                   how likely the place will be searched for.
854               country_code (Optional[str]): Country the feature is in as
855                   ISO 3166-1 alpha-2 country code.
856               address_rows (Optional[AddressLines]): List of places that make up the
857                   computed address. `None` when `address_details` parameter was False.
858               linked_rows (Optional[AddressLines]): List of places that link to the object.
859                   `None` when `linked_places` parameter was False.
860               parented_rows (Optional[AddressLines]): List of direct children of the place.
861                   `None` when `parented_places` parameter was False.
862               name_keywords (Optional[WordInfos]): List of search words for the name of
863                    the place. `None` when `keywords` parameter is set to False.
864               address_keywords (Optional[WordInfos]): List of search word for the address of
865                    the place. `None` when `keywords` parameter is set to False.
866               bbox (Bbox): Bounding box of the full geometry of the place.
867                    If the place is a single point, then the size of the bounding
868                    box is guessed according to the type of place.
869               geometry (dict): Dictionary containing the full geometry of the place
870                    in the formats requested in the `geometry_output` parameter.
871         """
872         return self._loop.run_until_complete(
873                    self._async_api.search_address(amenity, street, city, county,
874                                                   state, country, postalcode, **params))
875
876     def search_category(self, categories: List[Tuple[str, str]],
877                         near_query: Optional[str] = None,
878                         **params: Any) -> SearchResults:
879         """ Find an object of a certain category near another place.
880
881             The near place may either be given as an unstructured search
882             query in itself or as a geographic area through the
883             viewbox or near parameters.
884
885             Parameters:
886               categories: Restrict search to places of the given
887                 categories. The category is the main OSM tag assigned to each
888                 place.
889               near_query: Optional free-text query to define the are to
890                 restrict search to.
891
892             Other parameters:
893               max_results (int): Maximum number of results to return. The
894                 actual number of results may be less. (Default: 10)
895               min_rank (int): Lowest permissible rank for the result.
896                 For addressable places this is the minimum
897                 [address rank](../customize/Ranking.md#address-rank). For all
898                 other places the [search rank](../customize/Ranking.md#search-rank)
899                 is used.
900               max_rank (int): Highest permissible rank for the result. See min_rank above.
901               layers (enum): Defines the kind of data to take into account.
902                 See [layers section](Input-Parameter-Types.md#layers) for details.
903                 (Default: addresses and POIs)
904               countries (list[str]): Restrict search to countries with the given
905                 ISO 3166-1 alpha-2 country code. An empty list (the default)
906                 disables this filter.
907               excluded (list[int]): A list of internal IDs of places to exclude
908                 from the search.
909               viewbox (Optional[Bbox]): Bounding box of an area to focus search on.
910               bounded_viewbox (bool): Consider the bounding box given in `viewbox`
911                 as a filter and return only results within the bounding box.
912               near (Optional[Point]): Focus search around the given point and
913                 return results ordered by distance to the given point.
914               near_radius (Optional[float]): Restrict results to results within
915                 the given distance in degrees of `near` point. Ignored, when
916                 `near` is not set.
917               geometry_output (enum): Add the full geometry of the place to the result.
918                 Multiple formats may be selected. Note that geometries can become
919                 quite large. (Default: none)
920               geometry_simplification (float): Simplification factor to use on
921                 the geometries before returning them. The factor expresses
922                 the tolerance in degrees from which the geometry may differ.
923                 Topology is preserved. (Default: 0.0)
924               address_details (bool): Add detailed information about the places
925                 that make up the address of the requested object. (Default: False)
926               linked_places (bool): Add detailed information about the places
927                 that link to the result. (Default: False)
928               parented_places (bool): Add detailed information about all places
929                 for which the requested object is a parent, i.e. all places for
930                 which the object provides the address details.
931                 Only POI places can have parents. (Default: False)
932               keywords (bool): Add detailed information about the search terms
933                 used for this place.
934
935             Returns:
936               source_table (enum): Data source of the place. See below for possible values.
937               category (tuple): A tuple of two strings with the primary OSM tag
938                   and value.
939               centroid (Point): Point position of the place.
940               place_id (Optional[int]): Internal ID of the place. This ID may differ
941                   for the same place between different installations.
942               osm_object (Optional[tuple]): OSM type and ID of the place, if available.
943               names (Optional[dict]): Dictionary of names of the place. Keys are
944                   usually the corresponding OSM tag keys.
945               address (Optional[dict]): Dictionary of address parts directly
946                   attributed to the place. Keys are usually the corresponding
947                   OSM tag keys with the `addr:` prefix removed.
948               extratags (Optional[dict]): Dictionary of additional attributes for
949                   the place. Usually OSM tag keys and values.
950               housenumber (Optional[str]): House number of the place, normalised
951                   for lookup. To get the house number in its original spelling,
952                   use `address['housenumber']`.
953               postcode (Optional[str]): Computed postcode for the place. To get
954                   directly attributed postcodes, use `address['postcode']` instead.
955               wikipedia (Optional[str]): Reference to a wikipedia site for the place.
956                   The string has the format <language code>:<wikipedia title>.
957               rank_address (int): [Address rank](../customize/Ranking.md#address-rank).
958               rank_search (int): [Search rank](../customize/Ranking.md#search-rank).
959               importance (Optional[float]): Relative importance of the place. This is a measure
960                   how likely the place will be searched for.
961               country_code (Optional[str]): Country the feature is in as
962                   ISO 3166-1 alpha-2 country code.
963               address_rows (Optional[AddressLines]): List of places that make up the
964                   computed address. `None` when `address_details` parameter was False.
965               linked_rows (Optional[AddressLines]): List of places that link to the object.
966                   `None` when `linked_places` parameter was False.
967               parented_rows (Optional[AddressLines]): List of direct children of the place.
968                   `None` when `parented_places` parameter was False.
969               name_keywords (Optional[WordInfos]): List of search words for the name of
970                    the place. `None` when `keywords` parameter is set to False.
971               address_keywords (Optional[WordInfos]): List of search word for the address of
972                    the place. `None` when `keywords` parameter is set to False.
973               bbox (Bbox): Bounding box of the full geometry of the place.
974                    If the place is a single point, then the size of the bounding
975                    box is guessed according to the type of place.
976               geometry (dict): Dictionary containing the full geometry of the place
977                    in the formats requested in the `geometry_output` parameter.
978         """
979         return self._loop.run_until_complete(
980                    self._async_api.search_category(categories, near_query, **params))