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