mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-16 05:18:00 +00:00
260 lines
9.1 KiB
Markdown
260 lines
9.1 KiB
Markdown
# Changing the Appearance of Results in the Server API
|
|
|
|
The Nominatim Server API offers a number of formatting options that
|
|
present search results in [different output formats](../api/Output.md).
|
|
These results only contain a subset of all the information that Nominatim
|
|
has about the result. This page explains how to adapt the result output
|
|
or add additional result formatting.
|
|
|
|
## Defining custom result formatting
|
|
|
|
To change the result output, you need to place a file `api/v1/format.py`
|
|
into your project directory. This file needs to define a single variable
|
|
`dispatch` containing a [FormatDispatcher](#formatdispatcher). This class
|
|
serves to collect the functions for formatting the different result types
|
|
and offers helper functions to apply the formatters.
|
|
|
|
There are two ways to define the `dispatch` variable. If you want to reuse
|
|
the default output formatting and just make some changes or add an additional
|
|
format type, then import the dispatch object from the default API:
|
|
|
|
``` python
|
|
from nominatim_api.v1.format import dispatch as dispatch
|
|
```
|
|
|
|
If you prefer to define a completely new result output, then you can
|
|
create an empty dispatcher object:
|
|
|
|
``` python
|
|
from nominatim_api import FormatDispatcher
|
|
|
|
dispatch = FormatDispatcher()
|
|
```
|
|
|
|
## The formatting function
|
|
|
|
The dispatcher organises the formatting functions by format and result type.
|
|
The format corresponds to the `format` parameter of the API. It can contain
|
|
one of the predefined format names or you can invent your own new format.
|
|
|
|
API calls return data classes or an array of a data class which represent
|
|
the result. You need to make sure there are formatters defined for the
|
|
following result types:
|
|
|
|
* StatusResult (single object, returned by `/status`)
|
|
* DetailedResult (single object, returned by `/details`)
|
|
* SearchResults (list of objects, returned by `/search`)
|
|
* ReverseResults (list of objects, returned by `/reverse` and `/lookup`)
|
|
* RawDataList (simple object, returned by `/deletable` and `/polygons`)
|
|
|
|
A formatter function has the following signature:
|
|
|
|
``` python
|
|
def format_func(result: ResultType, options: Mapping[str, Any]) -> str
|
|
```
|
|
|
|
The options dictionary contains additional information about the original
|
|
query. See the [reference below](#options-for-different-result-types)
|
|
about the possible options.
|
|
|
|
To set the result formatter for a certain result type and format, you need
|
|
to write the format function and decorate it with the
|
|
[`format_func`](#nominatim_api.FormatDispatcher.format_func)
|
|
decorator.
|
|
|
|
For example, let us extend the result for the status call in text format
|
|
and add the server URL. Such a formatter would look like this:
|
|
|
|
``` python
|
|
from nominatim_api import StatusResult
|
|
|
|
@dispatch.format_func(StatusResult, 'text')
|
|
def _format_status_text(result, _):
|
|
header = 'Status for server nominatim.openstreetmap.org'
|
|
if result.status:
|
|
return f"{header}\n\nERROR: {result.message}"
|
|
|
|
return f"{header}\n\nOK"
|
|
```
|
|
|
|
If your dispatcher is derived from the default one, then this definition
|
|
will overwrite the original formatter function. This way it is possible
|
|
to customize the output of selected results.
|
|
|
|
## Adding new formats
|
|
|
|
You may also define a completely different output format. This is as simple
|
|
as adding formatting functions for all result types using the custom
|
|
format name:
|
|
|
|
``` python
|
|
from nominatim_api import StatusResult
|
|
|
|
@dispatch.format_func(StatusResult, 'chatty')
|
|
def _format_status_text(result, _):
|
|
if result.status:
|
|
return f"The server is currently not running. {result.message}"
|
|
|
|
return "Good news! The server is running just fine."
|
|
```
|
|
|
|
That's all. Nominatim will automatically pick up the new format name and
|
|
will allow the user to use it. There is no need to implement formatter
|
|
functions for all the result types, when you invent a new one. The
|
|
available formats will be determined for each API endpoint separately.
|
|
To find out which formats are available, you can use the `--list-formats`
|
|
option of the CLI tool:
|
|
|
|
```
|
|
me@machine:planet-project$ nominatim status --list-formats
|
|
2024-08-16 19:54:00: Using project directory: /home/nominatim/planet-project
|
|
text
|
|
json
|
|
chatty
|
|
debug
|
|
me@machine:planet-project$
|
|
```
|
|
|
|
The `debug` format listed in the last line will always appear. It is a
|
|
special format that enables debug output via the command line (the same
|
|
as the `debug=1` parameter enables for the server API). To not clash
|
|
with this built-in function, you shouldn't name your own format 'debug'.
|
|
|
|
### Content type of new formats
|
|
|
|
All responses will be returned with the content type application/json by
|
|
default. If your format produces a different content type, you need
|
|
to configure the content type with the `set_content_type()` function.
|
|
|
|
For example, the 'chatty' format above returns just simple text. So the
|
|
content type should be set up as:
|
|
|
|
``` python
|
|
from nominatim_api.server.content_types import CONTENT_TEXT
|
|
|
|
dispatch.set_content_type('chatty', CONTENT_TEXT)
|
|
```
|
|
|
|
The `content_types` module used above provides constants for the most
|
|
frequent content types. You set the content type to an arbitrary string,
|
|
if the content type you need is not available.
|
|
|
|
## Formatting error messages
|
|
|
|
Any exception thrown during processing of a request is given to
|
|
a special error formatting function. It takes the requested content type,
|
|
the status code and the error message. It should return the error message
|
|
in a form appropriate for the given content type.
|
|
|
|
You can overwrite the default formatting function with the decorator
|
|
`error_format_func`:
|
|
|
|
``` python
|
|
import nominatim_api.server.content_types as ct
|
|
|
|
@dispatch.error_format_func
|
|
def _format_error(content_type: str, msg: str, status: int) -> str:
|
|
if content_type == ct.CONTENT_XML:
|
|
return f"""<?xml version="1.0" encoding="UTF-8" ?>
|
|
<message>{msg}</message>
|
|
"""
|
|
if content_type == ct.CONTENT_JSON:
|
|
return f'"{msg}"'
|
|
|
|
return f"ERROR: {msg}"
|
|
```
|
|
|
|
|
|
## Debugging custom formatters
|
|
|
|
The easiest way to try out your custom formatter is by using the Nominatim
|
|
CLI commands. Custom formats can be chosen with the `--format` parameter:
|
|
|
|
```
|
|
me@machine:planet-project$ nominatim status --format chatty
|
|
2024-08-16 19:54:00: Using project directory: /home/nominatim/planet-project
|
|
Good news! The server is running just fine.
|
|
me@machine:planet-project$
|
|
```
|
|
|
|
They will also emit full error messages when there is a problem with the
|
|
code you need to debug.
|
|
|
|
!!! danger
|
|
In some cases, when you make an error with your import statement, the
|
|
CLI will not give you an error but instead tell you, that the API
|
|
commands are no longer available:
|
|
|
|
me@machine: nominatim status
|
|
usage: nominatim [-h] [--version] {import,freeze,replication,special-phrases,add-data,index,refresh,admin} ...
|
|
nominatim: error: argument subcommand: invalid choice: 'status'
|
|
|
|
This happens because the CLI tool is meant to still work when the
|
|
nominatim-api package is not installed. Import errors involving
|
|
`nominatim_api` are interpreted as "package not installed".
|
|
|
|
Use the help command to find out which is the offending import that
|
|
could not be found:
|
|
|
|
me@machine: nominatim -h
|
|
... [other help text] ...
|
|
Nominatim API package not found (was looking for module: nominatim_api.xxx).
|
|
|
|
## Reference
|
|
|
|
### FormatDispatcher
|
|
|
|
::: nominatim_api.FormatDispatcher
|
|
options:
|
|
heading_level: 6
|
|
group_by_category: False
|
|
|
|
### JsonWriter
|
|
|
|
::: nominatim_api.utils.json_writer.JsonWriter
|
|
options:
|
|
heading_level: 6
|
|
group_by_category: False
|
|
|
|
### Options for different result types
|
|
|
|
This section lists the options that may be handed in with the different result
|
|
types in the v1 version of the Nominatim API.
|
|
|
|
#### StatusResult
|
|
|
|
_None._
|
|
|
|
#### DetailedResult
|
|
|
|
| Option | Description |
|
|
|-----------------|-------------|
|
|
| locales | [Locale](../library/Result-Handling.md#locale) object for the requested language(s) |
|
|
| group_hierarchy | Setting of [group_hierarchy](../api/Details.md#output-details) parameter |
|
|
| icon_base_url | (optional) URL pointing to icons as set in [NOMINATIM_MAPICON_URL](Settings.md#nominatim_mapicon_url) |
|
|
|
|
#### SearchResults
|
|
|
|
| Option | Description |
|
|
|-----------------|-------------|
|
|
| query | Original query string |
|
|
| more_url | URL for requesting additional results for the same query |
|
|
| exclude_place_ids | List of place IDs already returned |
|
|
| viewbox | Setting of [viewbox](../api/Search.md#result-restriction) parameter |
|
|
| extratags | Setting of [extratags](../api/Search.md#output-details) parameter |
|
|
| namedetails | Setting of [namedetails](../api/Search.md#output-details) parameter |
|
|
| addressdetails | Setting of [addressdetails](../api/Search.md#output-details) parameter |
|
|
|
|
#### ReverseResults
|
|
|
|
| Option | Description |
|
|
|-----------------|-------------|
|
|
| query | Original query string |
|
|
| extratags | Setting of [extratags](../api/Search.md#output-details) parameter |
|
|
| namedetails | Setting of [namedetails](../api/Search.md#output-details) parameter |
|
|
| addressdetails | Setting of [addressdetails](../api/Search.md#output-details) parameter |
|
|
|
|
#### RawDataList
|
|
|
|
_None._
|