]> git.openstreetmap.org Git - nominatim.git/blobdiff - src/nominatim_db/cli.py
look up all places at once
[nominatim.git] / src / nominatim_db / cli.py
index 41684fa1dbe9e37bf9c1d3e1a2c9ded9e7767715..f5f74208d3c7ba64eb01d5ed367e17738d6d63db 100644 (file)
@@ -14,17 +14,18 @@ import logging
 import os
 import sys
 import argparse
+import asyncio
 from pathlib import Path
 
 from .config import Configuration
 from .errors import UsageError
-from .tools.exec_utils import run_php_server
 from . import clicmd
 from . import version
 from .clicmd.args import NominatimArgs, Subcommand
 
 LOG = logging.getLogger()
 
+
 class CommandlineParser:
     """ Wraps some of the common functions for parsing the command line
         and setting up subcommands.
@@ -57,7 +58,6 @@ class CommandlineParser:
         group.add_argument('-j', '--threads', metavar='NUM', type=int,
                            help='Number of parallel threads to use')
 
-
     def nominatim_version_text(self) -> str:
         """ Program name and version number as string
         """
@@ -66,7 +66,6 @@ class CommandlineParser:
             text += f' ({version.GIT_COMMIT_HASH})'
         return text
 
-
     def add_subcommand(self, name: str, cmd: Subcommand) -> None:
         """ Add a subcommand to the parser. The subcommand must be a class
             with a function add_args() that adds the parameters for the
@@ -82,7 +81,6 @@ class CommandlineParser:
         parser.set_defaults(command=cmd)
         cmd.add_args(parser)
 
-
     def run(self, **kwargs: Any) -> int:
         """ Parse the command line arguments of the program and execute the
             appropriate subcommand.
@@ -111,17 +109,18 @@ class CommandlineParser:
 
         args.config = Configuration(args.project_dir,
                                     environ=kwargs.get('environ', os.environ))
-        args.config.set_libdirs(module=kwargs['module_dir'],
-                                osm2pgsql=kwargs['osm2pgsql_path'])
+        args.config.set_libdirs(osm2pgsql=kwargs['osm2pgsql_path'])
 
         log = logging.getLogger()
         log.warning('Using project directory: %s', str(args.project_dir))
 
         try:
-            return args.command.run(args)
+            ret = args.command.run(args)
+
+            return ret
         except UsageError as exception:
             if log.isEnabledFor(logging.DEBUG):
-                raise # use Python's exception printing
+                raise  # use Python's exception printing
             log.fatal('FATAL: %s', exception)
 
         # If we get here, then execution has failed in some way.
@@ -138,7 +137,6 @@ class CommandlineParser:
 # a subcommand.
 #
 # No need to document the functions each time.
-# pylint: disable=C0111
 class AdminServe:
     """\
     Start a simple web server for serving the API.
@@ -147,10 +145,10 @@ class AdminServe:
     from the current project directory. This webserver is only suitable
     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. 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.
+    There are two different webserver implementations for Python available:
+    falcon (the default) and starlette. You need to make sure the
+    appropriate Python packages as well as the uvicorn package are
+    installed to use this function.
 
     By the default, the webserver can be accessed at: http://127.0.0.1:8088
     """
@@ -160,32 +158,33 @@ class AdminServe:
         group.add_argument('--server', default='127.0.0.1:8088',
                            help='The address the server will listen to.')
         group.add_argument('--engine', default='falcon',
-                           choices=('php', 'falcon', 'starlette'),
+                           choices=('falcon', 'starlette'),
                            help='Webserver framework to run. (default: falcon)')
 
-
     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')
+        asyncio.run(self.run_uvicorn(args))
+
+        return 0
+
+    async def run_uvicorn(self, args: NominatimArgs) -> None:
+        import uvicorn
+
+        server_info = args.server.split(':', 1)
+        host = server_info[0]
+        if len(server_info) > 1:
+            if not server_info[1].isdigit():
+                raise UsageError('Invalid format for --server parameter. Use <host>:<port>')
+            port = int(server_info[1])
         else:
-            import uvicorn # pylint: disable=import-outside-toplevel
-            server_info = args.server.split(':', 1)
-            host = server_info[0]
-            if len(server_info) > 1:
-                if not server_info[1].isdigit():
-                    raise UsageError('Invalid format for --server parameter. Use <host>:<port>')
-                port = int(server_info[1])
-            else:
-                port = 8088
+            port = 8088
 
-            server_module = importlib.import_module(f'nominatim_api.server.{args.engine}.server')
+        server_module = importlib.import_module(f'nominatim_api.server.{args.engine}.server')
 
-            app = server_module.get_application(args.project_dir)
-            uvicorn.run(app, host=host, port=port)
+        app = server_module.get_application(args.project_dir)
 
-        return 0
+        config = uvicorn.Config(app, host=host, port=port)
+        server = uvicorn.Server(config)
+        await server.serve()
 
 
 def get_set_parser() -> CommandlineParser:
@@ -222,15 +221,15 @@ def get_set_parser() -> CommandlineParser:
         parser.add_subcommand('details', apicmd.APIDetails())
         parser.add_subcommand('status', apicmd.APIStatus())
     except ModuleNotFoundError as ex:
-        if not ex.name or 'nominatim_api' not in ex.name: # pylint: disable=E1135
+        if not ex.name or 'nominatim_api' not in ex.name:
             raise ex
 
         parser.parser.epilog = \
-            '\n\nNominatim API package not found. The following commands are not available:'\
+            f'\n\nNominatim API package not found (was looking for module: {ex.name}).'\
+            '\nThe following commands are not available:'\
             '\n    export, convert, serve, search, reverse, lookup, details, status'\
             "\n\nRun 'pip install nominatim-api' to install the package."
 
-
     return parser