# Configuring RiskScape

## Projects

Most of the configuration RiskScape uses is specified in a :ref:`project file <projects>`.
The `project.ini` file is like a 'work-space' that tells RiskScape what :ref:`models` it can run,
and what :ref:`functions`, :ref:`Bookmarks <bookmarks>`, and :ref:`types` can be used in the model.

## Settings

The :ref:`settings_ini` can be used to configure *global* RiskScape settings.

The contents of the `project.ini` file will vary depending on what you are modelling,
whereas the `settings.ini` file contains a smaller subset of RiskScape configuration that
will apply *every* time you run RiskScape.

## Secrets

The :ref:`secrets_ini` can be used to configure secrets that can be applied to requests for remote resources.

## Plugins

RiskScape has an extensible architecture. This means you can use :ref:`plugins` to enable or disable
related sets of functionality. By enabling optional plugins you can unlock more RiskScape features,
such as support for NetCDF input data.


.. _multiline-values:

## INI file format

RiskScape uses the [INI file format](https://en.wikipedia.org/wiki/INI_file) with one major
enhancement - it allows for multi-line configuration values using triple quotes.

```ini
[model example]
description = """
This is a
multi-line description
"""
```

Multi-line values are surrounded by three quote characters, using one of `"""`, `'''`, or `` ``` ``.
It makes sense to use a quote character that you're not likely to be using in the string itself.

```ini
[function example]
framework = python
source = '''
def function(exposure, hazard):
  """Python docstrings use triple quotes"""
  pass
'''
```

.. tip:: Multi-line values are particularly useful for :ref:`inline-functions`

### Comments

It is possible to add python-style comments to your configuration files to leave behind
information that is not included as part of the configuration.  Python-style comments
begin with a `#` and stop at the end of the line:

```ini
# An old version of our risk function
[function risk_old]
```

You can also put comments at the end of a line following a section header or a value.
When adding comments at the end of a line, it is important to add a space before the `#`:

```ini
map-attribute.id = OBJECTID # shapefiles always have this
```

Note that previous versions of RiskScape would have included the comment in the
value for `map-attribute.id`.  If you want to include a comment as part of a
configuration value, it's advised that you surround the value in triple quotes:

```ini
map-attribute.construction_type = '''
  # this expression calls a function to map the type
  if(const_type == 'wood',
  ...
'''
```

.. _on_conflict:

### Extending and Replacing sections

By default, RiskScape will use the first INI file section with a given key that it encounters. For example, if the project defines two bookmarks with the same name, then the first one seen will be used and the other will be ignored and a warning generated.

This behaviour can be an issue if you are :ref:`project-sharing` - there may be
bookmarks or models in a library project that you want to change without changing the library itself.  For example, you may want to use the model definition from the library, but replace parameter defaults.

To support this, RiskScape has an `on-conflict` directive that can be added to INI file sections.

.. note::

  Each ``on-conflict`` mode can only be used once for any given INI section key.
  If an ``on-conflict`` mode is re-used for the same INI section, then the section will be
  ignored.

.. note::

  ``on-conflict`` is ignored when set on a ``project`` section - all project sections
  are always read and processed.

#### Defaults

You use `defaults` to mark an INI section as containing default values that another section
can optionally extend. This is intended to be used in shared or library projects that other projects import.

```ini
[parameter exposure_layer]
on-conflict = defaults
properties = bookmark
description = This is a geospatial input layer containing the elements-at-risk that you want to model.
```

#### Extends

`extends` allows your INI section to inherit values from a `defaults` section, overriding
individual keys as needed.

.. note::

  ``extends`` is the default ``on-conflict`` mode.

Given the `defaults` section above in a parent project, you can add:

```ini
[parameter exposure_layer]
on-conflict = extends # this is not necessary because extends is the default conflict mode
default = Buildings
choices = Buildings, Roads, Population
```

Your parameter would then get the `properties` and `description` from the `defaults` section,
and the `default` and `choices` from the `extends` section.

#### Replaces

`replaces` allows you to completely replace another INI file section, regardless of the order
the sections are encountered. This is useful when you are :ref:`project-sharing` and want to
substitute your own definition for part of an imported project, discarding its values entirely.

If we were to add the following parameter to our examples above:

```ini
[parameter exposure_layer]
on-conflict = replaces
default = Rail
```

Then the `choices` and `description` would be removed and only the `default` would be
set.

### Unsupported INI features

RiskScape's INI parser does not support:

- Using `:` as a key/value separator, e.g. `type: text` - this needs to be separated with an equals sign, e.g. `type = text`
- Space separated key/value, e.g. `type text` - this also needs to be separated with an equals sign, e.g. `type = text`

If you have used this format with your project files in the past, due to changes in RiskScape's INI
parser, you may now get an error that looks something like:

```
Problems found with --project
  - Problems found with 'file:/Projects/getting-started/project.ini' config
    - Unexpected character 'd' at line 4, column 1
```

If you get an error like this after upgrading RiskScape, you may be using a no longer supported
key/value format.  You will need to update your project files to use `=` as a separator (as above).
