X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/0add25e33500110a36458a0bb3fa292d408d2b85..2c61fe08a031bd4ccbe47c62c021321e2dff7510:/src/nominatim_db/cli.py diff --git a/src/nominatim_db/cli.py b/src/nominatim_db/cli.py index 93278668..8d4585c6 100644 --- a/src/nominatim_db/cli.py +++ b/src/nominatim_db/cli.py @@ -2,16 +2,15 @@ # # This file is part of Nominatim. (https://nominatim.org) # -# Copyright (C) 2024 by the Nominatim developer community. +# Copyright (C) 2025 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. """ -from typing import Optional, Any +from typing import Optional, List, Mapping import importlib import logging -import os import sys import argparse import asyncio @@ -19,13 +18,13 @@ 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. @@ -58,7 +57,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 """ @@ -67,7 +65,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 @@ -83,14 +80,14 @@ class CommandlineParser: parser.set_defaults(command=cmd) cmd.add_args(parser) - - def run(self, **kwargs: Any) -> int: + def run(self, cli_args: Optional[List[str]], + environ: Optional[Mapping[str, str]]) -> int: """ Parse the command line arguments of the program and execute the appropriate subcommand. """ args = NominatimArgs() try: - self.parser.parse_args(args=kwargs.get('cli_args'), namespace=args) + self.parser.parse_args(args=cli_args, namespace=args) except SystemExit: return 1 @@ -104,16 +101,13 @@ class CommandlineParser: args.project_dir = Path(args.project_dir).resolve() - if 'cli_args' not in kwargs: + if cli_args is None: logging.basicConfig(stream=sys.stderr, format='%(asctime)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=max(4 - args.verbose, 1) * 10) - 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 = Configuration(args.project_dir, environ=environ) log = logging.getLogger() log.warning('Using project directory: %s', str(args.project_dir)) @@ -122,7 +116,7 @@ class CommandlineParser: return args.command.run(args) 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. @@ -139,7 +133,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. @@ -148,10 +141,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 """ @@ -161,23 +154,16 @@ 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') - else: - asyncio.run(self.run_uvicorn(args)) + asyncio.run(self.run_uvicorn(args)) return 0 - async def run_uvicorn(self, args: NominatimArgs) -> None: - import uvicorn # pylint: disable=import-outside-toplevel + import uvicorn server_info = args.server.split(':', 1) host = server_info[0] @@ -231,21 +217,28 @@ 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 -def nominatim(**kwargs: Any) -> int: +def nominatim(cli_args: Optional[List[str]] = None, + environ: Optional[Mapping[str, str]] = None) -> int: """\ Command-line tools for importing, updating, administrating and querying the Nominatim database. + + 'cli_args' is a list of parameters for the command to run. If not given, + sys.args will be used. + + 'environ' is the dictionary of environment variables containing the + Nominatim configuration. When None, the os.environ is inherited. """ - return get_set_parser().run(**kwargs) + return get_set_parser().run(cli_args=cli_args, environ=environ)