2 Nominatim configuration accessor.
6 from pathlib import Path
8 from dotenv import dotenv_values
10 from nominatim.errors import UsageError
12 LOG = logging.getLogger()
15 """ Load and manage the project configuration.
17 Nominatim uses dotenv to configure the software. Configuration options
18 are resolved in the following order:
20 * from the OS environment (or the dirctionary given in `environ`
21 * from the .env file in the project directory of the installation
22 * from the default installation in the configuration directory
24 All Nominatim configuration options are prefixed with 'NOMINATIM_' to
25 avoid conflicts with other environment variables.
28 def __init__(self, project_dir, config_dir, environ=None):
29 self.environ = environ or os.environ
30 self.project_dir = project_dir
31 self.config_dir = config_dir
32 self._config = dotenv_values(str((config_dir / 'env.defaults').resolve()))
33 if project_dir is not None and (project_dir / '.env').is_file():
34 self._config.update(dotenv_values(str((project_dir / '.env').resolve())))
36 # Add defaults for variables that are left empty to set the default.
37 # They may still be overwritten by environment variables.
38 if not self._config['NOMINATIM_ADDRESS_LEVEL_CONFIG']:
39 self._config['NOMINATIM_ADDRESS_LEVEL_CONFIG'] = \
40 str(config_dir / 'address-levels.json')
42 class _LibDirs: # pylint: disable=too-few-public-methods
45 self.lib_dir = _LibDirs()
47 def set_libdirs(self, **kwargs):
48 """ Set paths to library functions and data.
50 for key, value in kwargs.items():
51 setattr(self.lib_dir, key, Path(value).resolve())
53 def __getattr__(self, name):
54 name = 'NOMINATIM_' + name
56 return self.environ.get(name) or self._config[name]
58 def get_bool(self, name):
59 """ Return the given configuration parameter as a boolean.
60 Values of '1', 'yes' and 'true' are accepted as truthy values,
61 everything else is interpreted as false.
63 return self.__getattr__(name).lower() in ('1', 'yes', 'true')
66 def get_int(self, name):
67 """ Return the given configuration parameter as an int.
70 return int(self.__getattr__(name))
72 LOG.fatal("Invalid setting NOMINATIM_%s. Needs to be a number.", name)
73 raise UsageError("Configuration error.")
76 def get_libpq_dsn(self):
77 """ Get configured database DSN converted into the key/value format
78 understood by libpq and psycopg.
80 dsn = self.DATABASE_DSN
82 def quote_param(param):
83 key, val = param.split('=')
84 val = val.replace('\\', '\\\\').replace("'", "\\'")
87 return key + '=' + val
89 if dsn.startswith('pgsql:'):
90 # Old PHP DSN format. Convert before returning.
91 return ' '.join([quote_param(p) for p in dsn[6:].split(';')])
96 def get_import_style_file(self):
97 """ Return the import style file as a path object. Translates the
98 name of the standard styles automatically into a file in the
101 style = self.__getattr__('IMPORT_STYLE')
103 if style in ('admin', 'street', 'address', 'full', 'extratags'):
104 return self.config_dir / 'import-{}.style'.format(style)
109 def get_os_env(self):
110 """ Return a copy of the OS environment with the Nominatim configuration
113 env = dict(self._config)
114 env.update(self.environ)