We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[BUG]  Unable to inspect recipes in mlflow-skinny on Databricks
### Issues Policy acknowledgement

- [X] I have read and agree to submit bug reports in accordance with the [issues policy](https://www.github.com/mlflow/mlflow/blob/master/ISSUE_POLICY.md)

### Willingness to contribute

No. I cannot contribute a bug fix at this time.

### MLflow version

- mlflow: 2.4.1

### System information

- Databricks 12.2 LTS
- Python: 3.9.5

### Describe the problem

Got `TemplateNotFound: resources/recipe_dag_template.html` when trying to inspect the recipe graph in the regression example from https://github.com/mlflow/recipes-examples on Databricks.

### Tracking information

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->


### Code to reproduce issue

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->
Clone the [repo](https://github.com/mlflow/recipes-examples) but do not run `pip install -r requirements.txt`
```python
!pip install mlflow-skinny==2.4.1

from mlflow.recipes import Recipe
r = Recipe(profile="databricks")
r.clean()
r.inspect()
```

### Stack trace

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->
```python
----> 1 r.inspect()

/databricks/python_shell/dbruntime/MLWorkloadsInstrumentation/_recipes.py in patched_api(self, *args, **kwargs)
    148     def patched_api(self, *args, **kwargs):
    149         try:
--> 150             result = original_api(self, *args, **kwargs)
    151             _try_record_api_call_usage_event(
    152                 usage_logger=usage_logger,

/local_disk0/.ephemeral_nfs/envs/pythonEnv-d2d5dd11-b2e9-4385-b609-d4c5248386db/lib/python3.9/site-packages/mlflow/recipes/regression/v1/recipe.py in inspect(self, step)
    402             regression_recipe.inspect(step="transform")
    403         """
--> 404         super().inspect(step=step)

/local_disk0/.ephemeral_nfs/envs/pythonEnv-d2d5dd11-b2e9-4385-b609-d4c5248386db/lib/python3.9/site-packages/mlflow/recipes/recipe.py in inspect(self, step)
    120         self._steps = self._resolve_recipe_steps()
    121         if not step:
--> 122             display_html(html_file_path=self._get_recipe_dag_file())
    123         else:
    124             output_directory = get_step_output_path(self._recipe_root_path, step, "")

/local_disk0/.ephemeral_nfs/envs/pythonEnv-d2d5dd11-b2e9-4385-b609-d4c5248386db/lib/python3.9/site-packages/mlflow/recipes/recipe.py in _get_recipe_dag_file(self)
    186 
    187         j2_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
--> 188         recipe_dag_template = j2_env.get_template("resources/recipe_dag_template.html").render(
    189             {
    190                 "recipe_yaml_help": {

/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/environment.py in get_template(self, name, parent, globals)
   1008             name = self.join_path(name, parent)
   1009 
-> 1010         return self._load_template(name, globals)
   1011 
   1012     @internalcode

/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/environment.py in _load_template(self, name, globals)
    967                 return template
    968 
--> 969         template = self.loader.load(self, name, self.make_globals(globals))
    970 
    971         if self.cache is not None:

/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/loaders.py in load(self, environment, name, globals)
    124         # first we try to get the source for this template together
    125         # with the filename and the uptodate function.
--> 126         source, filename, uptodate = self.get_source(environment, name)
    127 
    128         # try to load the code from the bytecode cache if there is a

/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/loaders.py in get_source(self, environment, template)
    216             # Use normpath to convert Windows altsep to sep.
    217             return contents, os.path.normpath(filename), uptodate
--> 218         raise TemplateNotFound(template)
    219 
    220     def list_templates(self) -> t.List[str]:

TemplateNotFound: resources/recipe_dag_template.html
```


### Other info / logs

<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->
N/A

### What component(s) does this bug affect?

- [ ] `area/artifacts`: Artifact stores and artifact logging
- [ ] `area/build`: Build and test infrastructure for MLflow
- [ ] `area/docs`: MLflow documentation pages
- [ ] `area/examples`: Example code
- [ ] `area/model-registry`: Model Registry service, APIs, and the fluent client calls for Model Registry
- [ ] `area/models`: MLmodel format, model serialization/deserialization, flavors
- [X] `area/recipes`: Recipes, Recipe APIs, Recipe configs, Recipe Templates
- [ ] `area/projects`: MLproject format, project running backends
- [ ] `area/scoring`: MLflow Model server, model deployment tools, Spark UDFs
- [ ] `area/server-infra`: MLflow Tracking server backend
- [ ] `area/tracking`: Tracking Service, tracking client APIs, autologging

### What interface(s) does this bug affect?

- [ ] `area/uiux`: Front-end, user experience, plotting, JavaScript, JavaScript dev server
- [ ] `area/docker`: Docker use across MLflow's components, such as MLflow Projects and MLflow Models
- [ ] `area/sqlalchemy`: Use of SQLAlchemy in the Tracking Service or Model Registry
- [ ] `area/windows`: Windows support

### What language(s) does this bug affect?

- [ ] `language/r`: R APIs and clients
- [ ] `language/java`: Java APIs and clients
- [ ] `language/new`: Proposals for new client languages

### What integration(s) does this bug affect?

- [ ] `integrations/azure`: Azure and Azure ML integrations
- [ ] `integrations/sagemaker`: SageMaker integrations
- [X] `integrations/databricks`: Databricks integrations

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `setup.py`
Content:
```
1 import os
2 import logging
3 from importlib.machinery import SourceFileLoader
4 from setuptools import setup, find_packages, Command
5 
6 _MLFLOW_SKINNY_ENV_VAR = "MLFLOW_SKINNY"
7 
8 version = (
9     SourceFileLoader("mlflow.version", os.path.join("mlflow", "version.py")).load_module().VERSION
10 )
11 
12 
13 # Get a list of all files in the directory to include in our module
14 def package_files(directory):
15     """
16     Recursively collects file paths within a directory relative to the mlflow directory.
17     """
18     mlflow_dir = os.path.abspath("mlflow")
19     paths = []
20     for root, _, filenames in os.walk(directory):
21         for filename in filenames:
22             paths.append(os.path.relpath(os.path.join(root, filename), mlflow_dir))
23     return paths
24 
25 
26 def is_comment_or_empty(line):
27     stripped = line.strip()
28     return stripped == "" or stripped.startswith("#")
29 
30 
31 def remove_comments_and_empty_lines(lines):
32     return [line for line in lines if not is_comment_or_empty(line)]
33 
34 
35 # Prints out a set of paths (relative to the mlflow/ directory) of files in mlflow/server/js/build
36 # to include in the wheel, e.g. "server/js/build/index.html"
37 js_files = package_files("mlflow/server/js/build")
38 models_container_server_files = package_files("mlflow/models/container")
39 alembic_files = [
40     "store/db_migrations/alembic.ini",
41     "temporary_db_migrations_for_pre_1_users/alembic.ini",
42 ]
43 extra_files = [
44     "pypi_package_index.json",
45     "pyspark/ml/log_model_allowlist.txt",
46     "server/auth/basic_auth.ini",
47 ]
48 recipes_template_files = package_files("mlflow/recipes/resources")
49 recipes_files = package_files("mlflow/recipes/cards/templates")
50 
51 
52 """
53 Minimal requirements for the skinny MLflow client which provides a limited
54 subset of functionality such as: RESTful client functionality for Tracking and
55 Model Registry, as well as support for Project execution against local backends
56 and Databricks.
57 """
58 with open(os.path.join("requirements", "skinny-requirements.txt")) as f:
59     SKINNY_REQUIREMENTS = remove_comments_and_empty_lines(f.read().splitlines())
60 
61 
62 """
63 These are the core requirements for the complete MLflow platform, which augments
64 the skinny client functionality with support for running the MLflow Tracking
65 Server & UI. It also adds project backends such as Docker and Kubernetes among
66 other capabilities.
67 """
68 with open(os.path.join("requirements", "core-requirements.txt")) as f:
69     CORE_REQUIREMENTS = SKINNY_REQUIREMENTS + remove_comments_and_empty_lines(f.read().splitlines())
70 
71 with open(os.path.join("requirements", "gateway-requirements.txt")) as f:
72     GATEWAY_REQUIREMENTS = remove_comments_and_empty_lines(f.read().splitlines())
73 
74 _is_mlflow_skinny = bool(os.environ.get(_MLFLOW_SKINNY_ENV_VAR))
75 logging.debug("{} env var is set: {}".format(_MLFLOW_SKINNY_ENV_VAR, _is_mlflow_skinny))
76 
77 
78 class ListDependencies(Command):
79     # `python setup.py <command name>` prints out "running <command name>" by default.
80     # This logging message must be hidden by specifying `--quiet` (or `-q`) when piping the output
81     # of this command to `pip install`.
82     description = "List mlflow dependencies"
83     user_options = [
84         ("skinny", None, "List mlflow-skinny dependencies"),
85     ]
86 
87     def initialize_options(self):
88         self.skinny = False
89 
90     def finalize_options(self):
91         pass
92 
93     def run(self):
94         dependencies = SKINNY_REQUIREMENTS if self.skinny else CORE_REQUIREMENTS
95         print("\n".join(dependencies))
96 
97 
98 MINIMUM_SUPPORTED_PYTHON_VERSION = "3.8"
99 
100 
101 class MinPythonVersion(Command):
102     description = "Print out the minimum supported Python version"
103     user_options = []
104 
105     def initialize_options(self):
106         pass
107 
108     def finalize_options(self):
109         pass
110 
111     def run(self):
112         print(MINIMUM_SUPPORTED_PYTHON_VERSION)
113 
114 
115 setup(
116     name="mlflow" if not _is_mlflow_skinny else "mlflow-skinny",
117     version=version,
118     packages=find_packages(exclude=["tests", "tests.*"]),
119     package_data={
120         "mlflow": (
121             js_files
122             + models_container_server_files
123             + alembic_files
124             + extra_files
125             + recipes_template_files
126             + recipes_files
127         ),
128     }
129     if not _is_mlflow_skinny
130     # include alembic files to enable usage of the skinny client with SQL databases
131     # if users install sqlalchemy and alembic independently
132     else {"mlflow": alembic_files + extra_files},
133     install_requires=CORE_REQUIREMENTS if not _is_mlflow_skinny else SKINNY_REQUIREMENTS,
134     extras_require={
135         "extras": [
136             # Required to log artifacts and models to HDFS artifact locations
137             "pyarrow",
138             # Required to sign outgoing request with SigV4 signature
139             "requests-auth-aws-sigv4",
140             # Required to log artifacts and models to AWS S3 artifact locations
141             "boto3",
142             # Required to log artifacts and models to GCS artifact locations
143             "google-cloud-storage>=1.30.0",
144             "azureml-core>=1.2.0",
145             # Required to log artifacts to SFTP artifact locations
146             "pysftp",
147             # Required by the mlflow.projects module, when running projects against
148             # a remote Kubernetes cluster
149             "kubernetes",
150             # Required to serve models through MLServer
151             # NOTE: remove the upper version pin once protobuf is no longer pinned in mlserver
152             # Reference issue: https://github.com/SeldonIO/MLServer/issues/1089
153             "mlserver>=1.2.0,!=1.3.1",
154             "mlserver-mlflow>=1.2.0,!=1.3.1",
155             "virtualenv",
156             # Required for exporting metrics from the MLflow server to Prometheus
157             # as part of the MLflow server monitoring add-on
158             "prometheus-flask-exporter",
159         ],
160         "databricks": [
161             # Required to write model artifacts to unity catalog locations
162             "azure-storage-file-datalake>12",
163             "google-cloud-storage>=1.30.0",
164             "boto3>1",
165         ],
166         "gateway": GATEWAY_REQUIREMENTS,
167         "sqlserver": ["mlflow-dbstore"],
168         "aliyun-oss": ["aliyunstoreplugin"],
169     },
170     entry_points="""
171         [console_scripts]
172         mlflow=mlflow.cli:cli
173 
174         [mlflow.app]
175         basic-auth=mlflow.server.auth:create_app
176 
177         [mlflow.app.client]
178         basic-auth=mlflow.server.auth.client:AuthServiceClient
179     """,
180     cmdclass={
181         "dependencies": ListDependencies,
182         "min_python_version": MinPythonVersion,
183     },
184     zip_safe=False,
185     author="Databricks",
186     description="MLflow: A Platform for ML Development and Productionization",
187     long_description=open("README.rst").read()
188     if not _is_mlflow_skinny
189     else open("README_SKINNY.rst").read() + open("README.rst").read(),
190     long_description_content_type="text/x-rst",
191     license="Apache License 2.0",
192     classifiers=[
193         "Intended Audience :: Developers",
194         f"Programming Language :: Python :: {MINIMUM_SUPPORTED_PYTHON_VERSION}",
195     ],
196     keywords="ml ai databricks",
197     url="https://mlflow.org/",
198     python_requires=f">={MINIMUM_SUPPORTED_PYTHON_VERSION}",
199     project_urls={
200         "Bug Tracker": "https://github.com/mlflow/mlflow/issues",
201         "Documentation": "https://mlflow.org/docs/latest/index.html",
202         "Source Code": "https://github.com/mlflow/mlflow",
203     },
204 )
205
```
--- 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/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -112,24 +112,30 @@
         print(MINIMUM_SUPPORTED_PYTHON_VERSION)
 
 
+skinny_package_data = [
+    # include alembic files to enable usage of the skinny client with SQL databases
+    # if users install sqlalchemy and alembic independently
+    *alembic_files,
+    *extra_files,
+    *recipes_template_files,
+    *recipes_files,
+]
+
 setup(
     name="mlflow" if not _is_mlflow_skinny else "mlflow-skinny",
     version=version,
     packages=find_packages(exclude=["tests", "tests.*"]),
-    package_data={
-        "mlflow": (
-            js_files
-            + models_container_server_files
-            + alembic_files
-            + extra_files
-            + recipes_template_files
-            + recipes_files
-        ),
-    }
-    if not _is_mlflow_skinny
-    # include alembic files to enable usage of the skinny client with SQL databases
-    # if users install sqlalchemy and alembic independently
-    else {"mlflow": alembic_files + extra_files},
+    package_data=(
+        {"mlflow": skinny_package_data}
+        if _is_mlflow_skinny
+        else {
+            "mlflow": [
+                *skinny_package_data,
+                *js_files,
+                *models_container_server_files,
+            ]
+        }
+    ),
     install_requires=CORE_REQUIREMENTS if not _is_mlflow_skinny else SKINNY_REQUIREMENTS,
     extras_require={
         "extras": [

{"golden_diff": "diff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -112,24 +112,30 @@\n         print(MINIMUM_SUPPORTED_PYTHON_VERSION)\n \n \n+skinny_package_data = [\n+    # include alembic files to enable usage of the skinny client with SQL databases\n+    # if users install sqlalchemy and alembic independently\n+    *alembic_files,\n+    *extra_files,\n+    *recipes_template_files,\n+    *recipes_files,\n+]\n+\n setup(\n     name=\"mlflow\" if not _is_mlflow_skinny else \"mlflow-skinny\",\n     version=version,\n     packages=find_packages(exclude=[\"tests\", \"tests.*\"]),\n-    package_data={\n-        \"mlflow\": (\n-            js_files\n-            + models_container_server_files\n-            + alembic_files\n-            + extra_files\n-            + recipes_template_files\n-            + recipes_files\n-        ),\n-    }\n-    if not _is_mlflow_skinny\n-    # include alembic files to enable usage of the skinny client with SQL databases\n-    # if users install sqlalchemy and alembic independently\n-    else {\"mlflow\": alembic_files + extra_files},\n+    package_data=(\n+        {\"mlflow\": skinny_package_data}\n+        if _is_mlflow_skinny\n+        else {\n+            \"mlflow\": [\n+                *skinny_package_data,\n+                *js_files,\n+                *models_container_server_files,\n+            ]\n+        }\n+    ),\n     install_requires=CORE_REQUIREMENTS if not _is_mlflow_skinny else SKINNY_REQUIREMENTS,\n     extras_require={\n         \"extras\": [\n", "issue": "[BUG]  Unable to inspect recipes in mlflow-skinny on Databricks\n### Issues Policy acknowledgement\n\n- [X] I have read and agree to submit bug reports in accordance with the [issues policy](https://www.github.com/mlflow/mlflow/blob/master/ISSUE_POLICY.md)\n\n### Willingness to contribute\n\nNo. I cannot contribute a bug fix at this time.\n\n### MLflow version\n\n- mlflow: 2.4.1\n\n### System information\n\n- Databricks 12.2 LTS\r\n- Python: 3.9.5\n\n### Describe the problem\n\nGot `TemplateNotFound: resources/recipe_dag_template.html` when trying to inspect the recipe graph in the regression example from https://github.com/mlflow/recipes-examples on Databricks.\n\n### Tracking information\n\n<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->\r\n\n\n### Code to reproduce issue\n\n<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->\r\nClone the [repo](https://github.com/mlflow/recipes-examples) but do not run `pip install -r requirements.txt`\r\n```python\r\n!pip install mlflow-skinny==2.4.1\r\n\r\nfrom mlflow.recipes import Recipe\r\nr = Recipe(profile=\"databricks\")\r\nr.clean()\r\nr.inspect()\r\n```\n\n### Stack trace\n\n<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->\r\n```python\r\n----> 1 r.inspect()\r\n\r\n/databricks/python_shell/dbruntime/MLWorkloadsInstrumentation/_recipes.py in patched_api(self, *args, **kwargs)\r\n    148     def patched_api(self, *args, **kwargs):\r\n    149         try:\r\n--> 150             result = original_api(self, *args, **kwargs)\r\n    151             _try_record_api_call_usage_event(\r\n    152                 usage_logger=usage_logger,\r\n\r\n/local_disk0/.ephemeral_nfs/envs/pythonEnv-d2d5dd11-b2e9-4385-b609-d4c5248386db/lib/python3.9/site-packages/mlflow/recipes/regression/v1/recipe.py in inspect(self, step)\r\n    402             regression_recipe.inspect(step=\"transform\")\r\n    403         \"\"\"\r\n--> 404         super().inspect(step=step)\r\n\r\n/local_disk0/.ephemeral_nfs/envs/pythonEnv-d2d5dd11-b2e9-4385-b609-d4c5248386db/lib/python3.9/site-packages/mlflow/recipes/recipe.py in inspect(self, step)\r\n    120         self._steps = self._resolve_recipe_steps()\r\n    121         if not step:\r\n--> 122             display_html(html_file_path=self._get_recipe_dag_file())\r\n    123         else:\r\n    124             output_directory = get_step_output_path(self._recipe_root_path, step, \"\")\r\n\r\n/local_disk0/.ephemeral_nfs/envs/pythonEnv-d2d5dd11-b2e9-4385-b609-d4c5248386db/lib/python3.9/site-packages/mlflow/recipes/recipe.py in _get_recipe_dag_file(self)\r\n    186 \r\n    187         j2_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))\r\n--> 188         recipe_dag_template = j2_env.get_template(\"resources/recipe_dag_template.html\").render(\r\n    189             {\r\n    190                 \"recipe_yaml_help\": {\r\n\r\n/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/environment.py in get_template(self, name, parent, globals)\r\n   1008             name = self.join_path(name, parent)\r\n   1009 \r\n-> 1010         return self._load_template(name, globals)\r\n   1011 \r\n   1012     @internalcode\r\n\r\n/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/environment.py in _load_template(self, name, globals)\r\n    967                 return template\r\n    968 \r\n--> 969         template = self.loader.load(self, name, self.make_globals(globals))\r\n    970 \r\n    971         if self.cache is not None:\r\n\r\n/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/loaders.py in load(self, environment, name, globals)\r\n    124         # first we try to get the source for this template together\r\n    125         # with the filename and the uptodate function.\r\n--> 126         source, filename, uptodate = self.get_source(environment, name)\r\n    127 \r\n    128         # try to load the code from the bytecode cache if there is a\r\n\r\n/local_disk0/.ephemeral_nfs/cluster_libraries/python/lib/python3.9/site-packages/jinja2/loaders.py in get_source(self, environment, template)\r\n    216             # Use normpath to convert Windows altsep to sep.\r\n    217             return contents, os.path.normpath(filename), uptodate\r\n--> 218         raise TemplateNotFound(template)\r\n    219 \r\n    220     def list_templates(self) -> t.List[str]:\r\n\r\nTemplateNotFound: resources/recipe_dag_template.html\r\n```\r\n\n\n### Other info / logs\n\n<!-- PLEASE KEEP BACKTICKS AND CHECK PREVIEW -->\r\nN/A\n\n### What component(s) does this bug affect?\n\n- [ ] `area/artifacts`: Artifact stores and artifact logging\n- [ ] `area/build`: Build and test infrastructure for MLflow\n- [ ] `area/docs`: MLflow documentation pages\n- [ ] `area/examples`: Example code\n- [ ] `area/model-registry`: Model Registry service, APIs, and the fluent client calls for Model Registry\n- [ ] `area/models`: MLmodel format, model serialization/deserialization, flavors\n- [X] `area/recipes`: Recipes, Recipe APIs, Recipe configs, Recipe Templates\n- [ ] `area/projects`: MLproject format, project running backends\n- [ ] `area/scoring`: MLflow Model server, model deployment tools, Spark UDFs\n- [ ] `area/server-infra`: MLflow Tracking server backend\n- [ ] `area/tracking`: Tracking Service, tracking client APIs, autologging\n\n### What interface(s) does this bug affect?\n\n- [ ] `area/uiux`: Front-end, user experience, plotting, JavaScript, JavaScript dev server\n- [ ] `area/docker`: Docker use across MLflow's components, such as MLflow Projects and MLflow Models\n- [ ] `area/sqlalchemy`: Use of SQLAlchemy in the Tracking Service or Model Registry\n- [ ] `area/windows`: Windows support\n\n### What language(s) does this bug affect?\n\n- [ ] `language/r`: R APIs and clients\n- [ ] `language/java`: Java APIs and clients\n- [ ] `language/new`: Proposals for new client languages\n\n### What integration(s) does this bug affect?\n\n- [ ] `integrations/azure`: Azure and Azure ML integrations\n- [ ] `integrations/sagemaker`: SageMaker integrations\n- [X] `integrations/databricks`: Databricks integrations\n", "before_files": [{"content": "import os\nimport logging\nfrom importlib.machinery import SourceFileLoader\nfrom setuptools import setup, find_packages, Command\n\n_MLFLOW_SKINNY_ENV_VAR = \"MLFLOW_SKINNY\"\n\nversion = (\n    SourceFileLoader(\"mlflow.version\", os.path.join(\"mlflow\", \"version.py\")).load_module().VERSION\n)\n\n\n# Get a list of all files in the directory to include in our module\ndef package_files(directory):\n    \"\"\"\n    Recursively collects file paths within a directory relative to the mlflow directory.\n    \"\"\"\n    mlflow_dir = os.path.abspath(\"mlflow\")\n    paths = []\n    for root, _, filenames in os.walk(directory):\n        for filename in filenames:\n            paths.append(os.path.relpath(os.path.join(root, filename), mlflow_dir))\n    return paths\n\n\ndef is_comment_or_empty(line):\n    stripped = line.strip()\n    return stripped == \"\" or stripped.startswith(\"#\")\n\n\ndef remove_comments_and_empty_lines(lines):\n    return [line for line in lines if not is_comment_or_empty(line)]\n\n\n# Prints out a set of paths (relative to the mlflow/ directory) of files in mlflow/server/js/build\n# to include in the wheel, e.g. \"server/js/build/index.html\"\njs_files = package_files(\"mlflow/server/js/build\")\nmodels_container_server_files = package_files(\"mlflow/models/container\")\nalembic_files = [\n    \"store/db_migrations/alembic.ini\",\n    \"temporary_db_migrations_for_pre_1_users/alembic.ini\",\n]\nextra_files = [\n    \"pypi_package_index.json\",\n    \"pyspark/ml/log_model_allowlist.txt\",\n    \"server/auth/basic_auth.ini\",\n]\nrecipes_template_files = package_files(\"mlflow/recipes/resources\")\nrecipes_files = package_files(\"mlflow/recipes/cards/templates\")\n\n\n\"\"\"\nMinimal requirements for the skinny MLflow client which provides a limited\nsubset of functionality such as: RESTful client functionality for Tracking and\nModel Registry, as well as support for Project execution against local backends\nand Databricks.\n\"\"\"\nwith open(os.path.join(\"requirements\", \"skinny-requirements.txt\")) as f:\n    SKINNY_REQUIREMENTS = remove_comments_and_empty_lines(f.read().splitlines())\n\n\n\"\"\"\nThese are the core requirements for the complete MLflow platform, which augments\nthe skinny client functionality with support for running the MLflow Tracking\nServer & UI. It also adds project backends such as Docker and Kubernetes among\nother capabilities.\n\"\"\"\nwith open(os.path.join(\"requirements\", \"core-requirements.txt\")) as f:\n    CORE_REQUIREMENTS = SKINNY_REQUIREMENTS + remove_comments_and_empty_lines(f.read().splitlines())\n\nwith open(os.path.join(\"requirements\", \"gateway-requirements.txt\")) as f:\n    GATEWAY_REQUIREMENTS = remove_comments_and_empty_lines(f.read().splitlines())\n\n_is_mlflow_skinny = bool(os.environ.get(_MLFLOW_SKINNY_ENV_VAR))\nlogging.debug(\"{} env var is set: {}\".format(_MLFLOW_SKINNY_ENV_VAR, _is_mlflow_skinny))\n\n\nclass ListDependencies(Command):\n    # `python setup.py <command name>` prints out \"running <command name>\" by default.\n    # This logging message must be hidden by specifying `--quiet` (or `-q`) when piping the output\n    # of this command to `pip install`.\n    description = \"List mlflow dependencies\"\n    user_options = [\n        (\"skinny\", None, \"List mlflow-skinny dependencies\"),\n    ]\n\n    def initialize_options(self):\n        self.skinny = False\n\n    def finalize_options(self):\n        pass\n\n    def run(self):\n        dependencies = SKINNY_REQUIREMENTS if self.skinny else CORE_REQUIREMENTS\n        print(\"\\n\".join(dependencies))\n\n\nMINIMUM_SUPPORTED_PYTHON_VERSION = \"3.8\"\n\n\nclass MinPythonVersion(Command):\n    description = \"Print out the minimum supported Python version\"\n    user_options = []\n\n    def initialize_options(self):\n        pass\n\n    def finalize_options(self):\n        pass\n\n    def run(self):\n        print(MINIMUM_SUPPORTED_PYTHON_VERSION)\n\n\nsetup(\n    name=\"mlflow\" if not _is_mlflow_skinny else \"mlflow-skinny\",\n    version=version,\n    packages=find_packages(exclude=[\"tests\", \"tests.*\"]),\n    package_data={\n        \"mlflow\": (\n            js_files\n            + models_container_server_files\n            + alembic_files\n            + extra_files\n            + recipes_template_files\n            + recipes_files\n        ),\n    }\n    if not _is_mlflow_skinny\n    # include alembic files to enable usage of the skinny client with SQL databases\n    # if users install sqlalchemy and alembic independently\n    else {\"mlflow\": alembic_files + extra_files},\n    install_requires=CORE_REQUIREMENTS if not _is_mlflow_skinny else SKINNY_REQUIREMENTS,\n    extras_require={\n        \"extras\": [\n            # Required to log artifacts and models to HDFS artifact locations\n            \"pyarrow\",\n            # Required to sign outgoing request with SigV4 signature\n            \"requests-auth-aws-sigv4\",\n            # Required to log artifacts and models to AWS S3 artifact locations\n            \"boto3\",\n            # Required to log artifacts and models to GCS artifact locations\n            \"google-cloud-storage>=1.30.0\",\n            \"azureml-core>=1.2.0\",\n            # Required to log artifacts to SFTP artifact locations\n            \"pysftp\",\n            # Required by the mlflow.projects module, when running projects against\n            # a remote Kubernetes cluster\n            \"kubernetes\",\n            # Required to serve models through MLServer\n            # NOTE: remove the upper version pin once protobuf is no longer pinned in mlserver\n            # Reference issue: https://github.com/SeldonIO/MLServer/issues/1089\n            \"mlserver>=1.2.0,!=1.3.1\",\n            \"mlserver-mlflow>=1.2.0,!=1.3.1\",\n            \"virtualenv\",\n            # Required for exporting metrics from the MLflow server to Prometheus\n            # as part of the MLflow server monitoring add-on\n            \"prometheus-flask-exporter\",\n        ],\n        \"databricks\": [\n            # Required to write model artifacts to unity catalog locations\n            \"azure-storage-file-datalake>12\",\n            \"google-cloud-storage>=1.30.0\",\n            \"boto3>1\",\n        ],\n        \"gateway\": GATEWAY_REQUIREMENTS,\n        \"sqlserver\": [\"mlflow-dbstore\"],\n        \"aliyun-oss\": [\"aliyunstoreplugin\"],\n    },\n    entry_points=\"\"\"\n        [console_scripts]\n        mlflow=mlflow.cli:cli\n\n        [mlflow.app]\n        basic-auth=mlflow.server.auth:create_app\n\n        [mlflow.app.client]\n        basic-auth=mlflow.server.auth.client:AuthServiceClient\n    \"\"\",\n    cmdclass={\n        \"dependencies\": ListDependencies,\n        \"min_python_version\": MinPythonVersion,\n    },\n    zip_safe=False,\n    author=\"Databricks\",\n    description=\"MLflow: A Platform for ML Development and Productionization\",\n    long_description=open(\"README.rst\").read()\n    if not _is_mlflow_skinny\n    else open(\"README_SKINNY.rst\").read() + open(\"README.rst\").read(),\n    long_description_content_type=\"text/x-rst\",\n    license=\"Apache License 2.0\",\n    classifiers=[\n        \"Intended Audience :: Developers\",\n        f\"Programming Language :: Python :: {MINIMUM_SUPPORTED_PYTHON_VERSION}\",\n    ],\n    keywords=\"ml ai databricks\",\n    url=\"https://mlflow.org/\",\n    python_requires=f\">={MINIMUM_SUPPORTED_PYTHON_VERSION}\",\n    project_urls={\n        \"Bug Tracker\": \"https://github.com/mlflow/mlflow/issues\",\n        \"Documentation\": \"https://mlflow.org/docs/latest/index.html\",\n        \"Source Code\": \"https://github.com/mlflow/mlflow\",\n    },\n)\n", "path": "setup.py"}], "after_files": [{"content": "import os\nimport logging\nfrom importlib.machinery import SourceFileLoader\nfrom setuptools import setup, find_packages, Command\n\n_MLFLOW_SKINNY_ENV_VAR = \"MLFLOW_SKINNY\"\n\nversion = (\n    SourceFileLoader(\"mlflow.version\", os.path.join(\"mlflow\", \"version.py\")).load_module().VERSION\n)\n\n\n# Get a list of all files in the directory to include in our module\ndef package_files(directory):\n    \"\"\"\n    Recursively collects file paths within a directory relative to the mlflow directory.\n    \"\"\"\n    mlflow_dir = os.path.abspath(\"mlflow\")\n    paths = []\n    for root, _, filenames in os.walk(directory):\n        for filename in filenames:\n            paths.append(os.path.relpath(os.path.join(root, filename), mlflow_dir))\n    return paths\n\n\ndef is_comment_or_empty(line):\n    stripped = line.strip()\n    return stripped == \"\" or stripped.startswith(\"#\")\n\n\ndef remove_comments_and_empty_lines(lines):\n    return [line for line in lines if not is_comment_or_empty(line)]\n\n\n# Prints out a set of paths (relative to the mlflow/ directory) of files in mlflow/server/js/build\n# to include in the wheel, e.g. \"server/js/build/index.html\"\njs_files = package_files(\"mlflow/server/js/build\")\nmodels_container_server_files = package_files(\"mlflow/models/container\")\nalembic_files = [\n    \"store/db_migrations/alembic.ini\",\n    \"temporary_db_migrations_for_pre_1_users/alembic.ini\",\n]\nextra_files = [\n    \"pypi_package_index.json\",\n    \"pyspark/ml/log_model_allowlist.txt\",\n    \"server/auth/basic_auth.ini\",\n]\nrecipes_template_files = package_files(\"mlflow/recipes/resources\")\nrecipes_files = package_files(\"mlflow/recipes/cards/templates\")\n\n\n\"\"\"\nMinimal requirements for the skinny MLflow client which provides a limited\nsubset of functionality such as: RESTful client functionality for Tracking and\nModel Registry, as well as support for Project execution against local backends\nand Databricks.\n\"\"\"\nwith open(os.path.join(\"requirements\", \"skinny-requirements.txt\")) as f:\n    SKINNY_REQUIREMENTS = remove_comments_and_empty_lines(f.read().splitlines())\n\n\n\"\"\"\nThese are the core requirements for the complete MLflow platform, which augments\nthe skinny client functionality with support for running the MLflow Tracking\nServer & UI. It also adds project backends such as Docker and Kubernetes among\nother capabilities.\n\"\"\"\nwith open(os.path.join(\"requirements\", \"core-requirements.txt\")) as f:\n    CORE_REQUIREMENTS = SKINNY_REQUIREMENTS + remove_comments_and_empty_lines(f.read().splitlines())\n\nwith open(os.path.join(\"requirements\", \"gateway-requirements.txt\")) as f:\n    GATEWAY_REQUIREMENTS = remove_comments_and_empty_lines(f.read().splitlines())\n\n_is_mlflow_skinny = bool(os.environ.get(_MLFLOW_SKINNY_ENV_VAR))\nlogging.debug(\"{} env var is set: {}\".format(_MLFLOW_SKINNY_ENV_VAR, _is_mlflow_skinny))\n\n\nclass ListDependencies(Command):\n    # `python setup.py <command name>` prints out \"running <command name>\" by default.\n    # This logging message must be hidden by specifying `--quiet` (or `-q`) when piping the output\n    # of this command to `pip install`.\n    description = \"List mlflow dependencies\"\n    user_options = [\n        (\"skinny\", None, \"List mlflow-skinny dependencies\"),\n    ]\n\n    def initialize_options(self):\n        self.skinny = False\n\n    def finalize_options(self):\n        pass\n\n    def run(self):\n        dependencies = SKINNY_REQUIREMENTS if self.skinny else CORE_REQUIREMENTS\n        print(\"\\n\".join(dependencies))\n\n\nMINIMUM_SUPPORTED_PYTHON_VERSION = \"3.8\"\n\n\nclass MinPythonVersion(Command):\n    description = \"Print out the minimum supported Python version\"\n    user_options = []\n\n    def initialize_options(self):\n        pass\n\n    def finalize_options(self):\n        pass\n\n    def run(self):\n        print(MINIMUM_SUPPORTED_PYTHON_VERSION)\n\n\nskinny_package_data = [\n    # include alembic files to enable usage of the skinny client with SQL databases\n    # if users install sqlalchemy and alembic independently\n    *alembic_files,\n    *extra_files,\n    *recipes_template_files,\n    *recipes_files,\n]\n\nsetup(\n    name=\"mlflow\" if not _is_mlflow_skinny else \"mlflow-skinny\",\n    version=version,\n    packages=find_packages(exclude=[\"tests\", \"tests.*\"]),\n    package_data=(\n        {\"mlflow\": skinny_package_data}\n        if _is_mlflow_skinny\n        else {\n            \"mlflow\": [\n                *skinny_package_data,\n                *js_files,\n                *models_container_server_files,\n            ]\n        }\n    ),\n    install_requires=CORE_REQUIREMENTS if not _is_mlflow_skinny else SKINNY_REQUIREMENTS,\n    extras_require={\n        \"extras\": [\n            # Required to log artifacts and models to HDFS artifact locations\n            \"pyarrow\",\n            # Required to sign outgoing request with SigV4 signature\n            \"requests-auth-aws-sigv4\",\n            # Required to log artifacts and models to AWS S3 artifact locations\n            \"boto3\",\n            # Required to log artifacts and models to GCS artifact locations\n            \"google-cloud-storage>=1.30.0\",\n            \"azureml-core>=1.2.0\",\n            # Required to log artifacts to SFTP artifact locations\n            \"pysftp\",\n            # Required by the mlflow.projects module, when running projects against\n            # a remote Kubernetes cluster\n            \"kubernetes\",\n            # Required to serve models through MLServer\n            # NOTE: remove the upper version pin once protobuf is no longer pinned in mlserver\n            # Reference issue: https://github.com/SeldonIO/MLServer/issues/1089\n            \"mlserver>=1.2.0,!=1.3.1\",\n            \"mlserver-mlflow>=1.2.0,!=1.3.1\",\n            \"virtualenv\",\n            # Required for exporting metrics from the MLflow server to Prometheus\n            # as part of the MLflow server monitoring add-on\n            \"prometheus-flask-exporter\",\n        ],\n        \"databricks\": [\n            # Required to write model artifacts to unity catalog locations\n            \"azure-storage-file-datalake>12\",\n            \"google-cloud-storage>=1.30.0\",\n            \"boto3>1\",\n        ],\n        \"gateway\": GATEWAY_REQUIREMENTS,\n        \"sqlserver\": [\"mlflow-dbstore\"],\n        \"aliyun-oss\": [\"aliyunstoreplugin\"],\n    },\n    entry_points=\"\"\"\n        [console_scripts]\n        mlflow=mlflow.cli:cli\n\n        [mlflow.app]\n        basic-auth=mlflow.server.auth:create_app\n\n        [mlflow.app.client]\n        basic-auth=mlflow.server.auth.client:AuthServiceClient\n    \"\"\",\n    cmdclass={\n        \"dependencies\": ListDependencies,\n        \"min_python_version\": MinPythonVersion,\n    },\n    zip_safe=False,\n    author=\"Databricks\",\n    description=\"MLflow: A Platform for ML Development and Productionization\",\n    long_description=open(\"README.rst\").read()\n    if not _is_mlflow_skinny\n    else open(\"README_SKINNY.rst\").read() + open(\"README.rst\").read(),\n    long_description_content_type=\"text/x-rst\",\n    license=\"Apache License 2.0\",\n    classifiers=[\n        \"Intended Audience :: Developers\",\n        f\"Programming Language :: Python :: {MINIMUM_SUPPORTED_PYTHON_VERSION}\",\n    ],\n    keywords=\"ml ai databricks\",\n    url=\"https://mlflow.org/\",\n    python_requires=f\">={MINIMUM_SUPPORTED_PYTHON_VERSION}\",\n    project_urls={\n        \"Bug Tracker\": \"https://github.com/mlflow/mlflow/issues\",\n        \"Documentation\": \"https://mlflow.org/docs/latest/index.html\",\n        \"Source Code\": \"https://github.com/mlflow/mlflow\",\n    },\n)\n", "path": "setup.py"}]}