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