]> git.openstreetmap.org Git - nominatim.git/blobdiff - docs/customize/Result-Formatting.md
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / docs / customize / Result-Formatting.md
index 52a49af3b6b4a8df21f616768357cc9573c0a0dd..f3ac7f5a1ec1d600b90ece058fa6ae33b503df40 100644 (file)
@@ -66,6 +66,8 @@ 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'
@@ -86,19 +88,39 @@ 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 f"Good news! The server is running just fine."
+    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. Make sure to really define formatters for
-**all** result types. If they are for endpoints that you do not intend to
-use, you can simply return some static string but the function needs to be
-there.
+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
@@ -117,6 +139,67 @@ 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