We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Make ROOT_PATH, MODELS_PATH and DOWNLOADS_PATH environment variables
All config files I've seen so far have the following variables:
```
"ROOT_PATH": "~/.deeppavlov",
"DOWNLOADS_PATH": "{ROOT_PATH}/downloads",
"MODELS_PATH": "{ROOT_PATH}/models"
```
Should we make them environment variables?
This would be better for the following reasons:
1. No need to define the same variables across all configs
1. No need to redefine variables for your system. For example, I do not store source code and downloads/models at same place (cause of their huge size), so I need to change configs for me and change them _back_ to make PR (that is kind of ridiculous). If these variables were in the environment, I'd have to change them only one time - after deeppavlov installation.
1. Make configs working directory independent (no '~/'-paths)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `deeppavlov/core/commands/utils.py`
Content:
```
1 # Copyright 2017 Neural Networks and Deep Learning lab, MIPT
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 from pathlib import Path
15 from typing import Union, Dict, TypeVar
16 
17 from deeppavlov.core.common.file import read_json, find_config
18 
19 # noinspection PyShadowingBuiltins
20 _T = TypeVar('_T', str, float, bool, list, dict)
21 
22 
23 def _parse_config_property(item: _T, variables: Dict[str, Union[str, Path, float, bool, None]]) -> _T:
24     """Recursively apply config's variables values to its property"""
25     if isinstance(item, str):
26         return item.format(**variables)
27     elif isinstance(item, list):
28         return [_parse_config_property(item, variables) for item in item]
29     elif isinstance(item, dict):
30         return {k: _parse_config_property(v, variables) for k, v in item.items()}
31     else:
32         return item
33 
34 
35 def parse_config(config: Union[str, Path, dict]) -> dict:
36     """Read config's variables and apply their values to all its properties"""
37     if isinstance(config, (str, Path)):
38         config = read_json(find_config(config))
39 
40     variables = {
41         'DEEPPAVLOV_PATH': Path(__file__).parent.parent.parent
42     }
43     for name, value in config.get('metadata', {}).get('variables', {}).items():
44         variables[name] = value.format(**variables)
45 
46     return _parse_config_property(config, variables)
47 
48 
49 def expand_path(path: Union[str, Path]) -> Path:
50     """Convert relative paths to absolute with resolving user directory."""
51     return Path(path).expanduser().resolve()
52 
53 
54 def import_packages(packages: list) -> None:
55     """Import packages from list to execute their code."""
56     for package in packages:
57         __import__(package)
58
```
--- 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/deeppavlov/core/commands/utils.py b/deeppavlov/core/commands/utils.py
--- a/deeppavlov/core/commands/utils.py
+++ b/deeppavlov/core/commands/utils.py
@@ -11,6 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+import os
 from pathlib import Path
 from typing import Union, Dict, TypeVar
 
@@ -38,9 +39,12 @@
         config = read_json(find_config(config))
 
     variables = {
-        'DEEPPAVLOV_PATH': Path(__file__).parent.parent.parent
+        'DEEPPAVLOV_PATH': os.getenv(f'DP_DEEPPAVLOV_PATH', Path(__file__).parent.parent.parent)
     }
     for name, value in config.get('metadata', {}).get('variables', {}).items():
+        env_name = f'DP_{name}'
+        if env_name in os.environ:
+            value = os.getenv(env_name)
         variables[name] = value.format(**variables)
 
     return _parse_config_property(config, variables)

