Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

XP-456: replace CLI argument with a config file #221

Merged
merged 1 commit into from
Jan 28, 2020

Conversation

little-dude
Copy link
Contributor

@little-dude little-dude commented Jan 16, 2020

Summary

replace the CLI arguments with a config file

Reference:

https://xainag.atlassian.net/browse/XP-456
https://xainag.atlassian.net/browse/XP-512

Rationale

The CLI is getting complex so it is worth loading the configuration
from a file instead.

Implementation details

TOML

We decided to use TOML for the following reasons:

  • it is human friendly, ie easy to read and write
  • our configuration has a pretty flat structure which makes TOML
    quite adapted
  • it is well specified and has lots of implementation
  • it is well known

The other options we considered:

  • INI: it is quite frequent in the Python ecosystem to use INI for
    config files, and the standard library even provides support for
    this. However, INI is not as powerful as TOML and does not have a
    specification
  • JSON: it is very popular but is not human friendly. For instance,
    it does not support comments, is very verbose, and breaks
    easily (if a trailing comma is forgotten at the end of a list for
    instance)
  • YAML: another popular choice, but is in my opinion more complex
    than TOML.

Validation

We use the third-party schema library to validate the
configuration. It provides a convenient way to:

  • declare a schema to validate our config
  • leverage third-party libraries to validate some inputs (we use the
    idna library to validate hostnames)
  • define our own validators
  • transform data after it has been validated: this can be useful to
    turn a relative path into an absolute one for example
  • provide user friendly error message when the configuration is
    invalid

The Config class

By default, the schema library returns a dictionary containing a
valid configuration, but that is not convenient to manipulate in
Python. Therefore, we dynamically create a Config class from the
configuration schema, and instantiate a Config object from the data
returned by the schema validator.

Package re-organization

We moved the command line and config file logic into its own config
sub-package, and moved the former xain_fl.cli.main entrypoint into
the xain_fl.__main__ module.

Docker infrastructure

  • Cache the xain_fl dependencies. This considerably reduces
    "edit->build-> debug" cycle, since installing the dependencies takes
    about 30 minutes.
  • Move all the docker related files into the docker/ directory

Limitations and future work

  1. The documentation generated for the ServerConfig,
    AiConfig and StorageConfig classes is wrong. Each attribute is
    documented as "Alias for field number X". This can be fixed by
    having create_class_from_schema() setting the __doc__ attribute
    for each attribute. However, we won't be able to automatically
    document the type of each attribute.

  2. When the configuration contains an invalid value, the error message
    we generate does not contain the invalid value in question. I think
    it is possible to enable this in the future but haven't really
    looked into it.


Reviewer checklist

Reviewer agreement:

  • Reviewers assign themselves at the start of the review.
  • Reviewers do not commit or merge the merge request.
  • Reviewers have to check and mark items in the checklist.

Merge request checklist

  • Conforms to the merge request title naming XP-XXX <a description in imperative form>.
  • Each commit conforms to the naming convention XP-XXX <a description in imperative form>.
  • Linked the ticket in the merge request title or the references section.
  • Added an informative merge request summary.

Code checklist

  • Conforms to the branch naming XP-XXX-<a_small_stub>.
  • Passed scope checks.
  • Added or updated tests if needed.
  • Added or updated code documentation if needed.
  • Conforms to Google docstring style.
  • Conforms to XAIN structlog style.

@little-dude little-dude force-pushed the XP-456-config-file branch 7 times, most recently from 202bd14 to f4439b6 Compare January 20, 2020 15:37
@little-dude little-dude changed the title [WIP] XP-456: replace CLI argument with a config file XP-456: replace CLI argument with a config file Jan 20, 2020
Copy link
Contributor

@Robert-Steiner Robert-Steiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me so far. I will tests it tomorrow.

xain_fl/config/schema.py Outdated Show resolved Hide resolved
xain_fl/config/schema.py Outdated Show resolved Hide resolved
docker/dev/Dockerfile Outdated Show resolved Hide resolved
@dkravetz

This comment has been minimized.

Copy link
Contributor

@atymoshchuk atymoshchuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create follow-up tickets to make changes to docker files and any other changes. Would be great to have only changes about configuration in this pr and everything else in other dedicated prs. Also it’s good for history of tickets and changes introduced to keep the scope according to DoD of linked jira ticket.

Dockerfile.dev Outdated Show resolved Hide resolved
Dockerfile.dev Outdated Show resolved Hide resolved
docker/dev/Dockerfile Outdated Show resolved Hide resolved
docker/dev/docker-compose.yml Outdated Show resolved Hide resolved
xain_fl/config/schema.py Outdated Show resolved Hide resolved
@little-dude little-dude force-pushed the XP-456-config-file branch 3 times, most recently from f77ee94 to 6a90382 Compare January 21, 2020 08:23
@rsaffi

