]> git.openstreetmap.org Git - nominatim.git/blob - docs/customize/Result-Formatting.md
add documentation for custom formatters
[nominatim.git] / docs / customize / Result-Formatting.md
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._