From 65776bcaa8178f8533c8faa6019d706671a89cd4 Mon Sep 17 00:00:00 2001 From: Alex Strick van Linschoten Date: Fri, 16 Aug 2024 16:18:55 +0200 Subject: [PATCH] Fix Hugging Face Spaces permissions (#2925) * fix docs import * fix CORS issue in docker file * update user entries for CSP env var * update docs --- docker/zenml-server-hf-spaces.Dockerfile | 3 ++ ...f_spaces_chart.png => hf-spaces-chart.png} | Bin .../deploy-using-huggingface-spaces.md | 8 ++--- src/zenml/config/server_config.py | 30 ++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) rename docs/book/.gitbook/assets/{hf_spaces_chart.png => hf-spaces-chart.png} (100%) diff --git a/docker/zenml-server-hf-spaces.Dockerfile b/docker/zenml-server-hf-spaces.Dockerfile index 1f47d9d4647..ae59b6800a3 100644 --- a/docker/zenml-server-hf-spaces.Dockerfile +++ b/docker/zenml-server-hf-spaces.Dockerfile @@ -3,6 +3,9 @@ FROM zenmldocker/zenml-server:latest ENV ZENML_ANALYTICS_OPT_IN=true ENV ZENML_SERVER_DEPLOYMENT_TYPE="hf_spaces" +# fixes iframe / CORS issue for HF deployments +ENV ZENML_SERVER_SECURE_HEADERS_CSP="frame-ancestors *;" + ################################################################################ # # CONFIGURING YOUR ZENML HF SPACES SERVER diff --git a/docs/book/.gitbook/assets/hf_spaces_chart.png b/docs/book/.gitbook/assets/hf-spaces-chart.png similarity index 100% rename from docs/book/.gitbook/assets/hf_spaces_chart.png rename to docs/book/.gitbook/assets/hf-spaces-chart.png diff --git a/docs/book/getting-started/deploying-zenml/deploy-using-huggingface-spaces.md b/docs/book/getting-started/deploying-zenml/deploy-using-huggingface-spaces.md index 7bf8b78d0f0..e37edefcf23 100644 --- a/docs/book/getting-started/deploying-zenml/deploy-using-huggingface-spaces.md +++ b/docs/book/getting-started/deploying-zenml/deploy-using-huggingface-spaces.md @@ -7,10 +7,10 @@ description: Deploying ZenML to Huggingface Spaces. A quick way to deploy ZenML and get started is to use [HuggingFace Spaces](https://huggingface.co/spaces). HuggingFace Spaces is a platform for hosting and sharing ML projects and workflows, and it also works to deploy ZenML. You can be up and running in minutes (for free) with a hosted ZenML server, so it's a good option if you want to try out ZenML without any infrastructure overhead. {% hint style="info" %} -Note that it is not recommended to use HuggingFace Spaces for production use as by default the data stored there is non-persistent and the underlying machine is not as available to you as a dedicated machine. See our [other deployment options](./README.md) if you want to use ZenML in production. +If you are planning to use HuggingFace Spaces for production use, make sure you have [persistent storage turned on](https://huggingface.co/docs/hub/en/spaces-storage) so as to prevent loss of data. See our [other deployment options](./README.md) if you want alternative options. {% endhint %} -![ZenML on HuggingFace Spaces -- default deployment](../../../.gitbook/assets/hf\_spaces\_chart.png) +![ZenML on HuggingFace Spaces -- default deployment](../../.gitbook/assets/hf-spaces-chart.png) In this diagram, you can see what the default deployment of ZenML on HuggingFace looks like. @@ -48,10 +48,6 @@ zenml connect --url '' You can also use the Direct URL in your browser to use the ZenML dashboard as a fullscreen application (i.e. without the HuggingFace Spaces wrapper around it). -{% hint style="warning" %} -The ZenML dashboard will currently not work when viewed from within the Huggingface webpage (i.e. wrapped in the main `https://huggingface.co/...` website). This is on account of a limitation in how cookies are handled between ZenML and Huggingface. You **must** view the dashboard from the 'Direct URL' (see above). -{% endhint %} - ## Extra configuration options By default, the ZenML application will be configured to use an SQLite non-persistent database. If you want to use a persistent database, you can configure this by amending the `Dockerfile` to your Space's root directory. For full details on the various parameters you can change, see [our reference documentation](deploy-with-docker.md#advanced-server-configuration-options) on configuring ZenML when deployed with Docker. diff --git a/src/zenml/config/server_config.py b/src/zenml/config/server_config.py index 06b40752cee..15be8b47075 100644 --- a/src/zenml/config/server_config.py +++ b/src/zenml/config/server_config.py @@ -381,6 +381,36 @@ def _validate_config(cls, data: Dict[str, Any]) -> Dict[str, Any]: # Revert to the default value if the header is enabled del data[k] + # Handle merging of user-defined secure_headers_csp value with the default value + if "secure_headers_csp" in data: + user_defined_csp = data["secure_headers_csp"] + if isinstance(user_defined_csp, str): + # Parse the user-defined CSP string into a dictionary + user_defined_csp_dict = {} + for directive in user_defined_csp.split(";"): + directive = directive.strip() + if directive: + key, value = directive.split(" ", 1) + user_defined_csp_dict[key] = value.strip("'\"") + + # Merge the user-defined CSP dictionary with the default CSP dictionary + default_csp_dict = {} + for directive in DEFAULT_ZENML_SERVER_SECURE_HEADERS_CSP.split( + ";" + ): + directive = directive.strip() + if directive: + key, value = directive.split(" ", 1) + default_csp_dict[key] = value.strip("'\"") + + merged_csp_dict = {**default_csp_dict, **user_defined_csp_dict} + + # Convert the merged CSP dictionary back to a string + merged_csp_str = "; ".join( + f"{key} {value}" for key, value in merged_csp_dict.items() + ) + data["secure_headers_csp"] = merged_csp_str + return data @property