|
| 1 | +# Changing the Appearance of Results in the Server API |
| 2 | + |
| 3 | +The Nominatim Server API offers a number of formatting options that |
| 4 | +present search results in [different output formats](../api/Output.md). |
| 5 | +These results only contain a subset of all the information that Nominatim |
| 6 | +has about the result. This page explains how to adapt the result output |
| 7 | +or add additional result formatting. |
| 8 | + |
| 9 | +## Defining custom result formatting |
| 10 | + |
| 11 | +To change the result output, you need to place a file `api/v1/format.py` |
| 12 | +into your project directory. This file needs to define a single variable |
| 13 | +`dispatch` containing a [FormatDispatcher](#formatdispatcher). This class |
| 14 | +serves to collect the functions for formatting the different result types |
| 15 | +and offers helper functions to apply the formatters. |
| 16 | + |
| 17 | +There are two ways to define the `dispatch` variable. If you want to reuse |
| 18 | +the default output formatting and just make some changes or add an additional |
| 19 | +format type, then import the dispatch object from the default API: |
| 20 | + |
| 21 | +``` python |
| 22 | +from nominatim_api.v1.format import dispatch as dispatch |
| 23 | +``` |
| 24 | + |
| 25 | +If you prefer to define a completely new result output, then you can |
| 26 | +create an empty dispatcher object: |
| 27 | + |
| 28 | +``` python |
| 29 | +from nominatim_api import FormatDispatcher |
| 30 | + |
| 31 | +dispatch = FormatDispatcher() |
| 32 | +``` |
| 33 | + |
| 34 | +## The formatting function |
| 35 | + |
| 36 | +The dispatcher organises the formatting functions by format and result type. |
| 37 | +The format corresponds to the `format` parameter of the API. It can contain |
| 38 | +one of the predefined format names or you can invent your own new format. |
| 39 | + |
| 40 | +API calls return data classes or an array of a data class which represent |
| 41 | +the result. You need to make sure there are formatters defined for the |
| 42 | +following result types: |
| 43 | + |
| 44 | +* StatusResult (single object, returned by `/status`) |
| 45 | +* DetailedResult (single object, returned by `/details`) |
| 46 | +* SearchResults (list of objects, returned by `/search`) |
| 47 | +* ReverseResults (list of objects, returned by `/reverse` and `/lookup`) |
| 48 | +* RawDataList (simple object, returned by `/deletable` and `/polygons`) |
| 49 | + |
| 50 | +A formatter function has the following signature: |
| 51 | + |
| 52 | +``` python |
| 53 | +def format_func(result: ResultType, options: Mapping[str, Any]) -> str |
| 54 | +``` |
| 55 | + |
| 56 | +The options dictionary contains additional information about the original |
| 57 | +query. See the [reference below](#options-for-different-result-types) |
| 58 | +about the possible options. |
| 59 | + |
| 60 | +To set the result formatter for a certain result type and format, you need |
| 61 | +to write the format function and decorate it with the |
| 62 | +[`format_func`](#nominatim_api.FormatDispatcher.format_func) |
| 63 | +decorator. |
| 64 | + |
| 65 | +For example, let us extend the result for the status call in text format |
| 66 | +and add the server URL. Such a formatter would look like this: |
| 67 | + |
| 68 | +``` python |
| 69 | +@dispatch.format_func(StatusResult, 'text') |
| 70 | +def _format_status_text(result, _): |
| 71 | + header = 'Status for server nominatim.openstreetmap.org' |
| 72 | + if result.status: |
| 73 | + return f"{header}\n\nERROR: {result.message}" |
| 74 | + |
| 75 | + return f"{header}\n\nOK" |
| 76 | +``` |
| 77 | + |
| 78 | +If your dispatcher is derived from the default one, then this definition |
| 79 | +will overwrite the original formatter function. This way it is possible |
| 80 | +to customize the output of selected results. |
| 81 | + |
| 82 | +## Adding new formats |
| 83 | + |
| 84 | +You may also define a completely different output format. This is as simple |
| 85 | +as adding formatting functions for all result types using the custom |
| 86 | +format name: |
| 87 | + |
| 88 | +``` python |
| 89 | +@dispatch.format_func(StatusResult, 'chatty') |
| 90 | +def _format_status_text(result, _): |
| 91 | + if result.status: |
| 92 | + return f"The server is currently not running. {result.message}" |
| 93 | + |
| 94 | + return f"Good news! The server is running just fine." |
| 95 | +``` |
| 96 | + |
| 97 | +That's all. Nominatim will automatically pick up the new format name and |
| 98 | +will allow the user to use it. Make sure to really define formatters for |
| 99 | +**all** result types. If they are for endpoints that you do not intend to |
| 100 | +use, you can simply return some static string but the function needs to be |
| 101 | +there. |
| 102 | + |
| 103 | +All responses will be returned with the content type application/json by |
| 104 | +default. If your format produces a different content type, you need |
| 105 | +to configure the content type with the `set_content_type()` function. |
| 106 | + |
| 107 | +For example, the 'chatty' format above returns just simple text. So the |
| 108 | +content type should be set up as: |
| 109 | + |
| 110 | +``` python |
| 111 | +from nominatim_api.server.content_types import CONTENT_TEXT |
| 112 | + |
| 113 | +dispatch.set_content_type('chatty', CONTENT_TEXT) |
| 114 | +``` |
| 115 | + |
| 116 | +The `content_types` module used above provides constants for the most |
| 117 | +frequent content types. You set the content type to an arbitrary string, |
| 118 | +if the content type you need is not available. |
| 119 | + |
| 120 | +## Reference |
| 121 | + |
| 122 | +### FormatDispatcher |
| 123 | + |
| 124 | +::: nominatim_api.FormatDispatcher |
| 125 | + options: |
| 126 | + heading_level: 6 |
| 127 | + group_by_category: False |
| 128 | + |
| 129 | +### JsonWriter |
| 130 | + |
| 131 | +::: nominatim_api.utils.json_writer.JsonWriter |
| 132 | + options: |
| 133 | + heading_level: 6 |
| 134 | + group_by_category: False |
| 135 | + |
| 136 | +### Options for different result types |
| 137 | + |
| 138 | +This section lists the options that may be handed in with the different result |
| 139 | +types in the v1 version of the Nominatim API. |
| 140 | + |
| 141 | +#### StatusResult |
| 142 | + |
| 143 | +_None._ |
| 144 | + |
| 145 | +#### DetailedResult |
| 146 | + |
| 147 | +| Option | Description | |
| 148 | +|-----------------|-------------| |
| 149 | +| locales | [Locale](../library/Result-Handling.md#locale) object for the requested language(s) | |
| 150 | +| group_hierarchy | Setting of [group_hierarchy](../api/Details.md#output-details) parameter | |
| 151 | +| icon_base_url | (optional) URL pointing to icons as set in [NOMINATIM_MAPICON_URL](Settings.md#nominatim_mapicon_url) | |
| 152 | + |
| 153 | +#### SearchResults |
| 154 | + |
| 155 | +| Option | Description | |
| 156 | +|-----------------|-------------| |
| 157 | +| query | Original query string | |
| 158 | +| more_url | URL for requesting additional results for the same query | |
| 159 | +| exclude_place_ids | List of place IDs already returned | |
| 160 | +| viewbox | Setting of [viewbox](../api/Search.md#result-restriction) parameter | |
| 161 | +| extratags | Setting of [extratags](../api/Search.md#output-details) parameter | |
| 162 | +| namedetails | Setting of [namedetails](../api/Search.md#output-details) parameter | |
| 163 | +| addressdetails | Setting of [addressdetails](../api/Search.md#output-details) parameter | |
| 164 | + |
| 165 | +#### ReverseResults |
| 166 | + |
| 167 | +| Option | Description | |
| 168 | +|-----------------|-------------| |
| 169 | +| query | Original query string | |
| 170 | +| extratags | Setting of [extratags](../api/Search.md#output-details) parameter | |
| 171 | +| namedetails | Setting of [namedetails](../api/Search.md#output-details) parameter | |
| 172 | +| addressdetails | Setting of [addressdetails](../api/Search.md#output-details) parameter | |
| 173 | + |
| 174 | +#### RawDataList |
| 175 | + |
| 176 | +_None._ |
0 commit comments