{"golden_diff": "diff --git a/deeppavlov/core/commands/utils.py b/deeppavlov/core/commands/utils.py\n--- a/deeppavlov/core/commands/utils.py\n+++ b/deeppavlov/core/commands/utils.py\n@@ -11,6 +11,7 @@\n # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n # See the License for the specific language governing permissions and\n # limitations under the License.\n+import os\n from pathlib import Path\n from typing import Union, Dict, TypeVar\n \n@@ -38,9 +39,12 @@\n         config = read_json(find_config(config))\n \n     variables = {\n-        'DEEPPAVLOV_PATH': Path(__file__).parent.parent.parent\n+        'DEEPPAVLOV_PATH': os.getenv(f'DP_DEEPPAVLOV_PATH', Path(__file__).parent.parent.parent)\n     }\n     for name, value in config.get('metadata', {}).get('variables', {}).items():\n+        env_name = f'DP_{name}'\n+        if env_name in os.environ:\n+            value = os.getenv(env_name)\n         variables[name] = value.format(**variables)\n \n     return _parse_config_property(config, variables)\n", "issue": "Make ROOT_PATH, MODELS_PATH and DOWNLOADS_PATH environment variables\nAll config files I've seen so far have the following variables:\r\n```\r\n\"ROOT_PATH\": \"~/.deeppavlov\",\r\n\"DOWNLOADS_PATH\": \"{ROOT_PATH}/downloads\",\r\n\"MODELS_PATH\": \"{ROOT_PATH}/models\"\r\n```\r\nShould we make them environment variables?\r\nThis would be better for the following reasons:\r\n1. No need to define the same variables across all configs\r\n1. No need to redefine variables for your system. For example, I do not store source code and downloads/models at same place (cause of their huge size), so I need to change configs for me and change them _back_ to make PR (that is kind of ridiculous). If these variables were in the environment, I'd have to change them only one time - after deeppavlov installation.\r\n1. Make configs working directory independent (no '~/'-paths)\n", "before_files": [{"content": "# Copyright 2017 Neural Networks and Deep Learning lab, MIPT\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nfrom pathlib import Path\nfrom typing import Union, Dict, TypeVar\n\nfrom deeppavlov.core.common.file import read_json, find_config\n\n# noinspection PyShadowingBuiltins\n_T = TypeVar('_T', str, float, bool, list, dict)\n\n\ndef _parse_config_property(item: _T, variables: Dict[str, Union[str, Path, float, bool, None]]) -> _T:\n    \"\"\"Recursively apply config's variables values to its property\"\"\"\n    if isinstance(item, str):\n        return item.format(**variables)\n    elif isinstance(item, list):\n        return [_parse_config_property(item, variables) for item in item]\n    elif isinstance(item, dict):\n        return {k: _parse_config_property(v, variables) for k, v in item.items()}\n    else:\n        return item\n\n\ndef parse_config(config: Union[str, Path, dict]) -> dict:\n    \"\"\"Read config's variables and apply their values to all its properties\"\"\"\n    if isinstance(config, (str, Path)):\n        config = read_json(find_config(config))\n\n    variables = {\n        'DEEPPAVLOV_PATH': Path(__file__).parent.parent.parent\n    }\n    for name, value in config.get('metadata', {}).get('variables', {}).items():\n        variables[name] = value.format(**variables)\n\n    return _parse_config_property(config, variables)\n\n\ndef expand_path(path: Union[str, Path]) -> Path:\n    \"\"\"Convert relative paths to absolute with resolving user directory.\"\"\"\n    return Path(path).expanduser().resolve()\n\n\ndef import_packages(packages: list) -> None:\n    \"\"\"Import packages from list to execute their code.\"\"\"\n    for package in packages:\n        __import__(package)\n", "path": "deeppavlov/core/commands/utils.py"}], "after_files": [{"content": "# Copyright 2017 Neural Networks and Deep Learning lab, MIPT\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\nimport os\nfrom pathlib import Path\nfrom typing import Union, Dict, TypeVar\n\nfrom deeppavlov.core.common.file import read_json, find_config\n\n# noinspection PyShadowingBuiltins\n_T = TypeVar('_T', str, float, bool, list, dict)\n\n\ndef _parse_config_property(item: _T, variables: Dict[str, Union[str, Path, float, bool, None]]) -> _T:\n    \"\"\"Recursively apply config's variables values to its property\"\"\"\n    if isinstance(item, str):\n        return item.format(**variables)\n    elif isinstance(item, list):\n        return [_parse_config_property(item, variables) for item in item]\n    elif isinstance(item, dict):\n        return {k: _parse_config_property(v, variables) for k, v in item.items()}\n    else:\n        return item\n\n\ndef parse_config(config: Union[str, Path, dict]) -> dict:\n    \"\"\"Read config's variables and apply their values to all its properties\"\"\"\n    if isinstance(config, (str, Path)):\n        config = read_json(find_config(config))\n\n    variables = {\n        'DEEPPAVLOV_PATH': os.getenv(f'DP_DEEPPAVLOV_PATH', Path(__file__).parent.parent.parent)\n    }\n    for name, value in config.get('metadata', {}).get('variables', {}).items():\n        env_name = f'DP_{name}'\n        if env_name in os.environ:\n            value = os.getenv(env_name)\n        variables[name] = value.format(**variables)\n\n    return _parse_config_property(config, variables)\n\n\ndef expand_path(path: Union[str, Path]) -> Path:\n    \"\"\"Convert relative paths to absolute with resolving user directory.\"\"\"\n    return Path(path).expanduser().resolve()\n\n\ndef import_packages(packages: list) -> None:\n    \"\"\"Import packages from list to execute their code.\"\"\"\n    for package in packages:\n        __import__(package)\n", "path": "deeppavlov/core/commands/utils.py"}]}