From 721cefe10ebd085a64cc0777e62c99999ece55ff Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Fri, 17 Jan 2025 11:31:16 +0100 Subject: [PATCH 1/6] Format Python code with ruff --- .gitignore | 1 + .ruff.toml | 8 +++++++ contrib/data_engineering/scripts/add_asset.py | 5 ++++- .../{{.project_name}}/scripts/add_asset.py | 5 ++++- default_python/setup.py | 18 +++++++-------- default_python/src/default_python/main.py | 22 +++++++++++-------- default_python/src/dlt_pipeline.ipynb | 6 +++-- .../src/my_custom_wheel1/__init__.py | 2 ++ .../src/my_custom_wheel2/__init__.py | 2 ++ .../src/call_wheel.py | 2 +- .../private_wheel_packages/src/main.py | 4 ++-- .../src/python_wheel_poetry/hello.py | 2 ++ .../deployment/batch_inference/predict.py | 6 ++--- .../deployment/model_deployment/deploy.py | 12 ++++------ .../mlops_stacks/validation/validation.py | 5 +++-- 15 files changed, 62 insertions(+), 38 deletions(-) create mode 100644 .gitignore create mode 100644 .ruff.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b25701b2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.ruff_cache diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 00000000..08229033 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,8 @@ +[format] +exclude = [ + # Databricks notebooks with % magic commands don't parse as valid Python. + "mlops_stacks/mlops_stacks/deployment/batch_inference/notebooks/BatchInference.py", + "mlops_stacks/mlops_stacks/deployment/model_deployment/notebooks/ModelDeployment.py", + "mlops_stacks/mlops_stacks/training/notebooks/Train.py", + "mlops_stacks/mlops_stacks/validation/notebooks/ModelValidation.py", +] diff --git a/contrib/data_engineering/scripts/add_asset.py b/contrib/data_engineering/scripts/add_asset.py index 72991a81..1a20ae53 100644 --- a/contrib/data_engineering/scripts/add_asset.py +++ b/contrib/data_engineering/scripts/add_asset.py @@ -11,7 +11,10 @@ def init_bundle(asset_type: AssetType) -> None: - cmd = f"databricks bundle init https://github.com/databricks/bundle-examples --template-dir contrib/templates/data-engineering/assets/{asset_type} " + " ".join(sys.argv[2:]) + cmd = ( + f"databricks bundle init https://github.com/databricks/bundle-examples --template-dir contrib/templates/data-engineering/assets/{asset_type} " + + " ".join(sys.argv[2:]) + ) subprocess.run(cmd, shell=True) diff --git a/contrib/templates/data-engineering/template/{{.project_name}}/scripts/add_asset.py b/contrib/templates/data-engineering/template/{{.project_name}}/scripts/add_asset.py index 72991a81..1a20ae53 100644 --- a/contrib/templates/data-engineering/template/{{.project_name}}/scripts/add_asset.py +++ b/contrib/templates/data-engineering/template/{{.project_name}}/scripts/add_asset.py @@ -11,7 +11,10 @@ def init_bundle(asset_type: AssetType) -> None: - cmd = f"databricks bundle init https://github.com/databricks/bundle-examples --template-dir contrib/templates/data-engineering/assets/{asset_type} " + " ".join(sys.argv[2:]) + cmd = ( + f"databricks bundle init https://github.com/databricks/bundle-examples --template-dir contrib/templates/data-engineering/assets/{asset_type} " + + " ".join(sys.argv[2:]) + ) subprocess.run(cmd, shell=True) diff --git a/default_python/setup.py b/default_python/setup.py index 6ba5b7b4..c193bbd4 100644 --- a/default_python/setup.py +++ b/default_python/setup.py @@ -5,10 +5,12 @@ be executed directly. See README.md for how to deploy, test, and run the default_python project. """ + from setuptools import setup, find_packages import sys -sys.path.append('./src') + +sys.path.append("./src") import datetime import default_python @@ -17,17 +19,15 @@ name="default_python", # We use timestamp as Local version identifier (https://peps.python.org/pep-0440/#local-version-identifiers.) # to ensure that changes to wheel package are picked up when used on all-purpose clusters - version=default_python.__version__ + "+" + datetime.datetime.utcnow().strftime("%Y%m%d.%H%M%S"), + version=default_python.__version__ + + "+" + + datetime.datetime.utcnow().strftime("%Y%m%d.%H%M%S"), url="https://databricks.com", author="user@company.com", description="wheel file based on default_python/src", - packages=find_packages(where='./src'), - package_dir={'': 'src'}, - entry_points={ - "packages": [ - "main=default_python.main:main" - ] - }, + packages=find_packages(where="./src"), + package_dir={"": "src"}, + entry_points={"packages": ["main=default_python.main:main"]}, install_requires=[ # Dependencies in case the output wheel file is used as a library dependency. # For defining dependencies, when this package is used in Databricks, see: diff --git a/default_python/src/default_python/main.py b/default_python/src/default_python/main.py index c514c6dc..5ae344c7 100644 --- a/default_python/src/default_python/main.py +++ b/default_python/src/default_python/main.py @@ -1,21 +1,25 @@ from pyspark.sql import SparkSession, DataFrame + def get_taxis(spark: SparkSession) -> DataFrame: - return spark.read.table("samples.nyctaxi.trips") + return spark.read.table("samples.nyctaxi.trips") # Create a new Databricks Connect session. If this fails, # check that you have configured Databricks Connect correctly. # See https://docs.databricks.com/dev-tools/databricks-connect.html. def get_spark() -> SparkSession: - try: - from databricks.connect import DatabricksSession - return DatabricksSession.builder.getOrCreate() - except ImportError: - return SparkSession.builder.getOrCreate() + try: + from databricks.connect import DatabricksSession + + return DatabricksSession.builder.getOrCreate() + except ImportError: + return SparkSession.builder.getOrCreate() + def main(): - get_taxis(get_spark()).show(5) + get_taxis(get_spark()).show(5) + -if __name__ == '__main__': - main() +if __name__ == "__main__": + main() diff --git a/default_python/src/dlt_pipeline.ipynb b/default_python/src/dlt_pipeline.ipynb index 4216a065..6bd508a2 100644 --- a/default_python/src/dlt_pipeline.ipynb +++ b/default_python/src/dlt_pipeline.ipynb @@ -34,6 +34,7 @@ "# Import DLT and src/default_python\n", "import dlt\n", "import sys\n", + "\n", "sys.path.append(spark.conf.get(\"bundle.sourcePath\", \".\"))\n", "from pyspark.sql.functions import expr\n", "from default_python import main" @@ -55,11 +56,12 @@ "source": [ "@dlt.view\n", "def taxi_raw():\n", - " return main.get_taxis(spark)\n", + " return main.get_taxis(spark)\n", + "\n", "\n", "@dlt.table\n", "def filtered_taxis():\n", - " return dlt.read(\"taxi_raw\").filter(expr(\"fare_amount < 30\"))" + " return dlt.read(\"taxi_raw\").filter(expr(\"fare_amount < 30\"))" ] } ], diff --git a/knowledge_base/job_with_multiple_wheels/my_custom_wheel1/src/my_custom_wheel1/__init__.py b/knowledge_base/job_with_multiple_wheels/my_custom_wheel1/src/my_custom_wheel1/__init__.py index 79981ae4..7b614d08 100644 --- a/knowledge_base/job_with_multiple_wheels/my_custom_wheel1/src/my_custom_wheel1/__init__.py +++ b/knowledge_base/job_with_multiple_wheels/my_custom_wheel1/src/my_custom_wheel1/__init__.py @@ -3,5 +3,7 @@ """ Function to be called by [my_custom_wheel2]. """ + + def hello(): cowsay.cow("Hello, world!") diff --git a/knowledge_base/job_with_multiple_wheels/my_custom_wheel2/src/my_custom_wheel2/__init__.py b/knowledge_base/job_with_multiple_wheels/my_custom_wheel2/src/my_custom_wheel2/__init__.py index 51b098ad..02569d40 100644 --- a/knowledge_base/job_with_multiple_wheels/my_custom_wheel2/src/my_custom_wheel2/__init__.py +++ b/knowledge_base/job_with_multiple_wheels/my_custom_wheel2/src/my_custom_wheel2/__init__.py @@ -3,5 +3,7 @@ """ Function that calls into [my_custom_wheel1]. """ + + def hello(): my_custom_wheel1.hello() diff --git a/knowledge_base/job_with_multiple_wheels/src/call_wheel.py b/knowledge_base/job_with_multiple_wheels/src/call_wheel.py index 45ba8989..26a6bbab 100644 --- a/knowledge_base/job_with_multiple_wheels/src/call_wheel.py +++ b/knowledge_base/job_with_multiple_wheels/src/call_wheel.py @@ -1,4 +1,4 @@ import my_custom_wheel2 -if __name__ == '__main__': +if __name__ == "__main__": my_custom_wheel2.hello() diff --git a/knowledge_base/private_wheel_packages/src/main.py b/knowledge_base/private_wheel_packages/src/main.py index 06d5e490..ef3a0e61 100644 --- a/knowledge_base/private_wheel_packages/src/main.py +++ b/knowledge_base/private_wheel_packages/src/main.py @@ -2,5 +2,5 @@ # include an arbitrary wheel file in your bundle directory, deploy it, and use it from within your code. import cowsay -if __name__ == '__main__': - cowsay.cow('Hello, world!') +if __name__ == "__main__": + cowsay.cow("Hello, world!") diff --git a/knowledge_base/python_wheel_poetry/src/python_wheel_poetry/hello.py b/knowledge_base/python_wheel_poetry/src/python_wheel_poetry/hello.py index 5a0d7c3a..6e4200da 100644 --- a/knowledge_base/python_wheel_poetry/src/python_wheel_poetry/hello.py +++ b/knowledge_base/python_wheel_poetry/src/python_wheel_poetry/hello.py @@ -10,5 +10,7 @@ The value is the path to the function that is called when the command is run. The key is referred to in the `python_wheel_task` section in `databricks.yml`. """ + + def hello(): cowsay.cow("Hello, world!") diff --git a/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py b/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py index c08b61d2..00d311e1 100644 --- a/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py +++ b/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py @@ -11,7 +11,7 @@ def predict_batch( """ mlflow.set_registry_uri("databricks-uc") table = spark_session.table(input_table_name) - + predict = mlflow.pyfunc.spark_udf( spark_session, model_uri, result_type="string", env_manager="virtualenv" ) @@ -20,8 +20,8 @@ def predict_batch( .withColumn("model_version", lit(model_version)) .withColumn("inference_timestamp", to_timestamp(lit(ts))) ) - + output_df.display() # Model predictions are written to the Delta table provided as input. # Delta is the default format in Databricks Runtime 8.0 and above. - output_df.write.format("delta").mode("overwrite").saveAsTable(output_table_name) \ No newline at end of file + output_df.write.format("delta").mode("overwrite").saveAsTable(output_table_name) diff --git a/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py b/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py index 8dd72990..0add6e44 100644 --- a/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py +++ b/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py @@ -22,18 +22,14 @@ def deploy(model_uri, env): target_alias = "Champion" if target_alias not in mv.aliases: client.set_registered_model_alias( - name=model_name, - alias=target_alias, - version=version) + name=model_name, alias=target_alias, version=version + ) print(f"Assigned alias '{target_alias}' to model version {model_uri}.") - + # remove "Challenger" alias if assigning "Champion" alias if target_alias == "Champion" and "Challenger" in mv.aliases: print(f"Removing 'Challenger' alias from model version {model_uri}.") - client.delete_registered_model_alias( - name=model_name, - alias="Challenger") - + client.delete_registered_model_alias(name=model_name, alias="Challenger") if __name__ == "__main__": diff --git a/mlops_stacks/mlops_stacks/validation/validation.py b/mlops_stacks/mlops_stacks/validation/validation.py index ac4f2eac..ced8329d 100644 --- a/mlops_stacks/mlops_stacks/validation/validation.py +++ b/mlops_stacks/mlops_stacks/validation/validation.py @@ -1,11 +1,11 @@ import numpy as np from mlflow.models import make_metric, MetricThreshold + # Custom metrics to be included. Return empty list if custom metrics are not needed. # Please refer to custom_metrics parameter in mlflow.evaluate documentation https://mlflow.org/docs/latest/python_api/mlflow.html#mlflow.evaluate # TODO(optional) : custom_metrics def custom_metrics(): - # TODO(optional) : define custom metric function to be included in custom_metrics. def squared_diff_plus_one(eval_df, _builtin_metrics): """ @@ -23,7 +23,8 @@ def squared_diff_plus_one(eval_df, _builtin_metrics): def validation_thresholds(): return { "max_error": MetricThreshold( - threshold=500, higher_is_better=False # max_error should be <= 500 + threshold=500, + higher_is_better=False, # max_error should be <= 500 ), "mean_squared_error": MetricThreshold( threshold=20, # mean_squared_error should be <= 20 From eab04865e71a70ef1c9363979cd8ad0e9f326eba Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Fri, 17 Jan 2025 11:33:29 +0100 Subject: [PATCH 2/6] Run ruff format in workflow --- .github/workflows/fmt.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/workflows/fmt.yml diff --git a/.github/workflows/fmt.yml b/.github/workflows/fmt.yml new file mode 100644 index 00000000..0210813d --- /dev/null +++ b/.github/workflows/fmt.yml @@ -0,0 +1,23 @@ +name: fmt + +on: + pull_request: + types: [opened, synchronize] + merge_group: + types: [checks_requested] + +jobs: + ruff: + runs-on: + group: databricks-protected-runner-group + labels: linux-ubuntu-latest + + steps: + - name: Checkout repository and submodules + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Install ruff + uses: astral-sh/ruff-action@31a518504640beb4897d0b9f9e50a2a9196e75ba # v3.0.1 + with: + version: "0.9.1" + args: "format --check" From 5033784b3b4d8449a7db31b46e3127d5cee516d3 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Fri, 17 Jan 2025 11:37:31 +0100 Subject: [PATCH 3/6] Skip formatting of templates --- .ruff.toml | 10 ++++----- default_python/setup.py | 18 +++++++-------- default_python/src/default_python/main.py | 22 ++++++++----------- default_python/src/dlt_pipeline.ipynb | 6 ++--- .../deployment/batch_inference/predict.py | 6 ++--- .../deployment/model_deployment/deploy.py | 12 ++++++---- .../mlops_stacks/validation/validation.py | 5 ++--- 7 files changed, 38 insertions(+), 41 deletions(-) diff --git a/.ruff.toml b/.ruff.toml index 08229033..093fc8d9 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -1,8 +1,8 @@ [format] exclude = [ - # Databricks notebooks with % magic commands don't parse as valid Python. - "mlops_stacks/mlops_stacks/deployment/batch_inference/notebooks/BatchInference.py", - "mlops_stacks/mlops_stacks/deployment/model_deployment/notebooks/ModelDeployment.py", - "mlops_stacks/mlops_stacks/training/notebooks/Train.py", - "mlops_stacks/mlops_stacks/validation/notebooks/ModelValidation.py", + # Templates are responsible for formatting at the source. + "dbt_sql", + "default_python", + "default_sql", + "mlops_stacks", ] diff --git a/default_python/setup.py b/default_python/setup.py index c193bbd4..6ba5b7b4 100644 --- a/default_python/setup.py +++ b/default_python/setup.py @@ -5,12 +5,10 @@ be executed directly. See README.md for how to deploy, test, and run the default_python project. """ - from setuptools import setup, find_packages import sys - -sys.path.append("./src") +sys.path.append('./src') import datetime import default_python @@ -19,15 +17,17 @@ name="default_python", # We use timestamp as Local version identifier (https://peps.python.org/pep-0440/#local-version-identifiers.) # to ensure that changes to wheel package are picked up when used on all-purpose clusters - version=default_python.__version__ - + "+" - + datetime.datetime.utcnow().strftime("%Y%m%d.%H%M%S"), + version=default_python.__version__ + "+" + datetime.datetime.utcnow().strftime("%Y%m%d.%H%M%S"), url="https://databricks.com", author="user@company.com", description="wheel file based on default_python/src", - packages=find_packages(where="./src"), - package_dir={"": "src"}, - entry_points={"packages": ["main=default_python.main:main"]}, + packages=find_packages(where='./src'), + package_dir={'': 'src'}, + entry_points={ + "packages": [ + "main=default_python.main:main" + ] + }, install_requires=[ # Dependencies in case the output wheel file is used as a library dependency. # For defining dependencies, when this package is used in Databricks, see: diff --git a/default_python/src/default_python/main.py b/default_python/src/default_python/main.py index 5ae344c7..c514c6dc 100644 --- a/default_python/src/default_python/main.py +++ b/default_python/src/default_python/main.py @@ -1,25 +1,21 @@ from pyspark.sql import SparkSession, DataFrame - def get_taxis(spark: SparkSession) -> DataFrame: - return spark.read.table("samples.nyctaxi.trips") + return spark.read.table("samples.nyctaxi.trips") # Create a new Databricks Connect session. If this fails, # check that you have configured Databricks Connect correctly. # See https://docs.databricks.com/dev-tools/databricks-connect.html. def get_spark() -> SparkSession: - try: - from databricks.connect import DatabricksSession - - return DatabricksSession.builder.getOrCreate() - except ImportError: - return SparkSession.builder.getOrCreate() - + try: + from databricks.connect import DatabricksSession + return DatabricksSession.builder.getOrCreate() + except ImportError: + return SparkSession.builder.getOrCreate() def main(): - get_taxis(get_spark()).show(5) - + get_taxis(get_spark()).show(5) -if __name__ == "__main__": - main() +if __name__ == '__main__': + main() diff --git a/default_python/src/dlt_pipeline.ipynb b/default_python/src/dlt_pipeline.ipynb index 6bd508a2..4216a065 100644 --- a/default_python/src/dlt_pipeline.ipynb +++ b/default_python/src/dlt_pipeline.ipynb @@ -34,7 +34,6 @@ "# Import DLT and src/default_python\n", "import dlt\n", "import sys\n", - "\n", "sys.path.append(spark.conf.get(\"bundle.sourcePath\", \".\"))\n", "from pyspark.sql.functions import expr\n", "from default_python import main" @@ -56,12 +55,11 @@ "source": [ "@dlt.view\n", "def taxi_raw():\n", - " return main.get_taxis(spark)\n", - "\n", + " return main.get_taxis(spark)\n", "\n", "@dlt.table\n", "def filtered_taxis():\n", - " return dlt.read(\"taxi_raw\").filter(expr(\"fare_amount < 30\"))" + " return dlt.read(\"taxi_raw\").filter(expr(\"fare_amount < 30\"))" ] } ], diff --git a/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py b/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py index 00d311e1..c08b61d2 100644 --- a/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py +++ b/mlops_stacks/mlops_stacks/deployment/batch_inference/predict.py @@ -11,7 +11,7 @@ def predict_batch( """ mlflow.set_registry_uri("databricks-uc") table = spark_session.table(input_table_name) - + predict = mlflow.pyfunc.spark_udf( spark_session, model_uri, result_type="string", env_manager="virtualenv" ) @@ -20,8 +20,8 @@ def predict_batch( .withColumn("model_version", lit(model_version)) .withColumn("inference_timestamp", to_timestamp(lit(ts))) ) - + output_df.display() # Model predictions are written to the Delta table provided as input. # Delta is the default format in Databricks Runtime 8.0 and above. - output_df.write.format("delta").mode("overwrite").saveAsTable(output_table_name) + output_df.write.format("delta").mode("overwrite").saveAsTable(output_table_name) \ No newline at end of file diff --git a/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py b/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py index 0add6e44..8dd72990 100644 --- a/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py +++ b/mlops_stacks/mlops_stacks/deployment/model_deployment/deploy.py @@ -22,14 +22,18 @@ def deploy(model_uri, env): target_alias = "Champion" if target_alias not in mv.aliases: client.set_registered_model_alias( - name=model_name, alias=target_alias, version=version - ) + name=model_name, + alias=target_alias, + version=version) print(f"Assigned alias '{target_alias}' to model version {model_uri}.") - + # remove "Challenger" alias if assigning "Champion" alias if target_alias == "Champion" and "Challenger" in mv.aliases: print(f"Removing 'Challenger' alias from model version {model_uri}.") - client.delete_registered_model_alias(name=model_name, alias="Challenger") + client.delete_registered_model_alias( + name=model_name, + alias="Challenger") + if __name__ == "__main__": diff --git a/mlops_stacks/mlops_stacks/validation/validation.py b/mlops_stacks/mlops_stacks/validation/validation.py index ced8329d..ac4f2eac 100644 --- a/mlops_stacks/mlops_stacks/validation/validation.py +++ b/mlops_stacks/mlops_stacks/validation/validation.py @@ -1,11 +1,11 @@ import numpy as np from mlflow.models import make_metric, MetricThreshold - # Custom metrics to be included. Return empty list if custom metrics are not needed. # Please refer to custom_metrics parameter in mlflow.evaluate documentation https://mlflow.org/docs/latest/python_api/mlflow.html#mlflow.evaluate # TODO(optional) : custom_metrics def custom_metrics(): + # TODO(optional) : define custom metric function to be included in custom_metrics. def squared_diff_plus_one(eval_df, _builtin_metrics): """ @@ -23,8 +23,7 @@ def squared_diff_plus_one(eval_df, _builtin_metrics): def validation_thresholds(): return { "max_error": MetricThreshold( - threshold=500, - higher_is_better=False, # max_error should be <= 500 + threshold=500, higher_is_better=False # max_error should be <= 500 ), "mean_squared_error": MetricThreshold( threshold=20, # mean_squared_error should be <= 20 From 137faf1c2d798922d1607359734b25f4348bacaa Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Fri, 17 Jan 2025 11:44:58 +0100 Subject: [PATCH 4/6] Include glob in exclude pattern --- .ruff.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.ruff.toml b/.ruff.toml index 093fc8d9..6845a35c 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -1,8 +1,8 @@ [format] exclude = [ # Templates are responsible for formatting at the source. - "dbt_sql", - "default_python", - "default_sql", - "mlops_stacks", + "dbt_sql/*", + "default_python/*", + "default_sql/*", + "mlops_stacks/*", ] From 5f17c0efb4289abdd3a3cb54ad096557ff741a57 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Fri, 17 Jan 2025 11:45:51 +0100 Subject: [PATCH 5/6] Format again --- .../streamlit-app/template/{{.project_name}}/app/app.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contrib/templates/streamlit-app/template/{{.project_name}}/app/app.py b/contrib/templates/streamlit-app/template/{{.project_name}}/app/app.py index 8cec20ae..ba338ed2 100644 --- a/contrib/templates/streamlit-app/template/{{.project_name}}/app/app.py +++ b/contrib/templates/streamlit-app/template/{{.project_name}}/app/app.py @@ -5,9 +5,9 @@ import pandas as pd # Ensure environment variable is set correctly -assert os.getenv( - "DATABRICKS_WAREHOUSE_ID" -), "DATABRICKS_WAREHOUSE_ID must be set in app.yaml." +assert os.getenv("DATABRICKS_WAREHOUSE_ID"), ( + "DATABRICKS_WAREHOUSE_ID must be set in app.yaml." +) def sqlQuery(query: str) -> pd.DataFrame: From 54c73e1c8c989b4f52e26b181a496f134505ea50 Mon Sep 17 00:00:00 2001 From: Pieter Noordhuis Date: Fri, 17 Jan 2025 11:47:10 +0100 Subject: [PATCH 6/6] Install -> Run --- .github/workflows/fmt.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fmt.yml b/.github/workflows/fmt.yml index 0210813d..265ab493 100644 --- a/.github/workflows/fmt.yml +++ b/.github/workflows/fmt.yml @@ -16,7 +16,7 @@ jobs: - name: Checkout repository and submodules uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Install ruff + - name: Run ruff uses: astral-sh/ruff-action@31a518504640beb4897d0b9f9e50a2a9196e75ba # v3.0.1 with: version: "0.9.1"