]> git.openstreetmap.org Git - nominatim.git/blob - nominatim/tools/exec_utils.py
add Python package configuration
[nominatim.git] / nominatim / tools / exec_utils.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 Helper functions for executing external programs.
9 """
10 from typing import Any, Mapping, IO
11 import logging
12 import os
13 import subprocess
14 import shutil
15 import urllib.request as urlrequest
16
17 from nominatim.typing import StrPath
18 from nominatim.version import NOMINATIM_VERSION
19 from nominatim.db.connection import get_pg_env
20
21 LOG = logging.getLogger()
22
23 def run_php_server(server_address: str, base_dir: StrPath) -> None:
24     """ Run the built-in server from the given directory.
25     """
26     subprocess.run(['/usr/bin/env', 'php', '-S', server_address],
27                    cwd=str(base_dir), check=True)
28
29
30 def run_osm2pgsql(options: Mapping[str, Any]) -> None:
31     """ Run osm2pgsql with the given options.
32     """
33     env = get_pg_env(options['dsn'])
34
35     osm2pgsql_cmd = options['osm2pgsql']
36     if osm2pgsql_cmd is None:
37         osm2pgsql_cmd = shutil.which('osm2pgsql')
38         if osm2pgsql_cmd is None:
39             raise RuntimeError('osm2pgsql executable not found. Please install osm2pgsql first.')
40
41     cmd = [str(osm2pgsql_cmd),
42            '--slim',
43            '--log-progress', 'true',
44            '--number-processes', '1' if options['append'] else str(options['threads']),
45            '--cache', str(options['osm2pgsql_cache']),
46            '--style', str(options['osm2pgsql_style'])
47           ]
48
49     if str(options['osm2pgsql_style']).endswith('.lua'):
50         env['LUA_PATH'] = ';'.join((str(options['osm2pgsql_style_path'] / '?.lua'),
51                                     os.environ.get('LUAPATH', ';')))
52         cmd.extend(('--output', 'flex'))
53     else:
54         cmd.extend(('--output', 'gazetteer', '--hstore', '--latlon'))
55
56     cmd.append('--append' if options['append'] else '--create')
57
58     if options['flatnode_file']:
59         cmd.extend(('--flat-nodes', options['flatnode_file']))
60
61     for key, param in (('slim_data', '--tablespace-slim-data'),
62                        ('slim_index', '--tablespace-slim-index'),
63                        ('main_data', '--tablespace-main-data'),
64                        ('main_index', '--tablespace-main-index')):
65         if options['tablespaces'][key]:
66             cmd.extend((param, options['tablespaces'][key]))
67
68     if options['tablespaces']['main_data']:
69         env['NOMINATIM_TABLESPACE_PLACE_DATA'] = options['tablespaces']['main_data']
70     if options['tablespaces']['main_index']:
71         env['NOMINATIM_TABLESPACE_PLACE_INDEX'] = options['tablespaces']['main_index']
72
73     if options.get('disable_jit', False):
74         env['PGOPTIONS'] = '-c jit=off -c max_parallel_workers_per_gather=0'
75
76     if 'import_data' in options:
77         cmd.extend(('-r', 'xml', '-'))
78     elif isinstance(options['import_file'], list):
79         for fname in options['import_file']:
80             cmd.append(str(fname))
81     else:
82         cmd.append(str(options['import_file']))
83
84     subprocess.run(cmd, cwd=options.get('cwd', '.'),
85                    input=options.get('import_data'),
86                    env=env, check=True)
87
88
89 def get_url(url: str) -> str:
90     """ Get the contents from the given URL and return it as a UTF-8 string.
91     """
92     headers = {"User-Agent": f"Nominatim/{NOMINATIM_VERSION!s}"}
93
94     try:
95         request = urlrequest.Request(url, headers=headers)
96         with urlrequest.urlopen(request) as response: # type: IO[bytes]
97             return response.read().decode('utf-8')
98     except Exception:
99         LOG.fatal('Failed to load URL: %s', url)
100         raise