]> git.openstreetmap.org Git - nominatim.git/blobdiff - nominatim/cli.py
minimum counts for tokens should always be 1
[nominatim.git] / nominatim / cli.py
index c134ca1808c2a2fe7267fc26947c54931bb23ab7..720a8ece33e8e126422490735cdd7c055653ea4c 100644 (file)
@@ -2,13 +2,14 @@
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
 #
 # This file is part of Nominatim. (https://nominatim.org)
 #
-# Copyright (C) 2022 by the Nominatim developer community.
+# Copyright (C) 2023 by the Nominatim developer community.
 # For a full list of authors see the git log.
 """
 Command-line interface to the Nominatim functions for import, update,
 database administration and querying.
 """
 # For a full list of authors see the git log.
 """
 Command-line interface to the Nominatim functions for import, update,
 database administration and querying.
 """
-from typing import Optional, Any, List, Union
+from typing import Optional, Any
+import importlib
 import logging
 import os
 import sys
 import logging
 import os
 import sys
@@ -16,7 +17,7 @@ import argparse
 from pathlib import Path
 
 from nominatim.config import Configuration
 from pathlib import Path
 
 from nominatim.config import Configuration
-from nominatim.tools.exec_utils import run_legacy_script, run_php_server
+from nominatim.tools.exec_utils import run_php_server
 from nominatim.errors import UsageError
 from nominatim import clicmd
 from nominatim import version
 from nominatim.errors import UsageError
 from nominatim import clicmd
 from nominatim import version
@@ -60,7 +61,7 @@ class CommandlineParser:
     def nominatim_version_text(self) -> str:
         """ Program name and version number as string
         """
     def nominatim_version_text(self) -> str:
         """ Program name and version number as string
         """
-        text = f'Nominatim version {version.version_str()}'
+        text = f'Nominatim version {version.NOMINATIM_VERSION!s}'
         if version.GIT_COMMIT_HASH is not None:
             text += f' ({version.GIT_COMMIT_HASH})'
         return text
         if version.GIT_COMMIT_HASH is not None:
             text += f' ({version.GIT_COMMIT_HASH})'
         return text
@@ -100,7 +101,6 @@ class CommandlineParser:
             self.parser.print_help()
             return 1
 
             self.parser.print_help()
             return 1
 
-        args.phpcgi_path = Path(kwargs['phpcgi_path'])
         args.project_dir = Path(args.project_dir).resolve()
 
         if 'cli_args' not in kwargs:
         args.project_dir = Path(args.project_dir).resolve()
 
         if 'cli_args' not in kwargs:
@@ -139,60 +139,6 @@ class CommandlineParser:
 #
 # No need to document the functions each time.
 # pylint: disable=C0111
 #
 # No need to document the functions each time.
 # pylint: disable=C0111
-class QueryExport:
-    """\
-    Export addresses as CSV file from the database.
-    """
-
-    def add_args(self, parser: argparse.ArgumentParser) -> None:
-        group = parser.add_argument_group('Output arguments')
-        group.add_argument('--output-type', default='street',
-                           choices=('continent', 'country', 'state', 'county',
-                                    'city', 'suburb', 'street', 'path'),
-                           help='Type of places to output (default: street)')
-        group.add_argument('--output-format',
-                           default='street;suburb;city;county;state;country',
-                           help=("Semicolon-separated list of address types "
-                                 "(see --output-type). Multiple ranks can be "
-                                 "merged into one column by simply using a "
-                                 "comma-separated list."))
-        group.add_argument('--output-all-postcodes', action='store_true',
-                           help=("List all postcodes for address instead of "
-                                 "just the most likely one"))
-        group.add_argument('--language',
-                           help=("Preferred language for output "
-                                 "(use local name, if omitted)"))
-        group = parser.add_argument_group('Filter arguments')
-        group.add_argument('--restrict-to-country', metavar='COUNTRY_CODE',
-                           help='Export only objects within country')
-        group.add_argument('--restrict-to-osm-node', metavar='ID', type=int,
-                           help='Export only children of this OSM node')
-        group.add_argument('--restrict-to-osm-way', metavar='ID', type=int,
-                           help='Export only children of this OSM way')
-        group.add_argument('--restrict-to-osm-relation', metavar='ID', type=int,
-                           help='Export only children of this OSM relation')
-
-
-    def run(self, args: NominatimArgs) -> int:
-        params: List[Union[int, str]] = [
-                             '--output-type', args.output_type,
-                             '--output-format', args.output_format]
-        if args.output_all_postcodes:
-            params.append('--output-all-postcodes')
-        if args.language:
-            params.extend(('--language', args.language))
-        if args.restrict_to_country:
-            params.extend(('--restrict-to-country', args.restrict_to_country))
-        if args.restrict_to_osm_node:
-            params.extend(('--restrict-to-osm-node', args.restrict_to_osm_node))
-        if args.restrict_to_osm_way:
-            params.extend(('--restrict-to-osm-way', args.restrict_to_osm_way))
-        if args.restrict_to_osm_relation:
-            params.extend(('--restrict-to-osm-relation', args.restrict_to_osm_relation))
-
-        return run_legacy_script('export.php', *params, config=args.config)
-
-
 class AdminServe:
     """\
     Start a simple web server for serving the API.
 class AdminServe:
     """\
     Start a simple web server for serving the API.
