]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/clicmd/args.py
add type annotations for command line functions
[nominatim.git] / nominatim / clicmd / args.py
1 # SPDX-License-Identifier: GPL-2.0-only
2 #
3 # This file is part of Nominatim. (https://nominatim.org)
4 #
5 # Copyright (C) 2022 by the Nominatim developer community.
6 # For a full list of authors see the git log.
7 """
8 Provides custom functions over command-line arguments.
9 """
10 from typing import Optional, List, Dict, Any, Sequence, Tuple
11 import argparse
12 import logging
13 from pathlib import Path
14
15 from typing_extensions import Protocol
16
17 from nominatim.errors import UsageError
18 from nominatim.config import Configuration
19
20 LOG = logging.getLogger()
21
22 class Subcommand(Protocol):
23     """
24     Interface to be implemented by classes implementing a CLI subcommand.
25     """
26
27     def add_args(self, parser: argparse.ArgumentParser) -> None:
28         """
29         Fill the given parser for the subcommand with the appropriate
30         parameters.
31         """
32
33     def run(self, args: 'NominatimArgs') -> int:
34         """
35         Run the subcommand with the given parsed arguments.
36         """
37
38
39 class NominatimArgs:
40     """ Customized namespace class for the nominatim command line tool
41         to receive the command-line arguments.
42     """
43     # Basic environment set by root program.
44     config: Configuration
45     project_dir: Path
46     module_dir: Path
47     osm2pgsql_path: Path
48     phplib_dir: Path
49     sqllib_dir: Path
50     data_dir: Path
51     config_dir: Path
52     phpcgi_path: Path
53
54     # Global switches
55     version: bool
56     subcommand: Optional[str]
57     command: Subcommand
58
59     # Shared parameters
60     osm2pgsql_cache: Optional[int]
61     socket_timeout: int
62
63     # Arguments added to all subcommands.
64     verbose: int
65     threads: Optional[int]
66
67     # Arguments to 'add-data'
68     file: Optional[str]
69     diff: Optional[str]
70     node: Optional[int]
71     way: Optional[int]
72     relation: Optional[int]
73     tiger_data: Optional[str]
74     use_main_api: bool
75
76     # Arguments to 'admin'
77     warm: bool
78     check_database: bool
79     migrate: bool
80     analyse_indexing: bool
81     target: Optional[str]
82     osm_id: Optional[str]
83     place_id: Optional[int]
84
85     # Arguments to 'import'
86     osm_file: List[str]
87     continue_at: Optional[str]
88     reverse_only: bool
89     no_partitions: bool
90     no_updates: bool
91     offline: bool
92     ignore_errors: bool
93     index_noanalyse: bool
94
95     # Arguments to 'index'
96     boundaries_only: bool
97     no_boundaries: bool
98     minrank: int
99     maxrank: int
100
101     # Arguments to 'export'
102     output_type: str
103     output_format: str
104     output_all_postcodes: bool
105     language: Optional[str]
106     restrict_to_country: Optional[str]
107     restrict_to_osm_node: Optional[int]
108     restrict_to_osm_way: Optional[int]
109     restrict_to_osm_relation: Optional[int]
110
111     # Arguments to 'refresh'
112     postcodes: bool
113     word_tokens: bool
114     word_counts: bool
115     address_levels: bool
116     functions: bool
117     wiki_data: bool
118     importance: bool
119     website: bool
120     diffs: bool
121     enable_debug_statements: bool
122     data_object: Sequence[Tuple[str, int]]
123     data_area: Sequence[Tuple[str, int]]
124
125     # Arguments to 'replication'
126     init: bool
127     update_functions: bool
128     check_for_updates: bool
129     once: bool
130     catch_up: bool
131     do_index: bool
132
133     # Arguments to 'serve'
134     server: str
135
136     # Arguments to 'special-phrases
137     import_from_wiki: bool
138     import_from_csv: Optional[str]
139     no_replace: bool
140
141     # Arguments to all query functions
142     format: str
143     addressdetails: bool
144     extratags: bool
145     namedetails: bool
146     lang: Optional[str]
147     polygon_output: Optional[str]
148     polygon_threshold: Optional[float]
149
150     # Arguments to 'search'
151     query: Optional[str]
152     street: Optional[str]
153     city: Optional[str]
154     county: Optional[str]
155     state: Optional[str]
156     country: Optional[str]
157     postalcode: Optional[str]
158     countrycodes: Optional[str]
159     exclude_place_ids: Optional[str]
160     limit: Optional[int]
161     viewbox: Optional[str]
162     bounded: bool
163     dedupe: bool
164
165     # Arguments to 'reverse'
166     lat: float
167     lon: float
168     zoom: Optional[int]
169
170     # Arguments to 'lookup'
171     ids: Sequence[str]
172
173     # Arguments to 'details'
174     object_class: Optional[str]
175
176
177     def osm2pgsql_options(self, default_cache: int,
178                           default_threads: int) -> Dict[str, Any]:
179         """ Return the standard osm2pgsql options that can be derived
180             from the command line arguments. The resulting dict can be
181             further customized and then used in `run_osm2pgsql()`.
182         """
183         return dict(osm2pgsql=self.config.OSM2PGSQL_BINARY or self.osm2pgsql_path,
184                     osm2pgsql_cache=self.osm2pgsql_cache or default_cache,
185                     osm2pgsql_style=self.config.get_import_style_file(),
186                     threads=self.threads or default_threads,
187                     dsn=self.config.get_libpq_dsn(),
188                     flatnode_file=str(self.config.get_path('FLATNODE_FILE') or ''),
189                     tablespaces=dict(slim_data=self.config.TABLESPACE_OSM_DATA,
190                                      slim_index=self.config.TABLESPACE_OSM_INDEX,
191                                      main_data=self.config.TABLESPACE_PLACE_DATA,
192                                      main_index=self.config.TABLESPACE_PLACE_INDEX
193                                     )
194                    )
195
196
197     def get_osm_file_list(self) -> Optional[List[Path]]:
198         """ Return the --osm-file argument as a list of Paths or None
199             if no argument was given. The function also checks if the files
200             exist and raises a UsageError if one cannot be found.
201         """
202         if not self.osm_file:
203             return None
204
205         files = [Path(f) for f in self.osm_file]
206         for fname in files:
207             if not fname.is_file():
208                 LOG.fatal("OSM file '%s' does not exist.", fname)
209                 raise UsageError('Cannot access file.')
210
211         return files