# Getting Started
-The Nominatim search frontend can directly be used as a Python library in
-scripts and applications. When you have imported your own Nominatim database,
-then it is no longer necessary to run a full web service for it and access
-the database through http requests. With the Nominatim library it is possible
-to access all search functionality directly from your Python code. There are
-also less constraints on the kinds of data that can be accessed. The library
-allows to get access to more detailed information about the objects saved
-in the database.
-
-!!! danger
- The library interface is currently in an experimental stage. There might
- be some smaller adjustments to the public interface until the next version.
-
- The library also misses a proper installation routine, so some manipulation
- of the PYTHONPATH is required. Use is only recommended for advanced Python
- programmers at the moment.
+The Nominatim search frontend is implemented as a Python library and can as
+such directly be used in Python scripts and applications. You don't need to
+set up a web frontend and access it through HTTP calls. The library gives
+direct access to the Nominatim database through similar search functions as
+offered by the web API. In addition, it will give you a more complete and
+detailed view on the search objects stored in the database.
+
+!!! warning
+
+ The Nominatim library is used for accessing a local Nominatim database.
+ It is not meant to be used against web services of Nominatim like the
+ one on https://nominatim.openstreetmap.org. If you need a Python library
+ to access these web services, have a look at
+ [GeoPy](https://geopy.readthedocs.io). Don't forget to consult the
+ usage policy of the service you want to use before accessing such
+ a web service.
## Installation
To use the Nominatim library, you need access to a local Nominatim database.
-Follow the [installation and import instructions](../admin/) to set up your
-database.
+Follow the [installation](../admin/Installation.md) and
+[import](../admin/Import.md) instructions to set up your database.
-It is not yet possible to install it in the usual way via pip or inside a
-virtualenv. To get access to the library you need to set an appropriate
-PYTHONPATH. With the default installation, the python library can be found
-under `/usr/local/share/nominatim/lib-python`. If you have installed
-Nominatim under a different prefix, adapt the `/usr/local/` part accordingly.
-You can also point the PYTHONPATH to the Nominatim source code.
+The Nominatim frontend library is contained in the Python package `nominatim-api`.
+You can install the latest released version directly from pip:
-### A simple search example
+ pip install nominatim-api
+
+To install the package from the source tree directly, run:
+
+ pip install packaging/nominatim-api
+
+Usually you would want to run this in a virtual environment.
+
+## A simple search example
To query the Nominatim database you need to first set up a connection. This
is done by creating an Nominatim API object. This object exposes all the
search functions of Nominatim that are also known from its web API.
-This code snippet implements a simple search for the town if 'Brugge':
+This code snippet implements a simple search for the town of 'Brugge':
!!! example
=== "NominatimAPIAsync"
``` python
- from pathlib import Path
import asyncio
- import nominatim.api as napi
+ import nominatim_api as napi
async def search(query):
- api = napi.NominatimAPIAsync(Path('.'))
-
- return await api.search(query)
+ async with napi.NominatimAPIAsync() as api:
+ return await api.search(query)
results = asyncio.run(search('Brugge'))
if not results:
print('Cannot find Brugge')
else:
- print(f'Found a place at {results[0].centroid.x},{results[1].centroid.y}')
+ print(f'Found a place at {results[0].centroid.x},{results[0].centroid.y}')
```
=== "NominatimAPI"
``` python
- from pathlib import Path
-
- import nominatim.api as napi
+ import nominatim_api as napi
- api = napi.NominatimAPI(Path('.'))
-
- results = api.search('Brugge')
+ with napi.NominatimAPI() as api:
+ results = api.search('Brugge')
if not results:
print('Cannot find Brugge')
else:
- print(f'Found a place at {results[0].centroid.x},{results[1].centroid.y}')
+ print(f'Found a place at {results[0].centroid.x},{results[0].centroid.y}')
```
The Nominatim library is designed around
For smaller scripts there is also a synchronous wrapper around the API. By
using `NominatimAPI`, you get exactly the same interface using classic functions.
-The examples in this chapter will always show how work with both of the
-implementations. The documentation itself will refer usually only to
+The examples in this chapter will always show-case both
+implementations. The documentation itself will usually refer only to
'Nominatim API class' when both flavours are meant. If a functionality is
available only for the synchronous or asynchronous version, this will be
explicitly mentioned.
-### Defining which database to use
+## Defining which database to use
The [Configuration](../admin/Import.md#configuration-setup-in-env)
section explains how Nominatim is configured using the
Nominatim API library. You should therefore be sure you are familiar with
the section.
-The constructor of the 'Nominatim API class' takes one mandatory parameter:
-the path to the [project directory](../admin/Import.md#creating-the-project-directory).
-You should have set up this directory as part of the Nominatim import.
-Any configuration found in the `.env` file in this directory will automatically
-used.
+There are three different ways, how configuration options can be set for
+a 'Nominatim API class'. When you have set up your Nominatim database, you
+have normally created a [project directory](../admin/Import.md#creating-the-project-directory)
+which stores the various configuration and customization files that Nominatim
+needs. You may pass the location of the project directory to your
+'Nominatim API class' constructor and it will read the .env file in the
+directory and set the configuration accordingly. Here is the simple search
+example, using the configuration from a pre-defined project directory in
+`/srv/nominatim-project`:
+
+!!! example
+ === "NominatimAPIAsync"
+ ``` python
+ import asyncio
+
+ import nominatim_api as napi
-The second way to configure your Nominatim setup is through environment variables.
-Normally, Nominatim will check the operating system environment. This can be
-overwritten by giving the constructor a dictionary of configuration parameters.
+ async def search(query):
+ async with napi.NominatimAPIAsync('/srv/nominatim-project') as api:
+ return await api.search(query)
-Let us look up 'Brugge' in the special database named 'belgium' instead of the
-standard 'nominatim' database:
+ results = asyncio.run(search('Brugge'))
+ if not results:
+ print('Cannot find Brugge')
+ else:
+ print(f'Found a place at {results[0].centroid.x},{results[0].centroid.y}')
+ ```
+
+ === "NominatimAPI"
+ ``` python
+ import nominatim_api as napi
+
+ with napi.NominatimAPI('/srv/nominatim-project') as api:
+ results = api.search('Brugge')
+
+ if not results:
+ print('Cannot find Brugge')
+ else:
+ print(f'Found a place at {results[0].centroid.x},{results[0].centroid.y}')
+ ```
+
+
+You may also configure Nominatim by setting environment variables.
+Normally Nominatim will check the operating system environment. Lets
+say you want to look up 'Brugge' in the special database named 'belgium' instead of the
+standard 'nominatim' database. You can run the example script above like this:
+
+```
+NOMINATIM_DATABASE_DSN=pgsql:dbname=belgium python3 example.py
+```
+
+The third option to configure the library is to hand in the configuration
+parameters into the 'Nominatim API class'. Changing the database would look
+like this:
!!! example
=== "NominatimAPIAsync"
``` python
- from pathlib import Path
import asyncio
-
- import nominatim.api as napi
+ import nominatim_api as napi
config_params = {
'NOMINATIM_DATABASE_DSN': 'pgsql:dbname=belgium'
}
async def search(query):
- api = napi.NominatimAPIAsync(Path('.'), environ=config_params)
-
- return await api.search(query)
+ async with napi.NominatimAPIAsync(environ=config_params) as api:
+ return await api.search(query)
results = asyncio.run(search('Brugge'))
```
=== "NominatimAPI"
``` python
- from pathlib import Path
-
- import nominatim.api as napi
+ import nominatim_api as napi
config_params = {
'NOMINATIM_DATABASE_DSN': 'pgsql:dbname=belgium'
}
- api = napi.NominatimAPI(Path('.'), environ=config_params)
-
- results = api.search('Brugge')
+ with napi.NominatimAPI(environ=config_params) as api:
+ results = api.search('Brugge')
```
-### Presenting results to humans
+When the `environ` parameter is given, then only configuration variables
+from this dictionary will be used. The operating system's environment
+variables will be ignored.
-All search functions return the raw results from the database. There is no
-full human-readable label. To create such a label, you need two things:
+## Presenting results to humans
+
+All search functions return full result objects from the database. Such a
+result object contains lots of details: names, address information, OSM tags etc.
+This gives you lots of flexibility what to do with the results.
+
+One of the most common things to get is some kind of human-readable label
+that describes the result in a compact form. Usually this would be the name
+of the object and some parts of the address to explain where in the world
+it is. To create such a label, you need two things:
* the address details of the place
-* adapt the result to the language you wish to use for display
+* all names for the label adapted to the language you wish to use for display
Again searching for 'Brugge', this time with a nicely formatted result:
!!! example
=== "NominatimAPIAsync"
``` python
- from pathlib import Path
import asyncio
- import nominatim.api as napi
+ import nominatim_api as napi
async def search(query):
- api = napi.NominatimAPIAsync(Path('.'))
-
- return await api.search(query, address_details=True)
+ async with napi.NominatimAPIAsync() as api:
+ return await api.search(query, address_details=True)
results = asyncio.run(search('Brugge'))
=== "NominatimAPI"
``` python
- from pathlib import Path
-
- import nominatim.api as napi
-
- api = napi.NominatimAPI(Path('.'))
+ import nominatim_api as napi
- results = api.search('Brugge', address_details=True)
+ with napi.NominatimAPI() as api:
+ results = api.search('Brugge', address_details=True)
locale = napi.Locales(['fr', 'en'])
for i, result in enumerate(results):
places in `address_rows` contain all possible name translation for each row.
The library has a helper class `Locale` which helps extracting a name of a
-place in the preferred language. It gets a list of language code in the
-order of preference. So
+place in the preferred language. It takes a single parameter with a list
+of language codes in the order of preference. So
``` python
locale = napi.Locale(['fr', 'en'])
not possible, it tries English and eventually falls back to the default `name`
or `ref`.
-The Locale object can be applied to a name dictionary to return the best-matching
+The `Locale` object can be applied to a name dictionary to return the best-matching
name out of it:
``` python
This is a fairly simple way to create a human-readable description. The
place information in `address_rows` contains further information about each
-place. For example, which OSM `adlin_level` was used, what category the place
+place. For example, which OSM `admin_level` was used, what category the place
belongs to or what rank Nominatim has assigned. Use this to adapt the output
to local address formats.