This comment has been minimized.

@little-dude

This comment has been minimized.

@little-dude

This comment has been minimized.

xain_fl/config/schema.py Outdated Show resolved Hide resolved
@little-dude
Copy link
Contributor Author

Thanks for the review @finiteprods, I applied the changes you suggested.

Robert-Steiner
Robert-Steiner previously approved these changes Jan 22, 2020
.gitignore Outdated Show resolved Hide resolved
Dockerfile.dev Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
docker/dev/xain-fl.toml Outdated Show resolved Hide resolved
docker/dev/xain-fl.toml Outdated Show resolved Hide resolved
xain_fl/__main__.py Outdated Show resolved Hide resolved
description (str): description of the expected type of value
for this configuration item
"""
return f"Invalid `{key}`: value must be {description}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update this function after updating structlog message.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atymoshchuk sorry, I'm not sure what you mean here.

xain_fl/config/schema.py Outdated Show resolved Hide resolved
xain_fl/config/schema.py Outdated Show resolved Hide resolved
xain_fl/config/schema.py Outdated Show resolved Hide resolved
@little-dude
Copy link
Contributor Author

This conflicts with #237 but I'll rebase after the final review.

atymoshchuk
atymoshchuk previously approved these changes Jan 28, 2020
docker-compose-dev.yml Outdated Show resolved Hide resolved
Cc: finiteprods <kwok.doc@gmail.com>
Cc: Robert Steiner <robertt.debug@gmail.com>
Cc: janpetschexain <58227040+janpetschexain@users.noreply.github.com>

References
==========

https://xainag.atlassian.net/browse/XP-456
https://xainag.atlassian.net/browse/DO-58

Rationale
=========

The CLI is getting complex so it is worth loading the configuration
from a file instead.

Implementation details
======================

TOML
----

We decided to use TOML for the following reasons:

  - it is human friendly, ie easy to read and write
  - our configuration has a pretty flat structure which makes TOML
    quite adapted
  - it is well specified and has lots of implementation
  - it is well known

The other options we considered:

  - INI: it is quite frequent in the Python ecosystem to use INI for
    config files, and the standard library even provides support for
    this. However, INI is not as powerful as TOML and does not have a
    specification
  - JSON: it is very popular but is not human friendly. For instance,
    it does not support comments, is very verbose, and breaks
    easily (if a trailing comma is forgotten at the end of a list for
    instance)
  - YAML: another popular choice, but is in my opinion more complex
    than TOML.

Validation
----------

We use the third-party `schema` library to validate the
configuration. It provides a convenient way to:

- declare a schema to validate our config
- leverage third-party libraries to validate some inputs (we use the
  `idna` library to validate hostnames)
- define our own validators
- transform data after it has been validated: this can be useful to
  turn a relative path into an absolute one for example
- provide user friendly error message when the configuration is
  invalid

The `Config` class
------------------

By default, the `schema` library returns a dictionary containing a
valid configuration, but that is not convenient to manipulate in
Python. Therefore, we dynamically create a `Config` class from the
configuration schema, and instantiate a `Config` object from the data
returned by the `schema` validator.

Package re-organization
-----------------------

We moved the command line and config file logic into its own `config`
sub-package, and moved the former `xain_fl.cli.main` entrypoint into
the `xain_fl.__main__` module.

Docker infrastructure
---------------------

- Cache the xain_fl dependencies. This considerably reduces
  "edit->build-> debug" cycle, since installing the dependencies takes
  about 30 minutes.
- Move all the docker related files into the `docker/` directory

Current limitations and future work
-----------------------------------

1. The documentation generated for the `ServerConfig`,
   `AiConfig` and `StorageConfig`  classes is wrong. Each attribute is
   documented as "Alias for field number X". This can be fixed by
   having `create_class_from_schema()` setting the `__doc__` attribute
   for each attribute. However, we won't be able to automatically
   document the type of each attribute.

2. When the configuration contains an invalid value, the error message
   we generate does not contain the invalid value in question. I think
   it is possible to enable this in the future but haven't really
   looked into it.
@little-dude little-dude merged commit 8b9f74c into xaynetwork:development Jan 28, 2020
@little-dude little-dude deleted the XP-456-config-file branch January 28, 2020 11:56
little-dude added a commit to little-dude/xain-fl that referenced this pull request Jan 28, 2020
Summary: fix `coordinator` command in the docker "release" image.

References:

xaynetwork#221
https://xainag.atlassian.net/browse/XP-456
little-dude added a commit that referenced this pull request Jan 29, 2020
Summary: fix `coordinator` command in the docker "release" image.

References:

#221
https://xainag.atlassian.net/browse/XP-456
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants