We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Remove/change log level for "Credentials not found in your Kedro project config"
## Description
When getting the credentials in the KedroContext, we specifically look for the `credentials` file. If a project doesn't make use of this file a warning log will be thrown saying "Credentials not found in your Kedro project config". Not all users use the credentials file and so this warning isn't applicable. 

## Context
We're adding functionality to allow users to have credentials in environment variables (which is currently also possible with the `TemplatedConfigLoader`), which makes this error irrelevant. 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `kedro/framework/context/context.py`
Content:
```
1 """This module provides context for Kedro project."""
2 
3 from copy import deepcopy
4 from pathlib import Path, PurePosixPath, PureWindowsPath
5 from typing import Any, Dict, Optional, Union
6 from urllib.parse import urlparse
7 from warnings import warn
8 
9 from pluggy import PluginManager
10 
11 from kedro.config import ConfigLoader, MissingConfigException
12 from kedro.framework.project import settings
13 from kedro.io import DataCatalog
14 from kedro.pipeline.pipeline import _transcode_split
15 
16 
17 def _is_relative_path(path_string: str) -> bool:
18     """Checks whether a path string is a relative path.
19 
20     Example:
21     ::
22         >>> _is_relative_path("data/01_raw") == True
23         >>> _is_relative_path("logs/info.log") == True
24         >>> _is_relative_path("/tmp/data/01_raw") == False
25         >>> _is_relative_path(r"C:\\logs\\info.log") == False
26         >>> _is_relative_path(r"\\logs\\'info.log") == False
27         >>> _is_relative_path("c:/logs/info.log") == False
28         >>> _is_relative_path("s3://logs/info.log") == False
29 
30     Args:
31         path_string: The path string to check.
32     Returns:
33         Whether the string is a relative path.
34     """
35     # os.path.splitdrive does not reliably work on non-Windows systems
36     # breaking the coverage, using PureWindowsPath instead
37     is_full_windows_path_with_drive = bool(PureWindowsPath(path_string).drive)
38     if is_full_windows_path_with_drive:
39         return False
40 
41     is_remote_path = bool(urlparse(path_string).scheme)
42     if is_remote_path:
43         return False
44 
45     is_absolute_path = PurePosixPath(path_string).is_absolute()
46     if is_absolute_path:
47         return False
48 
49     return True
50 
51 
52 def _convert_paths_to_absolute_posix(
53     project_path: Path, conf_dictionary: Dict[str, Any]
54 ) -> Dict[str, Any]:
55     """Turn all relative paths inside ``conf_dictionary`` into absolute paths by appending them
56     to ``project_path`` and convert absolute Windows paths to POSIX format. This is a hack to
57     make sure that we don't have to change user's working directory for logging and datasets to
58     work. It is important for non-standard workflows such as IPython notebook where users don't go
59     through `kedro run` or `__main__.py` entrypoints.
60 
61     Example:
62     ::
63         >>> conf = _convert_paths_to_absolute_posix(
64         >>>     project_path=Path("/path/to/my/project"),
65         >>>     conf_dictionary={
66         >>>         "handlers": {
67         >>>             "info_file_handler": {
68         >>>                 "filename": "logs/info.log"
69         >>>             }
70         >>>         }
71         >>>     }
72         >>> )
73         >>> print(conf['handlers']['info_file_handler']['filename'])
74         "/path/to/my/project/logs/info.log"
75 
76     Args:
77         project_path: The root directory to prepend to relative path to make absolute path.
78         conf_dictionary: The configuration containing paths to expand.
79     Returns:
80         A dictionary containing only absolute paths.
81     Raises:
82         ValueError: If the provided ``project_path`` is not an absolute path.
83     """
84     if not project_path.is_absolute():
85         raise ValueError(
86             f"project_path must be an absolute path. Received: {project_path}"
87         )
88 
89     # only check a few conf keys that are known to specify a path string as value
90     conf_keys_with_filepath = ("filename", "filepath", "path")
91 
92     for conf_key, conf_value in conf_dictionary.items():
93 
94         # if the conf_value is another dictionary, absolutify its paths first.
95         if isinstance(conf_value, dict):
96             conf_dictionary[conf_key] = _convert_paths_to_absolute_posix(
97                 project_path, conf_value
98             )
99             continue
100 
101         # if the conf_value is not a dictionary nor a string, skip
102         if not isinstance(conf_value, str):
103             continue
104 
105         # if the conf_value is a string but the conf_key isn't one associated with filepath, skip
106         if conf_key not in conf_keys_with_filepath:
107             continue
108 
109         if _is_relative_path(conf_value):
110             # Absolute local path should be in POSIX format
111             conf_value_absolute_path = (project_path / conf_value).as_posix()
112             conf_dictionary[conf_key] = conf_value_absolute_path
113         elif PureWindowsPath(conf_value).drive:
114             # Convert absolute Windows path to POSIX format
115             conf_dictionary[conf_key] = PureWindowsPath(conf_value).as_posix()
116 
117     return conf_dictionary
118 
119 
120 def _validate_layers_for_transcoding(catalog: DataCatalog) -> None:
121     """Check that transcoded names that correspond to
122     the same dataset also belong to the same layer.
123     """
124 
125     def _find_conflicts():
126         base_names_to_layer = {}
127         for current_layer, dataset_names in catalog.layers.items():
128             for name in dataset_names:
129                 base_name, _ = _transcode_split(name)
130                 known_layer = base_names_to_layer.setdefault(base_name, current_layer)
131                 if current_layer != known_layer:
132                     yield name
133                 else:
134                     base_names_to_layer[base_name] = current_layer
135 
136     conflicting_datasets = sorted(_find_conflicts())
137     if conflicting_datasets:
138         error_str = ", ".join(conflicting_datasets)
139         raise ValueError(
140             f"Transcoded datasets should have the same layer. Mismatch found for: {error_str}"
141         )
142 
143 
144 def _update_nested_dict(old_dict: Dict[Any, Any], new_dict: Dict[Any, Any]) -> None:
145     """Update a nested dict with values of new_dict.
146 
147     Args:
148         old_dict: dict to be updated
149         new_dict: dict to use for updating old_dict
150 
151     """
152     for key, value in new_dict.items():
153         if key not in old_dict:
154             old_dict[key] = value
155         else:
156             if isinstance(old_dict[key], dict) and isinstance(value, dict):
157                 _update_nested_dict(old_dict[key], value)
158             else:
159                 old_dict[key] = value
160 
161 
162 class KedroContext:
163     """``KedroContext`` is the base class which holds the configuration and
164     Kedro's main functionality.
165     """
166 
167     def __init__(
168         self,
169         package_name: str,
170         project_path: Union[Path, str],
171         config_loader: ConfigLoader,
172         hook_manager: PluginManager,
173         env: str = None,
174         extra_params: Dict[str, Any] = None,
175     ):  # pylint: disable=too-many-arguments
176         """Create a context object by providing the root of a Kedro project and
177         the environment configuration subfolders
178         (see ``kedro.config.ConfigLoader``)
179 
180         Raises:
181             KedroContextError: If there is a mismatch
182                 between Kedro project version and package version.
183 
184         Args:
185             package_name: Package name for the Kedro project the context is
186                 created for.
187             project_path: Project path to define the context for.
188             hook_manager: The ``PluginManager`` to activate hooks, supplied by the session.
189             env: Optional argument for configuration default environment to be used
190                 for running the pipeline. If not specified, it defaults to "local".
191             extra_params: Optional dictionary containing extra project parameters.
192                 If specified, will update (and therefore take precedence over)
193                 the parameters retrieved from the project configuration.
194         """
195         self._project_path = Path(project_path).expanduser().resolve()
196         self._package_name = package_name
197         self._config_loader = config_loader
198         self._env = env
199         self._extra_params = deepcopy(extra_params)
200         self._hook_manager = hook_manager
201 
202     @property  # type: ignore
203     def env(self) -> Optional[str]:
204         """Property for the current Kedro environment.
205 
206         Returns:
207             Name of the current Kedro environment.
208 
209         """
210         return self._env
211 
212     @property
213     def project_path(self) -> Path:
214         """Read-only property containing Kedro's root project directory.
215 
216         Returns:
217             Project directory.
218 
219         """
220         return self._project_path
221 
222     @property
223     def catalog(self) -> DataCatalog:
224         """Read-only property referring to Kedro's ``DataCatalog`` for this context.
225 
226         Returns:
227             DataCatalog defined in `catalog.yml`.
228         Raises:
229             KedroContextError: Incorrect ``DataCatalog`` registered for the project.
230 
231         """
232         return self._get_catalog()
233 
234     @property
235     def params(self) -> Dict[str, Any]:
236         """Read-only property referring to Kedro's parameters for this context.
237 
238         Returns:
239             Parameters defined in `parameters.yml` with the addition of any
240                 extra parameters passed at initialization.
241         """
242         try:
243             params = self.config_loader["parameters"]
244         except MissingConfigException as exc:
245             warn(f"Parameters not found in your Kedro project config.\n{str(exc)}")
246             params = {}
247         _update_nested_dict(params, self._extra_params or {})
248         return params
249 
250     @property
251     def config_loader(self):
252         """Read-only property referring to Kedro's ``ConfigLoader`` for this
253         context.
254         Returns:
255             Instance of `ConfigLoader`.
256         Raises:
257             KedroContextError: Incorrect ``ConfigLoader`` registered for the project.
258         """
259         return self._config_loader
260 
261     def _get_catalog(
262         self,
263         save_version: str = None,
264         load_versions: Dict[str, str] = None,
265     ) -> DataCatalog:
266         """A hook for changing the creation of a DataCatalog instance.
267 
268         Returns:
269             DataCatalog defined in `catalog.yml`.
270         Raises:
271             KedroContextError: Incorrect ``DataCatalog`` registered for the project.
272 
273         """
274         # '**/catalog*' reads modular pipeline configs
275         conf_catalog = self.config_loader["catalog"]
276         # turn relative paths in conf_catalog into absolute paths
277         # before initializing the catalog
278         conf_catalog = _convert_paths_to_absolute_posix(
279             project_path=self.project_path, conf_dictionary=conf_catalog
280         )
281         conf_creds = self._get_config_credentials()
282 
283         catalog = settings.DATA_CATALOG_CLASS.from_config(
284             catalog=conf_catalog,
285             credentials=conf_creds,
286             load_versions=load_versions,
287             save_version=save_version,
288         )
289 
290         feed_dict = self._get_feed_dict()
291         catalog.add_feed_dict(feed_dict)
292         if catalog.layers:
293             _validate_layers_for_transcoding(catalog)
294         self._hook_manager.hook.after_catalog_created(
295             catalog=catalog,
296             conf_catalog=conf_catalog,
297             conf_creds=conf_creds,
298             feed_dict=feed_dict,
299             save_version=save_version,
300             load_versions=load_versions,
301         )
302         return catalog
303 
304     def _get_feed_dict(self) -> Dict[str, Any]:
305         """Get parameters and return the feed dictionary."""
306         params = self.params
307         feed_dict = {"parameters": params}
308 
309         def _add_param_to_feed_dict(param_name, param_value):
310             """This recursively adds parameter paths to the `feed_dict`,
311             whenever `param_value` is a dictionary itself, so that users can
312             specify specific nested parameters in their node inputs.
313 
314             Example:
315 
316                 >>> param_name = "a"
317                 >>> param_value = {"b": 1}
318                 >>> _add_param_to_feed_dict(param_name, param_value)
319                 >>> assert feed_dict["params:a"] == {"b": 1}
320                 >>> assert feed_dict["params:a.b"] == 1
321             """
322             key = f"params:{param_name}"
323             feed_dict[key] = param_value
324 
325             if isinstance(param_value, dict):
326                 for key, val in param_value.items():
327                     _add_param_to_feed_dict(f"{param_name}.{key}", val)
328 
329         for param_name, param_value in params.items():
330             _add_param_to_feed_dict(param_name, param_value)
331 
332         return feed_dict
333 
334     def _get_config_credentials(self) -> Dict[str, Any]:
335         """Getter for credentials specified in credentials directory."""
336         try:
337             conf_creds = self.config_loader["credentials"]
338         except MissingConfigException as exc:
339             warn(f"Credentials not found in your Kedro project config.\n{str(exc)}")
340             conf_creds = {}
341         return conf_creds
342 
343 
344 class KedroContextError(Exception):
345     """Error occurred when loading project and running context pipeline."""
346
```
--- 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/kedro/framework/context/context.py b/kedro/framework/context/context.py
--- a/kedro/framework/context/context.py
+++ b/kedro/framework/context/context.py
@@ -1,5 +1,6 @@
 """This module provides context for Kedro project."""
 
