We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Enable E2E tests automation on Travis CI
## Current Behavior

We've got E2E tests but they can only be run on a local setup.

## Expected Behavior

E2E tests should run after each commit merge to master and on schedule (eg. each day at midnight).

## Tasks to do

- [ ] Prepare separate Docker-Compose configuration for E2E Tests
- [ ] Automate setup and tests in similar fashion that it is currently done in Backend functional tests
- [ ] Add E2E Tests to Travis CI configuration
- [ ] Update documentation for testing


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `backend/scripts/sync_configuration.py`
Content:
```
1 """Script for MedTagger's configuration synchronization."""
2 import logging.config
3 from typing import Dict
4 
5 import yaml
6 from sqlalchemy.exc import IntegrityError
7 
8 from medtagger.database.models import Task
9 from medtagger.definitions import LabelTool
10 from medtagger.repositories import (
11     datasets as DatasetsRepository,
12     tasks as TasksRepository,
13     label_tags as LabelTagsRepository,
14 )
15 from medtagger.types import TaskID
16 
17 logging.config.fileConfig('logging.conf')
18 logger = logging.getLogger(__name__)
19 
20 CONFIGURATION_FILE_NAME = '.medtagger.yml'
21 
22 
23 def sync_configuration(configuration: Dict) -> None:
24     """Synchronize configuration file with database entries.
25 
26     :param configuration: content of YAML configuration file
27     """
28     logger.info('Running Configuration Synchronization...')
29     _sync_datasets(configuration)
30     _sync_tasks(configuration)
31 
32 
33 def _sync_datasets(configuration: Dict) -> None:
34     """Synchronize Datasets from configuration file with database entries.
35 
36     Example DataSets in the configuration file:
37     ```
38     datasets:
39       - name: Kidneys
40         key: KIDNEYS
41         tasks:
42           - KIDNEYS_SEGMENTATION
43     ```
44 
45     :param configuration: content of YAML configuration file
46     """
47     datasets = configuration.get('datasets', []) or []
48     configuration_datasets_keys = {dataset['key'] for dataset in datasets}
49     database_datasets_keys = {dataset.key for dataset in DatasetsRepository.get_all_datasets(include_disabled=True)}
50 
51     datasets_to_add = configuration_datasets_keys - database_datasets_keys
52     datasets_to_disable = database_datasets_keys - configuration_datasets_keys
53     datasets_to_enable = database_datasets_keys & configuration_datasets_keys
54 
55     for dataset_key in datasets_to_add:
56         dataset = next(dataset for dataset in datasets if dataset['key'] == dataset_key)
57         DatasetsRepository.add_new_dataset(dataset['key'], dataset['name'])
58         logger.info('New DataSet added: %s', dataset['key'])
59 
60     for dataset_key in datasets_to_enable:
61         dataset = next(dataset for dataset in datasets if dataset['key'] == dataset_key)
62         DatasetsRepository.enable(dataset['key'])
63         DatasetsRepository.update(dataset['key'], dataset['name'])
64         logger.info('DataSet enabled: %s', dataset['key'])
65 
66     for dataset_key in datasets_to_disable:
67         DatasetsRepository.disable(dataset_key)
68         logger.info('DataSet disabled: %s', dataset_key)
69 
70 
71 def _sync_tasks(configuration: Dict) -> None:
72     """Synchronize Tasks from configuration file with database entries.
73 
74     Example Tasks in the configuration file:
75     ```
76     tasks:
77       - key: KIDNEYS_SEGMENTATION
78         name: Kidneys segmentation
79         image_path: assets/icon/kidneys_dataset_icon.svg
80         tags:
81           - key: LEFT_KIDNEY
82             name: Left Kidney
83             tools:
84               - CHAIN
85           - key: RIGHT_KIDNEY
86             name: Right Kidney
87             tools:
88               - CHAIN
89     ```
90 
91     :param configuration: content of YAML configuration file
92     """
93     datasets = configuration.get('datasets', []) or []
94     tasks = configuration.get('tasks', []) or []
95     configuration_tasks_keys = {task['key'] for task in tasks}
96     database_tasks_keys = {task.key for task in Task.query.all()}
97 
98     tasks_to_add = configuration_tasks_keys - database_tasks_keys
99     tasks_to_disable = database_tasks_keys - configuration_tasks_keys
100     tasks_to_enable = database_tasks_keys & configuration_tasks_keys
101 
102     # Add all new Tasks that haven't ever been in the DB
103     for task_key in tasks_to_add:
104         task = next(task for task in tasks if task['key'] == task_key)
105         datasets_keys = [dataset['key'] for dataset in datasets if task['key'] in dataset['tasks']]
106         TasksRepository.add_task(task['key'], task['name'], task['image_path'], datasets_keys, [])
107         _sync_label_tags_in_task(configuration, task_key)
108         logger.info('New Task added: %s', task['key'])
109 
110     # Enable back all Tasks that were previously commented-out or removed from configuration file
111     for task_key in tasks_to_enable:
112         TasksRepository.enable(task_key)
113         _sync_label_tags_in_task(configuration, task_key)
114         task = next(task for task in tasks if task['key'] == task_key)
115         datasets_keys = [dataset['key'] for dataset in datasets if task['key'] in dataset['tasks']]
116         TasksRepository.update(task_key, task['name'], task['image_path'], datasets_keys)
117         logger.info('Task enabled: %s', task_key)
118 
119     # Disable all Tasks that exists in the DB but are missing in configuration file
120     for task_key in tasks_to_disable:
121         TasksRepository.disable(task_key)
122         task = TasksRepository.get_task_by_key(task_key)
123         for tag in task.available_tags:
124             LabelTagsRepository.disable(tag.key)
125             logger.info('LabelTag disabled: %s', tag.key)
126         logger.info('Task disabled: %s', task_key)
127 
128 
129 def _sync_label_tags_in_task(configuration: Dict, task_key: str) -> None:
130     """Synchronize Label Tags in given Task based on configuration file and database entries.
131 
132     :param configuration: content of YAML configuration file
133     :param task_key: key for the Task that should be synchronized
134     """
135     db_task = TasksRepository.get_task_by_key(task_key)
136     configuration_task = next(task for task in configuration['tasks'] if task['key'] == task_key)
137     configuration_tags_keys = {tag['key'] for tag in configuration_task['tags']}
138     database_tags_keys = {tag.key for tag in db_task.available_tags}
139 
140     tags_to_add = configuration_tags_keys - database_tags_keys
141     tags_to_disable = database_tags_keys - configuration_tags_keys
142     tags_to_enable = database_tags_keys & configuration_tags_keys
143 
144     for tag_key in tags_to_add:
145         tag = next(tag for tag in configuration_task['tags'] if tag_key == tag['key'])
146         _add_label_tag(tag, db_task.id)
147         logger.info('New LabelTag added: %s', tag_key)
148 
149     for tag_key in tags_to_disable:
150         LabelTagsRepository.disable(tag_key)
151         logger.info('LabelTag disabled: %s', tag_key)
152 
153     for tag_key in tags_to_enable:
154         tag = next(tag for tag in configuration_task['tags'] if tag_key == tag['key'])
155         tools = [LabelTool[tool] for tool in tag['tools']]
156         LabelTagsRepository.enable(tag_key)
157         LabelTagsRepository.update(tag_key, tag['name'], tools)
158         logger.info('LabelTag enabled: %s', tag_key)
159 
160 
161 def _add_label_tag(tag: Dict, db_task_id: TaskID) -> None:
162     """Add Label Tag or reuse previously created one.
163 
164     :param tag: configuration of a Label Tag
165     :param db_task_id: TaskID which should be connected with this Label Tag
166     """
167     tools = [LabelTool[tool] for tool in tag['tools']]
168     try:
169         LabelTagsRepository.add_new_tag(tag['key'], tag['name'], tools, db_task_id)
170     except IntegrityError:
171         # Such Label Tag could be previously used in another Task
172         logger.warning('Reusing previously existing Label Tag (%s)! This may cause data inconsistency! '
173                        'Make sure you know what you are doing and clear database entries if necessary!',
174                        tag['key'])
175         LabelTagsRepository.update(tag['key'], tag['name'], tools, db_task_id)
176         LabelTagsRepository.enable(tag['key'])
177 
178 
179 def run() -> None:
180     """Entry point for this script."""
181     try:
182         with open(CONFIGURATION_FILE_NAME) as config_file:
183             configuration = yaml.load(config_file)
184             sync_configuration(configuration)
185     except yaml.YAMLError:
186         logger.exception('Invalid MedTagger configuration file format.')
187 
188 
189 if __name__ == '__main__':
190     run()
191
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/backend/scripts/sync_configuration.py b/backend/scripts/sync_configuration.py
--- a/backend/scripts/sync_configuration.py
+++ b/backend/scripts/sync_configuration.py
@@ -1,4 +1,5 @@
 """Script for MedTagger's configuration synchronization."""
+import argparse
 import logging.config
 from typing import Dict
 
@@ -17,7 +18,7 @@
 logging.config.fileConfig('logging.conf')
 logger = logging.getLogger(__name__)
 
-CONFIGURATION_FILE_NAME = '.medtagger.yml'
+DEFAULT_CONFIGURATION_FILE_NAME = '.medtagger.yml'
 
 
 def sync_configuration(configuration: Dict) -> None:
@@ -178,8 +179,12 @@
 
 def run() -> None:
     """Entry point for this script."""
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--configuration', type=str, default=DEFAULT_CONFIGURATION_FILE_NAME)
+    arguments = parser.parse_args()
+
     try:
-        with open(CONFIGURATION_FILE_NAME) as config_file:
+        with open(arguments.configuration) as config_file:
             configuration = yaml.load(config_file)
             sync_configuration(configuration)
     except yaml.YAMLError:

{"golden_diff": "diff --git a/backend/scripts/sync_configuration.py b/backend/scripts/sync_configuration.py\n--- a/backend/scripts/sync_configuration.py\n+++ b/backend/scripts/sync_configuration.py\n@@ -1,4 +1,5 @@\n \"\"\"Script for MedTagger's configuration synchronization.\"\"\"\n+import argparse\n import logging.config\n from typing import Dict\n \n@@ -17,7 +18,7 @@\n logging.config.fileConfig('logging.conf')\n logger = logging.getLogger(__name__)\n \n-CONFIGURATION_FILE_NAME = '.medtagger.yml'\n+DEFAULT_CONFIGURATION_FILE_NAME = '.medtagger.yml'\n \n \n def sync_configuration(configuration: Dict) -> None:\n@@ -178,8 +179,12 @@\n \n def run() -> None:\n     \"\"\"Entry point for this script.\"\"\"\n+    parser = argparse.ArgumentParser()\n+    parser.add_argument('--configuration', type=str, default=DEFAULT_CONFIGURATION_FILE_NAME)\n+    arguments = parser.parse_args()\n+\n     try:\n-        with open(CONFIGURATION_FILE_NAME) as config_file:\n+        with open(arguments.configuration) as config_file:\n             configuration = yaml.load(config_file)\n             sync_configuration(configuration)\n     except yaml.YAMLError:\n", "issue": "Enable E2E tests automation on Travis CI\n## Current Behavior\r\n\r\nWe've got E2E tests but they can only be run on a local setup.\r\n\r\n## Expected Behavior\r\n\r\nE2E tests should run after each commit merge to master and on schedule (eg. each day at midnight).\r\n\r\n## Tasks to do\r\n\r\n- [ ] Prepare separate Docker-Compose configuration for E2E Tests\r\n- [ ] Automate setup and tests in similar fashion that it is currently done in Backend functional tests\r\n- [ ] Add E2E Tests to Travis CI configuration\r\n- [ ] Update documentation for testing\r\n\n", "before_files": [{"content": "\"\"\"Script for MedTagger's configuration synchronization.\"\"\"\nimport logging.config\nfrom typing import Dict\n\nimport yaml\nfrom sqlalchemy.exc import IntegrityError\n\nfrom medtagger.database.models import Task\nfrom medtagger.definitions import LabelTool\nfrom medtagger.repositories import (\n    datasets as DatasetsRepository,\n    tasks as TasksRepository,\n    label_tags as LabelTagsRepository,\n)\nfrom medtagger.types import TaskID\n\nlogging.config.fileConfig('logging.conf')\nlogger = logging.getLogger(__name__)\n\nCONFIGURATION_FILE_NAME = '.medtagger.yml'\n\n\ndef sync_configuration(configuration: Dict) -> None:\n    \"\"\"Synchronize configuration file with database entries.\n\n    :param configuration: content of YAML configuration file\n    \"\"\"\n    logger.info('Running Configuration Synchronization...')\n    _sync_datasets(configuration)\n    _sync_tasks(configuration)\n\n\ndef _sync_datasets(configuration: Dict) -> None:\n    \"\"\"Synchronize Datasets from configuration file with database entries.\n\n    Example DataSets in the configuration file:\n    ```\n    datasets:\n      - name: Kidneys\n        key: KIDNEYS\n        tasks:\n          - KIDNEYS_SEGMENTATION\n    ```\n\n    :param configuration: content of YAML configuration file\n    \"\"\"\n    datasets = configuration.get('datasets', []) or []\n    configuration_datasets_keys = {dataset['key'] for dataset in datasets}\n    database_datasets_keys = {dataset.key for dataset in DatasetsRepository.get_all_datasets(include_disabled=True)}\n\n    datasets_to_add = configuration_datasets_keys - database_datasets_keys\n    datasets_to_disable = database_datasets_keys - configuration_datasets_keys\n    datasets_to_enable = database_datasets_keys & configuration_datasets_keys\n\n    for dataset_key in datasets_to_add:\n        dataset = next(dataset for dataset in datasets if dataset['key'] == dataset_key)\n        DatasetsRepository.add_new_dataset(dataset['key'], dataset['name'])\n        logger.info('New DataSet added: %s', dataset['key'])\n\n    for dataset_key in datasets_to_enable:\n        dataset = next(dataset for dataset in datasets if dataset['key'] == dataset_key)\n        DatasetsRepository.enable(dataset['key'])\n        DatasetsRepository.update(dataset['key'], dataset['name'])\n        logger.info('DataSet enabled: %s', dataset['key'])\n\n    for dataset_key in datasets_to_disable:\n        DatasetsRepository.disable(dataset_key)\n        logger.info('DataSet disabled: %s', dataset_key)\n\n\ndef _sync_tasks(configuration: Dict) -> None:\n    \"\"\"Synchronize Tasks from configuration file with database entries.\n\n    Example Tasks in the configuration file:\n    ```\n    tasks:\n      - key: KIDNEYS_SEGMENTATION\n        name: Kidneys segmentation\n        image_path: assets/icon/kidneys_dataset_icon.svg\n        tags:\n          - key: LEFT_KIDNEY\n            name: Left Kidney\n            tools:\n              - CHAIN\n          - key: RIGHT_KIDNEY\n            name: Right Kidney\n            tools:\n              - CHAIN\n    ```\n\n    :param configuration: content of YAML configuration file\n    \"\"\"\n    datasets = configuration.get('datasets', []) or []\n    tasks = configuration.get('tasks', []) or []\n    configuration_tasks_keys = {task['key'] for task in tasks}\n    database_tasks_keys = {task.key for task in Task.query.all()}\n\n    tasks_to_add = configuration_tasks_keys - database_tasks_keys\n    tasks_to_disable = database_tasks_keys - configuration_tasks_keys\n    tasks_to_enable = database_tasks_keys & configuration_tasks_keys\n\n    # Add all new Tasks that haven't ever been in the DB\n    for task_key in tasks_to_add:\n        task = next(task for task in tasks if task['key'] == task_key)\n        datasets_keys = [dataset['key'] for dataset in datasets if task['key'] in dataset['tasks']]\n        TasksRepository.add_task(task['key'], task['name'], task['image_path'], datasets_keys, [])\n        _sync_label_tags_in_task(configuration, task_key)\n        logger.info('New Task added: %s', task['key'])\n\n    # Enable back all Tasks that were previously commented-out or removed from configuration file\n    for task_key in tasks_to_enable:\n        TasksRepository.enable(task_key)\n        _sync_label_tags_in_task(configuration, task_key)\n        task = next(task for task in tasks if task['key'] == task_key)\n        datasets_keys = [dataset['key'] for dataset in datasets if task['key'] in dataset['tasks']]\n        TasksRepository.update(task_key, task['name'], task['image_path'], datasets_keys)\n        logger.info('Task enabled: %s', task_key)\n\n    # Disable all Tasks that exists in the DB but are missing in configuration file\n    for task_key in tasks_to_disable:\n        TasksRepository.disable(task_key)\n        task = TasksRepository.get_task_by_key(task_key)\n        for tag in task.available_tags:\n            LabelTagsRepository.disable(tag.key)\n            logger.info('LabelTag disabled: %s', tag.key)\n        logger.info('Task disabled: %s', task_key)\n\n\ndef _sync_label_tags_in_task(configuration: Dict, task_key: str) -> None:\n    \"\"\"Synchronize Label Tags in given Task based on configuration file and database entries.\n\n    :param configuration: content of YAML configuration file\n    :param task_key: key for the Task that should be synchronized\n    \"\"\"\n    db_task = TasksRepository.get_task_by_key(task_key)\n    configuration_task = next(task for task in configuration['tasks'] if task['key'] == task_key)\n    configuration_tags_keys = {tag['key'] for tag in configuration_task['tags']}\n    database_tags_keys = {tag.key for tag in db_task.available_tags}\n\n    tags_to_add = configuration_tags_keys - database_tags_keys\n    tags_to_disable = database_tags_keys - configuration_tags_keys\n    tags_to_enable = database_tags_keys & configuration_tags_keys\n\n    for tag_key in tags_to_add:\n        tag = next(tag for tag in configuration_task['tags'] if tag_key == tag['key'])\n        _add_label_tag(tag, db_task.id)\n        logger.info('New LabelTag added: %s', tag_key)\n\n    for tag_key in tags_to_disable:\n        LabelTagsRepository.disable(tag_key)\n        logger.info('LabelTag disabled: %s', tag_key)\n\n    for tag_key in tags_to_enable:\n        tag = next(tag for tag in configuration_task['tags'] if tag_key == tag['key'])\n        tools = [LabelTool[tool] for tool in tag['tools']]\n        LabelTagsRepository.enable(tag_key)\n        LabelTagsRepository.update(tag_key, tag['name'], tools)\n        logger.info('LabelTag enabled: %s', tag_key)\n\n\ndef _add_label_tag(tag: Dict, db_task_id: TaskID) -> None:\n    \"\"\"Add Label Tag or reuse previously created one.\n\n    :param tag: configuration of a Label Tag\n    :param db_task_id: TaskID which should be connected with this Label Tag\n    \"\"\"\n    tools = [LabelTool[tool] for tool in tag['tools']]\n    try:\n        LabelTagsRepository.add_new_tag(tag['key'], tag['name'], tools, db_task_id)\n    except IntegrityError:\n        # Such Label Tag could be previously used in another Task\n        logger.warning('Reusing previously existing Label Tag (%s)! This may cause data inconsistency! '\n                       'Make sure you know what you are doing and clear database entries if necessary!',\n                       tag['key'])\n        LabelTagsRepository.update(tag['key'], tag['name'], tools, db_task_id)\n        LabelTagsRepository.enable(tag['key'])\n\n\ndef run() -> None:\n    \"\"\"Entry point for this script.\"\"\"\n    try:\n        with open(CONFIGURATION_FILE_NAME) as config_file:\n            configuration = yaml.load(config_file)\n            sync_configuration(configuration)\n    except yaml.YAMLError:\n        logger.exception('Invalid MedTagger configuration file format.')\n\n\nif __name__ == '__main__':\n    run()\n", "path": "backend/scripts/sync_configuration.py"}], "after_files": [{"content": "\"\"\"Script for MedTagger's configuration synchronization.\"\"\"\nimport argparse\nimport logging.config\nfrom typing import Dict\n\nimport yaml\nfrom sqlalchemy.exc import IntegrityError\n\nfrom medtagger.database.models import Task\nfrom medtagger.definitions import LabelTool\nfrom medtagger.repositories import (\n    datasets as DatasetsRepository,\n    tasks as TasksRepository,\n    label_tags as LabelTagsRepository,\n)\nfrom medtagger.types import TaskID\n\nlogging.config.fileConfig('logging.conf')\nlogger = logging.getLogger(__name__)\n\nDEFAULT_CONFIGURATION_FILE_NAME = '.medtagger.yml'\n\n\ndef sync_configuration(configuration: Dict) -> None:\n    \"\"\"Synchronize configuration file with database entries.\n\n    :param configuration: content of YAML configuration file\n    \"\"\"\n    logger.info('Running Configuration Synchronization...')\n    _sync_datasets(configuration)\n    _sync_tasks(configuration)\n\n\ndef _sync_datasets(configuration: Dict) -> None:\n    \"\"\"Synchronize Datasets from configuration file with database entries.\n\n    Example DataSets in the configuration file:\n    ```\n    datasets:\n      - name: Kidneys\n        key: KIDNEYS\n        tasks:\n          - KIDNEYS_SEGMENTATION\n    ```\n\n    :param configuration: content of YAML configuration file\n    \"\"\"\n    datasets = configuration.get('datasets', []) or []\n    configuration_datasets_keys = {dataset['key'] for dataset in datasets}\n    database_datasets_keys = {dataset.key for dataset in DatasetsRepository.get_all_datasets(include_disabled=True)}\n\n    datasets_to_add = configuration_datasets_keys - database_datasets_keys\n    datasets_to_disable = database_datasets_keys - configuration_datasets_keys\n    datasets_to_enable = database_datasets_keys & configuration_datasets_keys\n\n    for dataset_key in datasets_to_add:\n        dataset = next(dataset for dataset in datasets if dataset['key'] == dataset_key)\n        DatasetsRepository.add_new_dataset(dataset['key'], dataset['name'])\n        logger.info('New DataSet added: %s', dataset['key'])\n\n    for dataset_key in datasets_to_enable:\n        dataset = next(dataset for dataset in datasets if dataset['key'] == dataset_key)\n        DatasetsRepository.enable(dataset['key'])\n        DatasetsRepository.update(dataset['key'], dataset['name'])\n        logger.info('DataSet enabled: %s', dataset['key'])\n\n    for dataset_key in datasets_to_disable:\n        DatasetsRepository.disable(dataset_key)\n        logger.info('DataSet disabled: %s', dataset_key)\n\n\ndef _sync_tasks(configuration: Dict) -> None:\n    \"\"\"Synchronize Tasks from configuration file with database entries.\n\n    Example Tasks in the configuration file:\n    ```\n    tasks:\n      - key: KIDNEYS_SEGMENTATION\n        name: Kidneys segmentation\n        image_path: assets/icon/kidneys_dataset_icon.svg\n        tags:\n          - key: LEFT_KIDNEY\n            name: Left Kidney\n            tools:\n              - CHAIN\n          - key: RIGHT_KIDNEY\n            name: Right Kidney\n            tools:\n              - CHAIN\n    ```\n\n    :param configuration: content of YAML configuration file\n    \"\"\"\n    datasets = configuration.get('datasets', []) or []\n    tasks = configuration.get('tasks', []) or []\n    configuration_tasks_keys = {task['key'] for task in tasks}\n    database_tasks_keys = {task.key for task in Task.query.all()}\n\n    tasks_to_add = configuration_tasks_keys - database_tasks_keys\n    tasks_to_disable = database_tasks_keys - configuration_tasks_keys\n    tasks_to_enable = database_tasks_keys & configuration_tasks_keys\n\n    # Add all new Tasks that haven't ever been in the DB\n    for task_key in tasks_to_add:\n        task = next(task for task in tasks if task['key'] == task_key)\n        datasets_keys = [dataset['key'] for dataset in datasets if task['key'] in dataset['tasks']]\n        TasksRepository.add_task(task['key'], task['name'], task['image_path'], datasets_keys, [])\n        _sync_label_tags_in_task(configuration, task_key)\n        logger.info('New Task added: %s', task['key'])\n\n    # Enable back all Tasks that were previously commented-out or removed from configuration file\n    for task_key in tasks_to_enable:\n        TasksRepository.enable(task_key)\n        _sync_label_tags_in_task(configuration, task_key)\n        task = next(task for task in tasks if task['key'] == task_key)\n        datasets_keys = [dataset['key'] for dataset in datasets if task['key'] in dataset['tasks']]\n        TasksRepository.update(task_key, task['name'], task['image_path'], datasets_keys)\n        logger.info('Task enabled: %s', task_key)\n\n    # Disable all Tasks that exists in the DB but are missing in configuration file\n    for task_key in tasks_to_disable:\n        TasksRepository.disable(task_key)\n        task = TasksRepository.get_task_by_key(task_key)\n        for tag in task.available_tags:\n            LabelTagsRepository.disable(tag.key)\n            logger.info('LabelTag disabled: %s', tag.key)\n        logger.info('Task disabled: %s', task_key)\n\n\ndef _sync_label_tags_in_task(configuration: Dict, task_key: str) -> None:\n    \"\"\"Synchronize Label Tags in given Task based on configuration file and database entries.\n\n    :param configuration: content of YAML configuration file\n    :param task_key: key for the Task that should be synchronized\n    \"\"\"\n    db_task = TasksRepository.get_task_by_key(task_key)\n    configuration_task = next(task for task in configuration['tasks'] if task['key'] == task_key)\n    configuration_tags_keys = {tag['key'] for tag in configuration_task['tags']}\n    database_tags_keys = {tag.key for tag in db_task.available_tags}\n\n    tags_to_add = configuration_tags_keys - database_tags_keys\n    tags_to_disable = database_tags_keys - configuration_tags_keys\n    tags_to_enable = database_tags_keys & configuration_tags_keys\n\n    for tag_key in tags_to_add:\n        tag = next(tag for tag in configuration_task['tags'] if tag_key == tag['key'])\n        _add_label_tag(tag, db_task.id)\n        logger.info('New LabelTag added: %s', tag_key)\n\n    for tag_key in tags_to_disable:\n        LabelTagsRepository.disable(tag_key)\n        logger.info('LabelTag disabled: %s', tag_key)\n\n    for tag_key in tags_to_enable:\n        tag = next(tag for tag in configuration_task['tags'] if tag_key == tag['key'])\n        tools = [LabelTool[tool] for tool in tag['tools']]\n        LabelTagsRepository.enable(tag_key)\n        LabelTagsRepository.update(tag_key, tag['name'], tools)\n        logger.info('LabelTag enabled: %s', tag_key)\n\n\ndef _add_label_tag(tag: Dict, db_task_id: TaskID) -> None:\n    \"\"\"Add Label Tag or reuse previously created one.\n\n    :param tag: configuration of a Label Tag\n    :param db_task_id: TaskID which should be connected with this Label Tag\n    \"\"\"\n    tools = [LabelTool[tool] for tool in tag['tools']]\n    try:\n        LabelTagsRepository.add_new_tag(tag['key'], tag['name'], tools, db_task_id)\n    except IntegrityError:\n        # Such Label Tag could be previously used in another Task\n        logger.warning('Reusing previously existing Label Tag (%s)! This may cause data inconsistency! '\n                       'Make sure you know what you are doing and clear database entries if necessary!',\n                       tag['key'])\n        LabelTagsRepository.update(tag['key'], tag['name'], tools, db_task_id)\n        LabelTagsRepository.enable(tag['key'])\n\n\ndef run() -> None:\n    \"\"\"Entry point for this script.\"\"\"\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--configuration', type=str, default=DEFAULT_CONFIGURATION_FILE_NAME)\n    arguments = parser.parse_args()\n\n    try:\n        with open(arguments.configuration) as config_file:\n            configuration = yaml.load(config_file)\n            sync_configuration(configuration)\n    except yaml.YAMLError:\n        logger.exception('Invalid MedTagger configuration file format.')\n\n\nif __name__ == '__main__':\n    run()\n", "path": "backend/scripts/sync_configuration.py"}]}