Coverage for mlos_bench/mlos_bench/services/local/temp_dir_context.py: 100%
24 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-21 01:50 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-21 01:50 +0000
1#
2# Copyright (c) Microsoft Corporation.
3# Licensed under the MIT License.
4#
5"""Helper functions to work with temp files locally on the scheduler side."""
7import abc
8import logging
9import os
10from collections.abc import Callable
11from contextlib import nullcontext
12from string import Template
13from tempfile import TemporaryDirectory
14from typing import Any
16from mlos_bench.services.base_service import Service
18_LOG = logging.getLogger(__name__)
21class TempDirContextService(Service, metaclass=abc.ABCMeta):
22 """
23 A *base* service class that provides a method to create a temporary directory
24 context for local scripts.
26 It is inherited by LocalExecService and MockLocalExecService. This class is not
27 supposed to be used as a standalone service.
28 """
30 def __init__(
31 self,
32 config: dict[str, Any] | None = None,
33 global_config: dict[str, Any] | None = None,
34 parent: Service | None = None,
35 methods: dict[str, Callable] | list[Callable] | None = None,
36 ):
37 """
38 Create a new instance of a service that provides temporary directory context for
39 local exec service.
41 Parameters
42 ----------
43 config : dict
44 Free-format dictionary that contains parameters for the service.
45 (E.g., root path for config files, etc.)
46 global_config : dict
47 Free-format dictionary of global parameters.
48 parent : Service
49 An optional parent service that can provide mixin functions.
50 methods : Union[dict[str, Callable], list[Callable], None]
51 New methods to register with the service.
52 """
53 super().__init__(
54 config,
55 global_config,
56 parent,
57 self.merge_methods(methods, [self.temp_dir_context]),
58 )
59 self._temp_dir = self.config.get("temp_dir")
60 if self._temp_dir:
61 # expand globals
62 self._temp_dir = Template(self._temp_dir).safe_substitute(global_config or {})
63 # and resolve the path to absolute path
64 self._temp_dir = self._config_loader_service.resolve_path(self._temp_dir)
65 _LOG.info("%s: temp dir: %s", self, self._temp_dir)
67 def temp_dir_context(
68 self,
69 path: str | None = None,
70 ) -> TemporaryDirectory | nullcontext:
71 """
72 Create a temp directory or use the provided path.
74 Parameters
75 ----------
76 path : str
77 A path to the temporary directory. Create a new one if None.
79 Returns
80 -------
81 temp_dir_context : tempfile.TemporaryDirectory
82 Temporary directory context to use in the `with` clause.
83 """
84 temp_dir = path or self._temp_dir
85 if temp_dir is None:
86 return TemporaryDirectory()
87 os.makedirs(temp_dir, exist_ok=True)
88 return nullcontext(temp_dir)