We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Move to new version json schema reference resolution
The latest version 4.18.0 of jsonschema migrated to a new way of handling schema reference resolution that breaks our current code.  Will need to adjust it, but for now I've pinned it to the old version in #436 

See Also:
https://python-jsonschema.readthedocs.io/en/stable/referencing/#migrating-from-refresolver

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mlos_bench/setup.py`
Content:
```
1 #
2 # Copyright (c) Microsoft Corporation.
3 # Licensed under the MIT License.
4 #
5 """
6 Setup instructions for the mlos_bench package.
7 """
8 
9 from logging import warning
10 from itertools import chain
11 from typing import Dict, List
12 
13 from setuptools import setup, find_packages
14 
15 from _version import _VERSION    # pylint: disable=import-private-name
16 
17 try:
18     from setuptools_scm import get_version
19     version = get_version(root='..', relative_to=__file__)
20     if version is not None:
21         _VERSION = version  # noqa: F811
22 except ImportError:
23     warning("setuptools_scm not found, using version from _version.py")
24 except LookupError as e:
25     warning(f"setuptools_scm failed to find git version, using version from _version.py: {e}")
26 
27 
28 extra_requires: Dict[str, List[str]] = {    # pylint: disable=consider-using-namedtuple-or-dataclass
29     # Additional tools for extra functionality.
30     'azure': ['azure-storage-file-share'],
31     'storage-sql-duckdb': ['sqlalchemy', 'duckdb_engine'],
32     'storage-sql-mysql': ['sqlalchemy', 'mysql-connector-python'],
33     'storage-sql-postgres': ['sqlalchemy', 'psycopg2'],
34     'storage-sql-sqlite': ['sqlalchemy'],   # sqlite3 comes with python, so we don't need to install it.
35     # Transitive extra_requires from mlos-core.
36     'flaml': ['flaml[blendsearch]'],
37     'smac': ['smac'],
38 }
39 
40 # construct special 'full' extra that adds requirements for all built-in
41 # backend integrations and additional extra features.
42 extra_requires['full'] = list(set(chain(*extra_requires.values())))
43 
44 extra_requires['full-tests'] = extra_requires['full'] + [
45     'pytest',
46     'pytest-forked',
47     'pytest-xdist',
48     'pytest-cov',
49     'pytest-local-badge',
50 ]
51 
52 # pylint: disable=duplicate-code
53 MODULE_BASE_NAME = 'mlos_bench'
54 setup(
55     name='mlos-bench',
56     version=_VERSION,
57     packages=find_packages(exclude=[f"{MODULE_BASE_NAME}.tests", f"{MODULE_BASE_NAME}.tests.*"]),
58     package_data={
59         '': ['py.typed', '**/*.pyi'],
60         'mlos_bench': [
61             'config/**/*.md',
62             'config/**/*.jsonc',
63             'config/**/*.json',
64             'config/**/*.py',
65             'config/**/*.sh',
66             'config/**/*.cmd',
67             'config/**/*.ps1',
68         ],
69     },
70     entry_points={
71         'console_scripts': [
72             'mlos_bench = mlos_bench.run:_main',
73         ],
74     },
75     install_requires=[
76         'mlos-core==' + _VERSION,
77         'requests',
78         'json5',
79         'jsonschema',
80         'importlib_resources;python_version<"3.10"',
81     ] + extra_requires['storage-sql-sqlite'],   # NOTE: For now sqlite is a fallback storage backend, so we always install it.
82     extras_require=extra_requires,
83     author='Microsoft',
84     author_email='mlos-maintainers@service.microsoft.com',
85     description=('MLOS Bench Python interface for benchmark automation and optimization.'),
86     license='MIT',
87     keywords='',
88     url='https://aka.ms/mlos-core',
89     python_requires='>=3.8',
90 )
91
```

Path: `mlos_bench/mlos_bench/config/schemas/config_schemas.py`
Content:
```
1 #
2 # Copyright (c) Microsoft Corporation.
3 # Licensed under the MIT License.
4 #
5 """
6 A simple class for describing where to find different config schemas and validating configs against them.
7 """
8 
9 import logging
10 from enum import Enum
11 from os import path, walk, environ
12 from typing import Dict, Iterator, Mapping
13 
14 import json         # schema files are pure json - no comments
15 import jsonschema
16 
17 from mlos_bench.util import path_join
18 
19 _LOG = logging.getLogger(__name__)
20 
21 # The path to find all config schemas.
22 CONFIG_SCHEMA_DIR = path_join(path.dirname(__file__), abs_path=True)
23 
24 # Allow skipping schema validation for tight dev cycle changes.
25 # It is used in `ConfigSchema.validate()` method below.
26 # NOTE: this may cause pytest to fail if it's expecting exceptions
27 # to be raised for invalid configs.
28 _VALIDATION_ENV_FLAG = 'MLOS_BENCH_SKIP_SCHEMA_VALIDATION'
29 _SKIP_VALIDATION = (environ.get(_VALIDATION_ENV_FLAG, 'false').lower()
30                     in {'true', 'y', 'yes', 'on', '1'})
31 
32 
33 # Note: we separate out the SchemaStore from a class method on ConfigSchema
34 # because of issues with mypy/pylint and non-Enum-member class members.
35 class SchemaStore(Mapping):
36     """
37     A simple class for storing schemas and subschemas for the validator to reference.
38     """
39 
40     # A class member mapping of schema id to schema object.
41     _SCHEMA_STORE: Dict[str, dict] = {}
42 
43     def __len__(self) -> int:
44         return self._SCHEMA_STORE.__len__()
45 
46     def __iter__(self) -> Iterator:
47         return self._SCHEMA_STORE.__iter__()
48 
49     def __getitem__(self, key: str) -> dict:
50         """Gets the schema object for the given key."""
51         if not self._SCHEMA_STORE:
52             self._load_schemas()
53         return self._SCHEMA_STORE[key]
54 
55     @classmethod
56     def _load_schemas(cls) -> None:
57         """Loads all schemas and subschemas into the schema store for the validator to reference."""
58         for root, _, files in walk(CONFIG_SCHEMA_DIR):
59             for file_name in files:
60                 if not file_name.endswith(".json"):
61                     continue
62                 file_path = path_join(root, file_name)
63                 if path.getsize(file_path) == 0:
64                     continue
65                 with open(file_path, mode="r", encoding="utf-8") as schema_file:
66                     schema = json.load(schema_file)
67                     cls._SCHEMA_STORE[file_path] = schema
68                     # Let the schema be referenced by its id as well.
69                     assert "$id" in schema
70                     assert schema["$id"] not in cls._SCHEMA_STORE
71                     cls._SCHEMA_STORE[schema["$id"]] = schema
72 
73 
74 SCHEMA_STORE = SchemaStore()
75 
76 
77 class ConfigSchema(Enum):
78     """
79     An enum to help describe schema types and help validate configs against them.
80     """
81 
82     CLI = path_join(CONFIG_SCHEMA_DIR, "cli/cli-schema.json")
83     GLOBALS = path_join(CONFIG_SCHEMA_DIR, "cli/globals-schema.json")
84     ENVIRONMENT = path_join(CONFIG_SCHEMA_DIR, "environments/environment-schema.json")
85     OPTIMIZER = path_join(CONFIG_SCHEMA_DIR, "optimizers/optimizer-schema.json")
86     SERVICE = path_join(CONFIG_SCHEMA_DIR, "services/service-schema.json")
87     STORAGE = path_join(CONFIG_SCHEMA_DIR, "storage/storage-schema.json")
88     TUNABLE_PARAMS = path_join(CONFIG_SCHEMA_DIR, "tunables/tunable-params-schema.json")
89     TUNABLE_VALUES = path_join(CONFIG_SCHEMA_DIR, "tunables/tunable-values-schema.json")
90 
91     @property
92     def schema(self) -> dict:
93         """Gets the schema object for this type."""
94         schema = SCHEMA_STORE[self.value]
95         assert schema
96         return schema
97 
98     def validate(self, config: dict) -> None:
99         """
100         Validates the given config against this schema.
101 
102         Parameters
103         ----------
104         config : dict
105             The config to validate.
106 
107         Raises
108         ------
109         jsonschema.exceptions.ValidationError
110         jsonschema.exceptions.SchemaError
111         """
112         if _SKIP_VALIDATION:
113             _LOG.warning("%s is set - skip schema validation", _VALIDATION_ENV_FLAG)
114         else:
115             resolver: jsonschema.RefResolver = jsonschema.RefResolver.from_schema(self.schema, store=SCHEMA_STORE)
116             jsonschema.validate(instance=config, schema=self.schema, resolver=resolver)
117
```
--- 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/mlos_bench/mlos_bench/config/schemas/config_schemas.py b/mlos_bench/mlos_bench/config/schemas/config_schemas.py
--- a/mlos_bench/mlos_bench/config/schemas/config_schemas.py
+++ b/mlos_bench/mlos_bench/config/schemas/config_schemas.py
@@ -14,6 +14,9 @@
 import json         # schema files are pure json - no comments
 import jsonschema
 
+from referencing import Registry, Resource
+from referencing.jsonschema import DRAFT202012
+
 from mlos_bench.util import path_join
 
 _LOG = logging.getLogger(__name__)
@@ -39,6 +42,7 @@
 
     # A class member mapping of schema id to schema object.
     _SCHEMA_STORE: Dict[str, dict] = {}
+    _REGISTRY: Registry = Registry()
 
     def __len__(self) -> int:
         return self._SCHEMA_STORE.__len__()
@@ -55,6 +59,8 @@
     @classmethod
     def _load_schemas(cls) -> None:
         """Loads all schemas and subschemas into the schema store for the validator to reference."""
+        if cls._SCHEMA_STORE:
+            return
         for root, _, files in walk(CONFIG_SCHEMA_DIR):
             for file_name in files:
                 if not file_name.endswith(".json"):
@@ -70,6 +76,23 @@
                     assert schema["$id"] not in cls._SCHEMA_STORE
                     cls._SCHEMA_STORE[schema["$id"]] = schema
 
+    @classmethod
+    def _load_registry(cls) -> None:
+        """Also store them in a Registry object for referencing by recent versions of jsonschema."""
+        if not cls._SCHEMA_STORE:
+            cls._load_schemas()
+        cls._REGISTRY = Registry().with_resources([
+            (url, Resource.from_contents(schema, default_specification=DRAFT202012))
+            for url, schema in cls._SCHEMA_STORE.items()
+        ])
+
+    @property
+    def registry(self) -> Registry:
+        """Returns a Registry object with all the schemas loaded."""
+        if not self._REGISTRY:
+            self._load_registry()
+        return self._REGISTRY
+
 
 SCHEMA_STORE = SchemaStore()
 
@@ -112,5 +135,7 @@
         if _SKIP_VALIDATION:
             _LOG.warning("%s is set - skip schema validation", _VALIDATION_ENV_FLAG)
         else:
-            resolver: jsonschema.RefResolver = jsonschema.RefResolver.from_schema(self.schema, store=SCHEMA_STORE)
-            jsonschema.validate(instance=config, schema=self.schema, resolver=resolver)
+            jsonschema.Draft202012Validator(
+                schema=self.schema,
+                registry=SCHEMA_STORE.registry,     # type: ignore[call-arg]
+            ).validate(config)
diff --git a/mlos_bench/setup.py b/mlos_bench/setup.py
--- a/mlos_bench/setup.py
+++ b/mlos_bench/setup.py
@@ -76,7 +76,7 @@
         'mlos-core==' + _VERSION,
         'requests',
         'json5',
-        'jsonschema',
+        'jsonschema>=4.18.0', 'referencing>=0.29.1',
         'importlib_resources;python_version<"3.10"',
     ] + extra_requires['storage-sql-sqlite'],   # NOTE: For now sqlite is a fallback storage backend, so we always install it.
     extras_require=extra_requires,

{"golden_diff": "diff --git a/mlos_bench/mlos_bench/config/schemas/config_schemas.py b/mlos_bench/mlos_bench/config/schemas/config_schemas.py\n--- a/mlos_bench/mlos_bench/config/schemas/config_schemas.py\n+++ b/mlos_bench/mlos_bench/config/schemas/config_schemas.py\n@@ -14,6 +14,9 @@\n import json         # schema files are pure json - no comments\n import jsonschema\n \n+from referencing import Registry, Resource\n+from referencing.jsonschema import DRAFT202012\n+\n from mlos_bench.util import path_join\n \n _LOG = logging.getLogger(__name__)\n@@ -39,6 +42,7 @@\n \n     # A class member mapping of schema id to schema object.\n     _SCHEMA_STORE: Dict[str, dict] = {}\n+    _REGISTRY: Registry = Registry()\n \n     def __len__(self) -> int:\n         return self._SCHEMA_STORE.__len__()\n@@ -55,6 +59,8 @@\n     @classmethod\n     def _load_schemas(cls) -> None:\n         \"\"\"Loads all schemas and subschemas into the schema store for the validator to reference.\"\"\"\n+        if cls._SCHEMA_STORE:\n+            return\n         for root, _, files in walk(CONFIG_SCHEMA_DIR):\n             for file_name in files:\n                 if not file_name.endswith(\".json\"):\n@@ -70,6 +76,23 @@\n                     assert schema[\"$id\"] not in cls._SCHEMA_STORE\n                     cls._SCHEMA_STORE[schema[\"$id\"]] = schema\n \n+    @classmethod\n+    def _load_registry(cls) -> None:\n+        \"\"\"Also store them in a Registry object for referencing by recent versions of jsonschema.\"\"\"\n+        if not cls._SCHEMA_STORE:\n+            cls._load_schemas()\n+        cls._REGISTRY = Registry().with_resources([\n+            (url, Resource.from_contents(schema, default_specification=DRAFT202012))\n+            for url, schema in cls._SCHEMA_STORE.items()\n+        ])\n+\n+    @property\n+    def registry(self) -> Registry:\n+        \"\"\"Returns a Registry object with all the schemas loaded.\"\"\"\n+        if not self._REGISTRY:\n+            self._load_registry()\n+        return self._REGISTRY\n+\n \n SCHEMA_STORE = SchemaStore()\n \n@@ -112,5 +135,7 @@\n         if _SKIP_VALIDATION:\n             _LOG.warning(\"%s is set - skip schema validation\", _VALIDATION_ENV_FLAG)\n         else:\n-            resolver: jsonschema.RefResolver = jsonschema.RefResolver.from_schema(self.schema, store=SCHEMA_STORE)\n-            jsonschema.validate(instance=config, schema=self.schema, resolver=resolver)\n+            jsonschema.Draft202012Validator(\n+                schema=self.schema,\n+                registry=SCHEMA_STORE.registry,     # type: ignore[call-arg]\n+            ).validate(config)\ndiff --git a/mlos_bench/setup.py b/mlos_bench/setup.py\n--- a/mlos_bench/setup.py\n+++ b/mlos_bench/setup.py\n@@ -76,7 +76,7 @@\n         'mlos-core==' + _VERSION,\n         'requests',\n         'json5',\n-        'jsonschema',\n+        'jsonschema>=4.18.0', 'referencing>=0.29.1',\n         'importlib_resources;python_version<\"3.10\"',\n     ] + extra_requires['storage-sql-sqlite'],   # NOTE: For now sqlite is a fallback storage backend, so we always install it.\n     extras_require=extra_requires,\n", "issue": "Move to new version json schema reference resolution\nThe latest version 4.18.0 of jsonschema migrated to a new way of handling schema reference resolution that breaks our current code.  Will need to adjust it, but for now I've pinned it to the old version in #436 \r\n\r\nSee Also:\r\nhttps://python-jsonschema.readthedocs.io/en/stable/referencing/#migrating-from-refresolver\n", "before_files": [{"content": "#\n# Copyright (c) Microsoft Corporation.\n# Licensed under the MIT License.\n#\n\"\"\"\nSetup instructions for the mlos_bench package.\n\"\"\"\n\nfrom logging import warning\nfrom itertools import chain\nfrom typing import Dict, List\n\nfrom setuptools import setup, find_packages\n\nfrom _version import _VERSION    # pylint: disable=import-private-name\n\ntry:\n    from setuptools_scm import get_version\n    version = get_version(root='..', relative_to=__file__)\n    if version is not None:\n        _VERSION = version  # noqa: F811\nexcept ImportError:\n    warning(\"setuptools_scm not found, using version from _version.py\")\nexcept LookupError as e:\n    warning(f\"setuptools_scm failed to find git version, using version from _version.py: {e}\")\n\n\nextra_requires: Dict[str, List[str]] = {    # pylint: disable=consider-using-namedtuple-or-dataclass\n    # Additional tools for extra functionality.\n    'azure': ['azure-storage-file-share'],\n    'storage-sql-duckdb': ['sqlalchemy', 'duckdb_engine'],\n    'storage-sql-mysql': ['sqlalchemy', 'mysql-connector-python'],\n    'storage-sql-postgres': ['sqlalchemy', 'psycopg2'],\n    'storage-sql-sqlite': ['sqlalchemy'],   # sqlite3 comes with python, so we don't need to install it.\n    # Transitive extra_requires from mlos-core.\n    'flaml': ['flaml[blendsearch]'],\n    'smac': ['smac'],\n}\n\n# construct special 'full' extra that adds requirements for all built-in\n# backend integrations and additional extra features.\nextra_requires['full'] = list(set(chain(*extra_requires.values())))\n\nextra_requires['full-tests'] = extra_requires['full'] + [\n    'pytest',\n    'pytest-forked',\n    'pytest-xdist',\n    'pytest-cov',\n    'pytest-local-badge',\n]\n\n# pylint: disable=duplicate-code\nMODULE_BASE_NAME = 'mlos_bench'\nsetup(\n    name='mlos-bench',\n    version=_VERSION,\n    packages=find_packages(exclude=[f\"{MODULE_BASE_NAME}.tests\", f\"{MODULE_BASE_NAME}.tests.*\"]),\n    package_data={\n        '': ['py.typed', '**/*.pyi'],\n        'mlos_bench': [\n            'config/**/*.md',\n            'config/**/*.jsonc',\n            'config/**/*.json',\n            'config/**/*.py',\n            'config/**/*.sh',\n            'config/**/*.cmd',\n            'config/**/*.ps1',\n        ],\n    },\n    entry_points={\n        'console_scripts': [\n            'mlos_bench = mlos_bench.run:_main',\n        ],\n    },\n    install_requires=[\n        'mlos-core==' + _VERSION,\n        'requests',\n        'json5',\n        'jsonschema',\n        'importlib_resources;python_version<\"3.10\"',\n    ] + extra_requires['storage-sql-sqlite'],   # NOTE: For now sqlite is a fallback storage backend, so we always install it.\n    extras_require=extra_requires,\n    author='Microsoft',\n    author_email='mlos-maintainers@service.microsoft.com',\n    description=('MLOS Bench Python interface for benchmark automation and optimization.'),\n    license='MIT',\n    keywords='',\n    url='https://aka.ms/mlos-core',\n    python_requires='>=3.8',\n)\n", "path": "mlos_bench/setup.py"}, {"content": "#\n# Copyright (c) Microsoft Corporation.\n# Licensed under the MIT License.\n#\n\"\"\"\nA simple class for describing where to find different config schemas and validating configs against them.\n\"\"\"\n\nimport logging\nfrom enum import Enum\nfrom os import path, walk, environ\nfrom typing import Dict, Iterator, Mapping\n\nimport json         # schema files are pure json - no comments\nimport jsonschema\n\nfrom mlos_bench.util import path_join\n\n_LOG = logging.getLogger(__name__)\n\n# The path to find all config schemas.\nCONFIG_SCHEMA_DIR = path_join(path.dirname(__file__), abs_path=True)\n\n# Allow skipping schema validation for tight dev cycle changes.\n# It is used in `ConfigSchema.validate()` method below.\n# NOTE: this may cause pytest to fail if it's expecting exceptions\n# to be raised for invalid configs.\n_VALIDATION_ENV_FLAG = 'MLOS_BENCH_SKIP_SCHEMA_VALIDATION'\n_SKIP_VALIDATION = (environ.get(_VALIDATION_ENV_FLAG, 'false').lower()\n                    in {'true', 'y', 'yes', 'on', '1'})\n\n\n# Note: we separate out the SchemaStore from a class method on ConfigSchema\n# because of issues with mypy/pylint and non-Enum-member class members.\nclass SchemaStore(Mapping):\n    \"\"\"\n    A simple class for storing schemas and subschemas for the validator to reference.\n    \"\"\"\n\n    # A class member mapping of schema id to schema object.\n    _SCHEMA_STORE: Dict[str, dict] = {}\n\n    def __len__(self) -> int:\n        return self._SCHEMA_STORE.__len__()\n\n    def __iter__(self) -> Iterator:\n        return self._SCHEMA_STORE.__iter__()\n\n    def __getitem__(self, key: str) -> dict:\n        \"\"\"Gets the schema object for the given key.\"\"\"\n        if not self._SCHEMA_STORE:\n            self._load_schemas()\n        return self._SCHEMA_STORE[key]\n\n    @classmethod\n    def _load_schemas(cls) -> None:\n        \"\"\"Loads all schemas and subschemas into the schema store for the validator to reference.\"\"\"\n        for root, _, files in walk(CONFIG_SCHEMA_DIR):\n            for file_name in files:\n                if not file_name.endswith(\".json\"):\n                    continue\n                file_path = path_join(root, file_name)\n                if path.getsize(file_path) == 0:\n                    continue\n                with open(file_path, mode=\"r\", encoding=\"utf-8\") as schema_file:\n                    schema = json.load(schema_file)\n                    cls._SCHEMA_STORE[file_path] = schema\n                    # Let the schema be referenced by its id as well.\n                    assert \"$id\" in schema\n                    assert schema[\"$id\"] not in cls._SCHEMA_STORE\n                    cls._SCHEMA_STORE[schema[\"$id\"]] = schema\n\n\nSCHEMA_STORE = SchemaStore()\n\n\nclass ConfigSchema(Enum):\n    \"\"\"\n    An enum to help describe schema types and help validate configs against them.\n    \"\"\"\n\n    CLI = path_join(CONFIG_SCHEMA_DIR, \"cli/cli-schema.json\")\n    GLOBALS = path_join(CONFIG_SCHEMA_DIR, \"cli/globals-schema.json\")\n    ENVIRONMENT = path_join(CONFIG_SCHEMA_DIR, \"environments/environment-schema.json\")\n    OPTIMIZER = path_join(CONFIG_SCHEMA_DIR, \"optimizers/optimizer-schema.json\")\n    SERVICE = path_join(CONFIG_SCHEMA_DIR, \"services/service-schema.json\")\n    STORAGE = path_join(CONFIG_SCHEMA_DIR, \"storage/storage-schema.json\")\n    TUNABLE_PARAMS = path_join(CONFIG_SCHEMA_DIR, \"tunables/tunable-params-schema.json\")\n    TUNABLE_VALUES = path_join(CONFIG_SCHEMA_DIR, \"tunables/tunable-values-schema.json\")\n\n    @property\n    def schema(self) -> dict:\n        \"\"\"Gets the schema object for this type.\"\"\"\n        schema = SCHEMA_STORE[self.value]\n        assert schema\n        return schema\n\n    def validate(self, config: dict) -> None:\n        \"\"\"\n        Validates the given config against this schema.\n\n        Parameters\n        ----------\n        config : dict\n            The config to validate.\n\n        Raises\n        ------\n        jsonschema.exceptions.ValidationError\n        jsonschema.exceptions.SchemaError\n        \"\"\"\n        if _SKIP_VALIDATION:\n            _LOG.warning(\"%s is set - skip schema validation\", _VALIDATION_ENV_FLAG)\n        else:\n            resolver: jsonschema.RefResolver = jsonschema.RefResolver.from_schema(self.schema, store=SCHEMA_STORE)\n            jsonschema.validate(instance=config, schema=self.schema, resolver=resolver)\n", "path": "mlos_bench/mlos_bench/config/schemas/config_schemas.py"}], "after_files": [{"content": "#\n# Copyright (c) Microsoft Corporation.\n# Licensed under the MIT License.\n#\n\"\"\"\nSetup instructions for the mlos_bench package.\n\"\"\"\n\nfrom logging import warning\nfrom itertools import chain\nfrom typing import Dict, List\n\nfrom setuptools import setup, find_packages\n\nfrom _version import _VERSION    # pylint: disable=import-private-name\n\ntry:\n    from setuptools_scm import get_version\n    version = get_version(root='..', relative_to=__file__)\n    if version is not None:\n        _VERSION = version  # noqa: F811\nexcept ImportError:\n    warning(\"setuptools_scm not found, using version from _version.py\")\nexcept LookupError as e:\n    warning(f\"setuptools_scm failed to find git version, using version from _version.py: {e}\")\n\n\nextra_requires: Dict[str, List[str]] = {    # pylint: disable=consider-using-namedtuple-or-dataclass\n    # Additional tools for extra functionality.\n    'azure': ['azure-storage-file-share'],\n    'storage-sql-duckdb': ['sqlalchemy', 'duckdb_engine'],\n    'storage-sql-mysql': ['sqlalchemy', 'mysql-connector-python'],\n    'storage-sql-postgres': ['sqlalchemy', 'psycopg2'],\n    'storage-sql-sqlite': ['sqlalchemy'],   # sqlite3 comes with python, so we don't need to install it.\n    # Transitive extra_requires from mlos-core.\n    'flaml': ['flaml[blendsearch]'],\n    'smac': ['smac'],\n}\n\n# construct special 'full' extra that adds requirements for all built-in\n# backend integrations and additional extra features.\nextra_requires['full'] = list(set(chain(*extra_requires.values())))\n\nextra_requires['full-tests'] = extra_requires['full'] + [\n    'pytest',\n    'pytest-forked',\n    'pytest-xdist',\n    'pytest-cov',\n    'pytest-local-badge',\n]\n\n# pylint: disable=duplicate-code\nMODULE_BASE_NAME = 'mlos_bench'\nsetup(\n    name='mlos-bench',\n    version=_VERSION,\n    packages=find_packages(exclude=[f\"{MODULE_BASE_NAME}.tests\", f\"{MODULE_BASE_NAME}.tests.*\"]),\n    package_data={\n        '': ['py.typed', '**/*.pyi'],\n        'mlos_bench': [\n            'config/**/*.md',\n            'config/**/*.jsonc',\n            'config/**/*.json',\n            'config/**/*.py',\n            'config/**/*.sh',\n            'config/**/*.cmd',\n            'config/**/*.ps1',\n        ],\n    },\n    entry_points={\n        'console_scripts': [\n            'mlos_bench = mlos_bench.run:_main',\n        ],\n    },\n    install_requires=[\n        'mlos-core==' + _VERSION,\n        'requests',\n        'json5',\n        'jsonschema>=4.18.0', 'referencing>=0.29.1',\n        'importlib_resources;python_version<\"3.10\"',\n    ] + extra_requires['storage-sql-sqlite'],   # NOTE: For now sqlite is a fallback storage backend, so we always install it.\n    extras_require=extra_requires,\n    author='Microsoft',\n    author_email='mlos-maintainers@service.microsoft.com',\n    description=('MLOS Bench Python interface for benchmark automation and optimization.'),\n    license='MIT',\n    keywords='',\n    url='https://aka.ms/mlos-core',\n    python_requires='>=3.8',\n)\n", "path": "mlos_bench/setup.py"}, {"content": "#\n# Copyright (c) Microsoft Corporation.\n# Licensed under the MIT License.\n#\n\"\"\"\nA simple class for describing where to find different config schemas and validating configs against them.\n\"\"\"\n\nimport logging\nfrom enum import Enum\nfrom os import path, walk, environ\nfrom typing import Dict, Iterator, Mapping\n\nimport json         # schema files are pure json - no comments\nimport jsonschema\n\nfrom referencing import Registry, Resource\nfrom referencing.jsonschema import DRAFT202012\n\nfrom mlos_bench.util import path_join\n\n_LOG = logging.getLogger(__name__)\n\n# The path to find all config schemas.\nCONFIG_SCHEMA_DIR = path_join(path.dirname(__file__), abs_path=True)\n\n# Allow skipping schema validation for tight dev cycle changes.\n# It is used in `ConfigSchema.validate()` method below.\n# NOTE: this may cause pytest to fail if it's expecting exceptions\n# to be raised for invalid configs.\n_VALIDATION_ENV_FLAG = 'MLOS_BENCH_SKIP_SCHEMA_VALIDATION'\n_SKIP_VALIDATION = (environ.get(_VALIDATION_ENV_FLAG, 'false').lower()\n                    in {'true', 'y', 'yes', 'on', '1'})\n\n\n# Note: we separate out the SchemaStore from a class method on ConfigSchema\n# because of issues with mypy/pylint and non-Enum-member class members.\nclass SchemaStore(Mapping):\n    \"\"\"\n    A simple class for storing schemas and subschemas for the validator to reference.\n    \"\"\"\n\n    # A class member mapping of schema id to schema object.\n    _SCHEMA_STORE: Dict[str, dict] = {}\n    _REGISTRY: Registry = Registry()\n\n    def __len__(self) -> int:\n        return self._SCHEMA_STORE.__len__()\n\n    def __iter__(self) -> Iterator:\n        return self._SCHEMA_STORE.__iter__()\n\n    def __getitem__(self, key: str) -> dict:\n        \"\"\"Gets the schema object for the given key.\"\"\"\n        if not self._SCHEMA_STORE:\n            self._load_schemas()\n        return self._SCHEMA_STORE[key]\n\n    @classmethod\n    def _load_schemas(cls) -> None:\n        \"\"\"Loads all schemas and subschemas into the schema store for the validator to reference.\"\"\"\n        if cls._SCHEMA_STORE:\n            return\n        for root, _, files in walk(CONFIG_SCHEMA_DIR):\n            for file_name in files:\n                if not file_name.endswith(\".json\"):\n                    continue\n                file_path = path_join(root, file_name)\n                if path.getsize(file_path) == 0:\n                    continue\n                with open(file_path, mode=\"r\", encoding=\"utf-8\") as schema_file:\n                    schema = json.load(schema_file)\n                    cls._SCHEMA_STORE[file_path] = schema\n                    # Let the schema be referenced by its id as well.\n                    assert \"$id\" in schema\n                    assert schema[\"$id\"] not in cls._SCHEMA_STORE\n                    cls._SCHEMA_STORE[schema[\"$id\"]] = schema\n\n    @classmethod\n    def _load_registry(cls) -> None:\n        \"\"\"Also store them in a Registry object for referencing by recent versions of jsonschema.\"\"\"\n        if not cls._SCHEMA_STORE:\n            cls._load_schemas()\n        cls._REGISTRY = Registry().with_resources([\n            (url, Resource.from_contents(schema, default_specification=DRAFT202012))\n            for url, schema in cls._SCHEMA_STORE.items()\n        ])\n\n    @property\n    def registry(self) -> Registry:\n        \"\"\"Returns a Registry object with all the schemas loaded.\"\"\"\n        if not self._REGISTRY:\n            self._load_registry()\n        return self._REGISTRY\n\n\nSCHEMA_STORE = SchemaStore()\n\n\nclass ConfigSchema(Enum):\n    \"\"\"\n    An enum to help describe schema types and help validate configs against them.\n    \"\"\"\n\n    CLI = path_join(CONFIG_SCHEMA_DIR, \"cli/cli-schema.json\")\n    GLOBALS = path_join(CONFIG_SCHEMA_DIR, \"cli/globals-schema.json\")\n    ENVIRONMENT = path_join(CONFIG_SCHEMA_DIR, \"environments/environment-schema.json\")\n    OPTIMIZER = path_join(CONFIG_SCHEMA_DIR, \"optimizers/optimizer-schema.json\")\n    SERVICE = path_join(CONFIG_SCHEMA_DIR, \"services/service-schema.json\")\n    STORAGE = path_join(CONFIG_SCHEMA_DIR, \"storage/storage-schema.json\")\n    TUNABLE_PARAMS = path_join(CONFIG_SCHEMA_DIR, \"tunables/tunable-params-schema.json\")\n    TUNABLE_VALUES = path_join(CONFIG_SCHEMA_DIR, \"tunables/tunable-values-schema.json\")\n\n    @property\n    def schema(self) -> dict:\n        \"\"\"Gets the schema object for this type.\"\"\"\n        schema = SCHEMA_STORE[self.value]\n        assert schema\n        return schema\n\n    def validate(self, config: dict) -> None:\n        \"\"\"\n        Validates the given config against this schema.\n\n        Parameters\n        ----------\n        config : dict\n            The config to validate.\n\n        Raises\n        ------\n        jsonschema.exceptions.ValidationError\n        jsonschema.exceptions.SchemaError\n        \"\"\"\n        if _SKIP_VALIDATION:\n            _LOG.warning(\"%s is set - skip schema validation\", _VALIDATION_ENV_FLAG)\n        else:\n            jsonschema.Draft202012Validator(\n                schema=self.schema,\n                registry=SCHEMA_STORE.registry,     # type: ignore[call-arg]\n            ).validate(config)\n", "path": "mlos_bench/mlos_bench/config/schemas/config_schemas.py"}]}