+import logging
 from copy import deepcopy
 from pathlib import Path, PurePosixPath, PureWindowsPath
 from typing import Any, Dict, Optional, Union
@@ -336,7 +337,9 @@
         try:
             conf_creds = self.config_loader["credentials"]
         except MissingConfigException as exc:
-            warn(f"Credentials not found in your Kedro project config.\n{str(exc)}")
+            logging.getLogger(__name__).debug(
+                "Credentials not found in your Kedro project config.\n %s", str(exc)
+            )
             conf_creds = {}
         return conf_creds

{"golden_diff": "diff --git a/kedro/framework/context/context.py b/kedro/framework/context/context.py\n--- a/kedro/framework/context/context.py\n+++ b/kedro/framework/context/context.py\n@@ -1,5 +1,6 @@\n \"\"\"This module provides context for Kedro project.\"\"\"\n \n+import logging\n from copy import deepcopy\n from pathlib import Path, PurePosixPath, PureWindowsPath\n from typing import Any, Dict, Optional, Union\n@@ -336,7 +337,9 @@\n         try:\n             conf_creds = self.config_loader[\"credentials\"]\n         except MissingConfigException as exc:\n-            warn(f\"Credentials not found in your Kedro project config.\\n{str(exc)}\")\n+            logging.getLogger(__name__).debug(\n+                \"Credentials not found in your Kedro project config.\\n %s\", str(exc)\n+            )\n             conf_creds = {}\n         return conf_creds\n", "issue": "Remove/change log level for \"Credentials not found in your Kedro project config\"\n## Description\r\nWhen getting the credentials in the KedroContext, we specifically look for the `credentials` file. If a project doesn't make use of this file a warning log will be thrown saying \"Credentials not found in your Kedro project config\". Not all users use the credentials file and so this warning isn't applicable. \r\n\r\n## Context\r\nWe're adding functionality to allow users to have credentials in environment variables (which is currently also possible with the `TemplatedConfigLoader`), which makes this error irrelevant. \r\n\n", "before_files": [{"content": "\"\"\"This module provides context for Kedro project.\"\"\"\n\nfrom copy import deepcopy\nfrom pathlib import Path, PurePosixPath, PureWindowsPath\nfrom typing import Any, Dict, Optional, Union\nfrom urllib.parse import urlparse\nfrom warnings import warn\n\nfrom pluggy import PluginManager\n\nfrom kedro.config import ConfigLoader, MissingConfigException\nfrom kedro.framework.project import settings\nfrom kedro.io import DataCatalog\nfrom kedro.pipeline.pipeline import _transcode_split\n\n\ndef _is_relative_path(path_string: str) -> bool:\n    \"\"\"Checks whether a path string is a relative path.\n\n    Example:\n    ::\n        >>> _is_relative_path(\"data/01_raw\") == True\n        >>> _is_relative_path(\"logs/info.log\") == True\n        >>> _is_relative_path(\"/tmp/data/01_raw\") == False\n        >>> _is_relative_path(r\"C:\\\\logs\\\\info.log\") == False\n        >>> _is_relative_path(r\"\\\\logs\\\\'info.log\") == False\n        >>> _is_relative_path(\"c:/logs/info.log\") == False\n        >>> _is_relative_path(\"s3://logs/info.log\") == False\n\n    Args:\n        path_string: The path string to check.\n    Returns:\n        Whether the string is a relative path.\n    \"\"\"\n    # os.path.splitdrive does not reliably work on non-Windows systems\n    # breaking the coverage, using PureWindowsPath instead\n    is_full_windows_path_with_drive = bool(PureWindowsPath(path_string).drive)\n    if is_full_windows_path_with_drive:\n        return False\n\n    is_remote_path = bool(urlparse(path_string).scheme)\n    if is_remote_path:\n        return False\n\n    is_absolute_path = PurePosixPath(path_string).is_absolute()\n    if is_absolute_path:\n        return False\n\n    return True\n\n\ndef _convert_paths_to_absolute_posix(\n    project_path: Path, conf_dictionary: Dict[str, Any]\n) -> Dict[str, Any]:\n    \"\"\"Turn all relative paths inside ``conf_dictionary`` into absolute paths by appending them\n    to ``project_path`` and convert absolute Windows paths to POSIX format. This is a hack to\n    make sure that we don't have to change user's working directory for logging and datasets to\n    work. It is important for non-standard workflows such as IPython notebook where users don't go\n    through `kedro run` or `__main__.py` entrypoints.\n\n    Example:\n    ::\n        >>> conf = _convert_paths_to_absolute_posix(\n        >>>     project_path=Path(\"/path/to/my/project\"),\n        >>>     conf_dictionary={\n        >>>         \"handlers\": {\n        >>>             \"info_file_handler\": {\n        >>>                 \"filename\": \"logs/info.log\"\n        >>>             }\n        >>>         }\n        >>>     }\n        >>> )\n        >>> print(conf['handlers']['info_file_handler']['filename'])\n        \"/path/to/my/project/logs/info.log\"\n\n    Args:\n        project_path: The root directory to prepend to relative path to make absolute path.\n        conf_dictionary: The configuration containing paths to expand.\n    Returns:\n        A dictionary containing only absolute paths.\n    Raises:\n        ValueError: If the provided ``project_path`` is not an absolute path.\n    \"\"\"\n    if not project_path.is_absolute():\n        raise ValueError(\n            f\"project_path must be an absolute path. Received: {project_path}\"\n        )\n\n    # only check a few conf keys that are known to specify a path string as value\n    conf_keys_with_filepath = (\"filename\", \"filepath\", \"path\")\n\n    for conf_key, conf_value in conf_dictionary.items():\n\n        # if the conf_value is another dictionary, absolutify its paths first.\n        if isinstance(conf_value, dict):\n            conf_dictionary[conf_key] = _convert_paths_to_absolute_posix(\n                project_path, conf_value\n            )\n            continue\n\n        # if the conf_value is not a dictionary nor a string, skip\n        if not isinstance(conf_value, str):\n            continue\n\n        # if the conf_value is a string but the conf_key isn't one associated with filepath, skip\n        if conf_key not in conf_keys_with_filepath:\n            continue\n\n        if _is_relative_path(conf_value):\n            # Absolute local path should be in POSIX format\n            conf_value_absolute_path = (project_path / conf_value).as_posix()\n            conf_dictionary[conf_key] = conf_value_absolute_path\n        elif PureWindowsPath(conf_value).drive:\n            # Convert absolute Windows path to POSIX format\n            conf_dictionary[conf_key] = PureWindowsPath(conf_value).as_posix()\n\n    return conf_dictionary\n\n\ndef _validate_layers_for_transcoding(catalog: DataCatalog) -> None:\n    \"\"\"Check that transcoded names that correspond to\n    the same dataset also belong to the same layer.\n    \"\"\"\n\n    def _find_conflicts():\n        base_names_to_layer = {}\n        for current_layer, dataset_names in catalog.layers.items():\n            for name in dataset_names:\n                base_name, _ = _transcode_split(name)\n                known_layer = base_names_to_layer.setdefault(base_name, current_layer)\n                if current_layer != known_layer:\n                    yield name\n                else:\n                    base_names_to_layer[base_name] = current_layer\n\n    conflicting_datasets = sorted(_find_conflicts())\n    if conflicting_datasets:\n        error_str = \", \".join(conflicting_datasets)\n        raise ValueError(\n            f\"Transcoded datasets should have the same layer. Mismatch found for: {error_str}\"\n        )\n\n\ndef _update_nested_dict(old_dict: Dict[Any, Any], new_dict: Dict[Any, Any]) -> None:\n    \"\"\"Update a nested dict with values of new_dict.\n\n    Args:\n        old_dict: dict to be updated\n        new_dict: dict to use for updating old_dict\n\n    \"\"\"\n    for key, value in new_dict.items():\n        if key not in old_dict:\n            old_dict[key] = value\n        else:\n            if isinstance(old_dict[key], dict) and isinstance(value, dict):\n                _update_nested_dict(old_dict[key], value)\n            else:\n                old_dict[key] = value\n\n\nclass KedroContext:\n    \"\"\"``KedroContext`` is the base class which holds the configuration and\n    Kedro's main functionality.\n    \"\"\"\n\n    def __init__(\n        self,\n        package_name: str,\n        project_path: Union[Path, str],\n        config_loader: ConfigLoader,\n        hook_manager: PluginManager,\n        env: str = None,\n        extra_params: Dict[str, Any] = None,\n    ):  # pylint: disable=too-many-arguments\n        \"\"\"Create a context object by providing the root of a Kedro project and\n        the environment configuration subfolders\n        (see ``kedro.config.ConfigLoader``)\n\n        Raises:\n            KedroContextError: If there is a mismatch\n                between Kedro project version and package version.\n\n        Args:\n            package_name: Package name for the Kedro project the context is\n                created for.\n            project_path: Project path to define the context for.\n            hook_manager: The ``PluginManager`` to activate hooks, supplied by the session.\n            env: Optional argument for configuration default environment to be used\n                for running the pipeline. If not specified, it defaults to \"local\".\n            extra_params: Optional dictionary containing extra project parameters.\n                If specified, will update (and therefore take precedence over)\n                the parameters retrieved from the project configuration.\n        \"\"\"\n        self._project_path = Path(project_path).expanduser().resolve()\n        self._package_name = package_name\n        self._config_loader = config_loader\n        self._env = env\n        self._extra_params = deepcopy(extra_params)\n        self._hook_manager = hook_manager\n\n    @property  # type: ignore\n    def env(self) -> Optional[str]:\n        \"\"\"Property for the current Kedro environment.\n\n        Returns:\n            Name of the current Kedro environment.\n\n        \"\"\"\n        return self._env\n\n    @property\n    def project_path(self) -> Path:\n        \"\"\"Read-only property containing Kedro's root project directory.\n\n        Returns:\n            Project directory.\n\n        \"\"\"\n        return self._project_path\n\n    @property\n    def catalog(self) -> DataCatalog:\n        \"\"\"Read-only property referring to Kedro's ``DataCatalog`` for this context.\n\n        Returns:\n            DataCatalog defined in `catalog.yml`.\n        Raises:\n            KedroContextError: Incorrect ``DataCatalog`` registered for the project.\n\n        \"\"\"\n        return self._get_catalog()\n\n    @property\n    def params(self) -> Dict[str, Any]:\n        \"\"\"Read-only property referring to Kedro's parameters for this context.\n\n        Returns:\n            Parameters defined in `parameters.yml` with the addition of any\n                extra parameters passed at initialization.\n        \"\"\"\n        try:\n            params = self.config_loader[\"parameters\"]\n        except MissingConfigException as exc:\n            warn(f\"Parameters not found in your Kedro project config.\\n{str(exc)}\")\n            params = {}\n        _update_nested_dict(params, self._extra_params or {})\n        return params\n\n    @property\n    def config_loader(self):\n        \"\"\"Read-only property referring to Kedro's ``ConfigLoader`` for this\n        context.\n        Returns:\n            Instance of `ConfigLoader`.\n        Raises:\n            KedroContextError: Incorrect ``ConfigLoader`` registered for the project.\n        \"\"\"\n        return self._config_loader\n\n    def _get_catalog(\n        self,\n        save_version: str = None,\n        load_versions: Dict[str, str] = None,\n    ) -> DataCatalog:\n        \"\"\"A hook for changing the creation of a DataCatalog instance.\n\n        Returns:\n            DataCatalog defined in `catalog.yml`.\n        Raises:\n            KedroContextError: Incorrect ``DataCatalog`` registered for the project.\n\n        \"\"\"\n        # '**/catalog*' reads modular pipeline configs\n        conf_catalog = self.config_loader[\"catalog\"]\n        # turn relative paths in conf_catalog into absolute paths\n        # before initializing the catalog\n        conf_catalog = _convert_paths_to_absolute_posix(\n            project_path=self.project_path, conf_dictionary=conf_catalog\n        )\n        conf_creds = self._get_config_credentials()\n\n        catalog = settings.DATA_CATALOG_CLASS.from_config(\n            catalog=conf_catalog,\n            credentials=conf_creds,\n            load_versions=load_versions,\n            save_version=save_version,\n        )\n\n        feed_dict = self._get_feed_dict()\n        catalog.add_feed_dict(feed_dict)\n        if catalog.layers:\n            _validate_layers_for_transcoding(catalog)\n        self._hook_manager.hook.after_catalog_created(\n            catalog=catalog,\n            conf_catalog=conf_catalog,\n            conf_creds=conf_creds,\n            feed_dict=feed_dict,\n            save_version=save_version,\n            load_versions=load_versions,\n        )\n        return catalog\n\n    def _get_feed_dict(self) -> Dict[str, Any]:\n        \"\"\"Get parameters and return the feed dictionary.\"\"\"\n        params = self.params\n        feed_dict = {\"parameters\": params}\n\n        def _add_param_to_feed_dict(param_name, param_value):\n            \"\"\"This recursively adds parameter paths to the `feed_dict`,\n            whenever `param_value` is a dictionary itself, so that users can\n            specify specific nested parameters in their node inputs.\n\n            Example:\n\n                >>> param_name = \"a\"\n                >>> param_value = {\"b\": 1}\n                >>> _add_param_to_feed_dict(param_name, param_value)\n                >>> assert feed_dict[\"params:a\"] == {\"b\": 1}\n                >>> assert feed_dict[\"params:a.b\"] == 1\n            \"\"\"\n            key = f\"params:{param_name}\"\n            feed_dict[key] = param_value\n\n            if isinstance(param_value, dict):\n                for key, val in param_value.items():\n                    _add_param_to_feed_dict(f\"{param_name}.{key}\", val)\n\n        for param_name, param_value in params.items():\n            _add_param_to_feed_dict(param_name, param_value)\n\n        return feed_dict\n\n    def _get_config_credentials(self) -> Dict[str, Any]:\n        \"\"\"Getter for credentials specified in credentials directory.\"\"\"\n        try:\n            conf_creds = self.config_loader[\"credentials\"]\n        except MissingConfigException as exc:\n            warn(f\"Credentials not found in your Kedro project config.\\n{str(exc)}\")\n            conf_creds = {}\n        return conf_creds\n\n\nclass KedroContextError(Exception):\n    \"\"\"Error occurred when loading project and running context pipeline.\"\"\"\n", "path": "kedro/framework/context/context.py"}], "after_files": [{"content": "\"\"\"This module provides context for Kedro project.\"\"\"\n\nimport logging\nfrom copy import deepcopy\nfrom pathlib import Path, PurePosixPath, PureWindowsPath\nfrom typing import Any, Dict, Optional, Union\nfrom urllib.parse import urlparse\nfrom warnings import warn\n\nfrom pluggy import PluginManager\n\nfrom kedro.config import ConfigLoader, MissingConfigException\nfrom kedro.framework.project import settings\nfrom kedro.io import DataCatalog\nfrom kedro.pipeline.pipeline import _transcode_split\n\n\ndef _is_relative_path(path_string: str) -> bool:\n    \"\"\"Checks whether a path string is a relative path.\n\n    Example:\n    ::\n        >>> _is_relative_path(\"data/01_raw\") == True\n        >>> _is_relative_path(\"logs/info.log\") == True\n        >>> _is_relative_path(\"/tmp/data/01_raw\") == False\n        >>> _is_relative_path(r\"C:\\\\logs\\\\info.log\") == False\n        >>> _is_relative_path(r\"\\\\logs\\\\'info.log\") == False\n        >>> _is_relative_path(\"c:/logs/info.log\") == False\n        >>> _is_relative_path(\"s3://logs/info.log\") == False\n\n    Args:\n        path_string: The path string to check.\n    Returns:\n        Whether the string is a relative path.\n    \"\"\"\n    # os.path.splitdrive does not reliably work on non-Windows systems\n    # breaking the coverage, using PureWindowsPath instead\n    is_full_windows_path_with_drive = bool(PureWindowsPath(path_string).drive)\n    if is_full_windows_path_with_drive:\n        return False\n\n    is_remote_path = bool(urlparse(path_string).scheme)\n    if is_remote_path:\n        return False\n\n    is_absolute_path = PurePosixPath(path_string).is_absolute()\n    if is_absolute_path:\n        return False\n\n    return True\n\n\ndef _convert_paths_to_absolute_posix(\n    project_path: Path, conf_dictionary: Dict[str, Any]\n) -> Dict[str, Any]:\n    \"\"\"Turn all relative paths inside ``conf_dictionary`` into absolute paths by appending them\n    to ``project_path`` and convert absolute Windows paths to POSIX format. This is a hack to\n    make sure that we don't have to change user's working directory for logging and datasets to\n    work. It is important for non-standard workflows such as IPython notebook where users don't go\n    through `kedro run` or `__main__.py` entrypoints.\n\n    Example:\n    ::\n        >>> conf = _convert_paths_to_absolute_posix(\n        >>>     project_path=Path(\"/path/to/my/project\"),\n        >>>     conf_dictionary={\n        >>>         \"handlers\": {\n        >>>             \"info_file_handler\": {\n        >>>                 \"filename\": \"logs/info.log\"\n        >>>             }\n        >>>         }\n        >>>     }\n        >>> )\n        >>> print(conf['handlers']['info_file_handler']['filename'])\n        \"/path/to/my/project/logs/info.log\"\n\n    Args:\n        project_path: The root directory to prepend to relative path to make absolute path.\n        conf_dictionary: The configuration containing paths to expand.\n    Returns:\n        A dictionary containing only absolute paths.\n    Raises:\n        ValueError: If the provided ``project_path`` is not an absolute path.\n    \"\"\"\n    if not project_path.is_absolute():\n        raise ValueError(\n            f\"project_path must be an absolute path. Received: {project_path}\"\n        )\n\n    # only check a few conf keys that are known to specify a path string as value\n    conf_keys_with_filepath = (\"filename\", \"filepath\", \"path\")\n\n    for conf_key, conf_value in conf_dictionary.items():\n\n        # if the conf_value is another dictionary, absolutify its paths first.\n        if isinstance(conf_value, dict):\n            conf_dictionary[conf_key] = _convert_paths_to_absolute_posix(\n                project_path, conf_value\n            )\n            continue\n\n        # if the conf_value is not a dictionary nor a string, skip\n        if not isinstance(conf_value, str):\n            continue\n\n        # if the conf_value is a string but the conf_key isn't one associated with filepath, skip\n        if conf_key not in conf_keys_with_filepath:\n            continue\n\n        if _is_relative_path(conf_value):\n            # Absolute local path should be in POSIX format\n            conf_value_absolute_path = (project_path / conf_value).as_posix()\n            conf_dictionary[conf_key] = conf_value_absolute_path\n        elif PureWindowsPath(conf_value).drive:\n            # Convert absolute Windows path to POSIX format\n            conf_dictionary[conf_key] = PureWindowsPath(conf_value).as_posix()\n\n    return conf_dictionary\n\n\ndef _validate_layers_for_transcoding(catalog: DataCatalog) -> None:\n    \"\"\"Check that transcoded names that correspond to\n    the same dataset also belong to the same layer.\n    \"\"\"\n\n    def _find_conflicts():\n        base_names_to_layer = {}\n        for current_layer, dataset_names in catalog.layers.items():\n            for name in dataset_names:\n                base_name, _ = _transcode_split(name)\n                known_layer = base_names_to_layer.setdefault(base_name, current_layer)\n                if current_layer != known_layer:\n                    yield name\n                else:\n                    base_names_to_layer[base_name] = current_layer\n\n    conflicting_datasets = sorted(_find_conflicts())\n    if conflicting_datasets:\n        error_str = \", \".join(conflicting_datasets)\n        raise ValueError(\n            f\"Transcoded datasets should have the same layer. Mismatch found for: {error_str}\"\n        )\n\n\ndef _update_nested_dict(old_dict: Dict[Any, Any], new_dict: Dict[Any, Any]) -> None:\n    \"\"\"Update a nested dict with values of new_dict.\n\n    Args:\n        old_dict: dict to be updated\n        new_dict: dict to use for updating old_dict\n\n    \"\"\"\n    for key, value in new_dict.items():\n        if key not in old_dict:\n            old_dict[key] = value\n        else:\n            if isinstance(old_dict[key], dict) and isinstance(value, dict):\n                _update_nested_dict(old_dict[key], value)\n            else:\n                old_dict[key] = value\n\n\nclass KedroContext:\n    \"\"\"``KedroContext`` is the base class which holds the configuration and\n    Kedro's main functionality.\n    \"\"\"\n\n    def __init__(\n        self,\n        package_name: str,\n        project_path: Union[Path, str],\n        config_loader: ConfigLoader,\n        hook_manager: PluginManager,\n        env: str = None,\n        extra_params: Dict[str, Any] = None,\n    ):  # pylint: disable=too-many-arguments\n        \"\"\"Create a context object by providing the root of a Kedro project and\n        the environment configuration subfolders\n        (see ``kedro.config.ConfigLoader``)\n\n        Raises:\n            KedroContextError: If there is a mismatch\n                between Kedro project version and package version.\n\n        Args:\n            package_name: Package name for the Kedro project the context is\n                created for.\n            project_path: Project path to define the context for.\n            hook_manager: The ``PluginManager`` to activate hooks, supplied by the session.\n            env: Optional argument for configuration default environment to be used\n                for running the pipeline. If not specified, it defaults to \"local\".\n            extra_params: Optional dictionary containing extra project parameters.\n                If specified, will update (and therefore take precedence over)\n                the parameters retrieved from the project configuration.\n        \"\"\"\n        self._project_path = Path(project_path).expanduser().resolve()\n        self._package_name = package_name\n        self._config_loader = config_loader\n        self._env = env\n        self._extra_params = deepcopy(extra_params)\n        self._hook_manager = hook_manager\n\n    @property  # type: ignore\n    def env(self) -> Optional[str]:\n        \"\"\"Property for the current Kedro environment.\n\n        Returns:\n            Name of the current Kedro environment.\n\n        \"\"\"\n        return self._env\n\n    @property\n    def project_path(self) -> Path:\n        \"\"\"Read-only property containing Kedro's root project directory.\n\n        Returns:\n            Project directory.\n\n        \"\"\"\n        return self._project_path\n\n    @property\n    def catalog(self) -> DataCatalog:\n        \"\"\"Read-only property referring to Kedro's ``DataCatalog`` for this context.\n\n        Returns:\n            DataCatalog defined in `catalog.yml`.\n        Raises:\n            KedroContextError: Incorrect ``DataCatalog`` registered for the project.\n\n        \"\"\"\n        return self._get_catalog()\n\n    @property\n    def params(self) -> Dict[str, Any]:\n        \"\"\"Read-only property referring to Kedro's parameters for this context.\n\n        Returns:\n            Parameters defined in `parameters.yml` with the addition of any\n                extra parameters passed at initialization.\n        \"\"\"\n        try:\n            params = self.config_loader[\"parameters\"]\n        except MissingConfigException as exc:\n            warn(f\"Parameters not found in your Kedro project config.\\n{str(exc)}\")\n            params = {}\n        _update_nested_dict(params, self._extra_params or {})\n        return params\n\n    @property\n    def config_loader(self):\n        \"\"\"Read-only property referring to Kedro's ``ConfigLoader`` for this\n        context.\n        Returns:\n            Instance of `ConfigLoader`.\n        Raises:\n            KedroContextError: Incorrect ``ConfigLoader`` registered for the project.\n        \"\"\"\n        return self._config_loader\n\n    def _get_catalog(\n        self,\n        save_version: str = None,\n        load_versions: Dict[str, str] = None,\n    ) -> DataCatalog:\n        \"\"\"A hook for changing the creation of a DataCatalog instance.\n\n        Returns:\n            DataCatalog defined in `catalog.yml`.\n        Raises:\n            KedroContextError: Incorrect ``DataCatalog`` registered for the project.\n\n        \"\"\"\n        # '**/catalog*' reads modular pipeline configs\n        conf_catalog = self.config_loader[\"catalog\"]\n        # turn relative paths in conf_catalog into absolute paths\n        # before initializing the catalog\n        conf_catalog = _convert_paths_to_absolute_posix(\n            project_path=self.project_path, conf_dictionary=conf_catalog\n        )\n        conf_creds = self._get_config_credentials()\n\n        catalog = settings.DATA_CATALOG_CLASS.from_config(\n            catalog=conf_catalog,\n            credentials=conf_creds,\n            load_versions=load_versions,\n            save_version=save_version,\n        )\n\n        feed_dict = self._get_feed_dict()\n        catalog.add_feed_dict(feed_dict)\n        if catalog.layers:\n            _validate_layers_for_transcoding(catalog)\n        self._hook_manager.hook.after_catalog_created(\n            catalog=catalog,\n            conf_catalog=conf_catalog,\n            conf_creds=conf_creds,\n            feed_dict=feed_dict,\n            save_version=save_version,\n            load_versions=load_versions,\n        )\n        return catalog\n\n    def _get_feed_dict(self) -> Dict[str, Any]:\n        \"\"\"Get parameters and return the feed dictionary.\"\"\"\n        params = self.params\n        feed_dict = {\"parameters\": params}\n\n        def _add_param_to_feed_dict(param_name, param_value):\n            \"\"\"This recursively adds parameter paths to the `feed_dict`,\n            whenever `param_value` is a dictionary itself, so that users can\n            specify specific nested parameters in their node inputs.\n\n            Example:\n\n                >>> param_name = \"a\"\n                >>> param_value = {\"b\": 1}\n                >>> _add_param_to_feed_dict(param_name, param_value)\n                >>> assert feed_dict[\"params:a\"] == {\"b\": 1}\n                >>> assert feed_dict[\"params:a.b\"] == 1\n            \"\"\"\n            key = f\"params:{param_name}\"\n            feed_dict[key] = param_value\n\n            if isinstance(param_value, dict):\n                for key, val in param_value.items():\n                    _add_param_to_feed_dict(f\"{param_name}.{key}\", val)\n\n        for param_name, param_value in params.items():\n            _add_param_to_feed_dict(param_name, param_value)\n\n        return feed_dict\n\n    def _get_config_credentials(self) -> Dict[str, Any]:\n        \"\"\"Getter for credentials specified in credentials directory.\"\"\"\n        try:\n            conf_creds = self.config_loader[\"credentials\"]\n        except MissingConfigException as exc:\n            logging.getLogger(__name__).debug(\n                \"Credentials not found in your Kedro project config.\\n %s\", str(exc)\n            )\n            conf_creds = {}\n        return conf_creds\n\n\nclass KedroContextError(Exception):\n    \"\"\"Error occurred when loading project and running context pipeline.\"\"\"\n", "path": "kedro/framework/context/context.py"}]}