@@ -202,7 +148,7 @@ class AdminServe:
     for testing and development. Do not use it in production setups!
 
     There are different webservers available. The default 'php' engine
     for testing and development. Do not use it in production setups!
 
     There are different webservers available. The default 'php' engine
-    runs the classic PHP frontend. 'sanic' and 'falcon' are Python servers
+    runs the classic PHP frontend. The other engines are Python servers
     which run the new Python frontend code. This is highly experimental
     at the moment and may not include the full API.
 
     which run the new Python frontend code. This is highly experimental
     at the moment and may not include the full API.
 
@@ -213,19 +159,18 @@ class AdminServe:
         group = parser.add_argument_group('Server arguments')
         group.add_argument('--server', default='127.0.0.1:8088',
                            help='The address the server will listen to.')
         group = parser.add_argument_group('Server arguments')
         group.add_argument('--server', default='127.0.0.1:8088',
                            help='The address the server will listen to.')
-        group.add_argument('--engine', default='php',
-                           choices=('php', 'sanic', 'falcon'),
-                           help='Webserver framework to run. (default: php)')
+        group.add_argument('--engine', default='falcon',
+                           choices=('php', 'falcon', 'starlette'),
+                           help='Webserver framework to run. (default: falcon)')
 
 
     def run(self, args: NominatimArgs) -> int:
         if args.engine == 'php':
 
 
     def run(self, args: NominatimArgs) -> int:
         if args.engine == 'php':
+            if args.config.lib_dir.php is None:
+                raise UsageError("PHP frontend not configured.")
             run_php_server(args.server, args.project_dir / 'website')
             run_php_server(args.server, args.project_dir / 'website')
-        elif args.engine == 'sanic':
-            import nominatim.server.sanic.server
-
-            app = nominatim.server.sanic.server.get_application(args.project_dir)
-
+        else:
+            import uvicorn # pylint: disable=import-outside-toplevel
             server_info = args.server.split(':', 1)
             host = server_info[0]
             if len(server_info) > 1:
             server_info = args.server.split(':', 1)
             host = server_info[0]
             if len(server_info) > 1:
@@ -234,14 +179,16 @@ class AdminServe:
                 port = int(server_info[1])
             else:
                 port = 8088
                 port = int(server_info[1])
             else:
                 port = 8088
-            app.run(host=host, port=port, debug=True)
-        elif args.engine == 'falcon':
-            raise NotImplementedError('Support for falcon not yet available.')
+
+            server_module = importlib.import_module(f'nominatim.server.{args.engine}.server')
+
+            app = server_module.get_application(args.project_dir)
+            uvicorn.run(app, host=host, port=port)
 
         return 0
 
 
 
         return 0
 
 
-def get_set_parser(**kwargs: Any) -> CommandlineParser:
+def get_set_parser() -> CommandlineParser:
     """\
     Initializes the parser and adds various subcommands for
     nominatim cli.
     """\
     Initializes the parser and adds various subcommands for
     nominatim cli.
@@ -260,17 +207,15 @@ def get_set_parser(**kwargs: Any) -> CommandlineParser:
 
     parser.add_subcommand('admin', clicmd.AdminFuncs())
 
 
     parser.add_subcommand('admin', clicmd.AdminFuncs())
 
-    parser.add_subcommand('export', QueryExport())
+    parser.add_subcommand('export', clicmd.QueryExport())
+    parser.add_subcommand('convert', clicmd.ConvertDB())
     parser.add_subcommand('serve', AdminServe())
 
     parser.add_subcommand('serve', AdminServe())
 
-    if kwargs.get('phpcgi_path'):
-        parser.add_subcommand('search', clicmd.APISearch())
-        parser.add_subcommand('reverse', clicmd.APIReverse())
-        parser.add_subcommand('lookup', clicmd.APILookup())
-        parser.add_subcommand('details', clicmd.APIDetails())
-        parser.add_subcommand('status', clicmd.APIStatus())
-    else:
-        parser.parser.epilog = 'php-cgi not found. Query commands not available.'
+    parser.add_subcommand('search', clicmd.APISearch())
+    parser.add_subcommand('reverse', clicmd.APIReverse())
+    parser.add_subcommand('lookup', clicmd.APILookup())
+    parser.add_subcommand('details', clicmd.APIDetails())
+    parser.add_subcommand('status', clicmd.APIStatus())
 
     return parser
 
 
     return parser
 
@@ -280,6 +225,4 @@ def nominatim(**kwargs: Any) -> int:
     Command-line tools for importing, updating, administrating and
     querying the Nominatim database.
     """
     Command-line tools for importing, updating, administrating and
     querying the Nominatim database.
     """
-    parser = get_set_parser(**kwargs)
-
-    return parser.run(**kwargs)
+    return get_set_parser().run(**kwargs)