From 5300189e729df23e25086bb2dfdb3cf9c167faf0 Mon Sep 17 00:00:00 2001 From: 131 <11222509+Netrvin@users.noreply.github.com> Date: Tue, 12 Mar 2024 23:04:52 +0800 Subject: [PATCH] Add custom frontend build (#783) - Use the `custom_build` to set the relative path for the custom build. - The `custom_build` path should contain a `./frontend/dist/index.html` file that will be load when users load the chainlit app url. - This `index.html` can contain any custom frontend, you're responsible for providing the full ui. --- backend/chainlit/config.py | 6 ++ backend/chainlit/server.py | 5 +- .../e2e/custom_build/.chainlit/config.toml | 101 ++++++++++++++++++ cypress/e2e/custom_build/main.py | 6 ++ cypress/e2e/custom_build/public/.gitignore | 2 + .../build/frontend/dist/assets/.PLACEHOLDER | 0 .../public/build/frontend/dist/index.html | 8 ++ cypress/e2e/custom_build/spec.cy.ts | 11 ++ 8 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 cypress/e2e/custom_build/.chainlit/config.toml create mode 100644 cypress/e2e/custom_build/main.py create mode 100644 cypress/e2e/custom_build/public/.gitignore create mode 100644 cypress/e2e/custom_build/public/build/frontend/dist/assets/.PLACEHOLDER create mode 100644 cypress/e2e/custom_build/public/build/frontend/dist/index.html create mode 100644 cypress/e2e/custom_build/spec.cy.ts diff --git a/backend/chainlit/config.py b/backend/chainlit/config.py index f56b96ca7a..d9d8d9a9ae 100644 --- a/backend/chainlit/config.py +++ b/backend/chainlit/config.py @@ -108,6 +108,11 @@ # Specify a custom font url. # custom_font = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" +# Specify a custom build directory for the frontend. +# This can be used to customize the frontend code. +# Be careful: If this is a relative path, it should not start with a slash. +# custom_build = "./public/build" + # Override default MUI light theme. (Check theme.ts) [UI.theme] #font_family = "Inter, sans-serif" @@ -204,6 +209,7 @@ class UISettings(DataClassJsonMixin): custom_css: Optional[str] = None custom_js: Optional[str] = None custom_font: Optional[str] = None + custom_build: Optional[str] = None @dataclass() diff --git a/backend/chainlit/server.py b/backend/chainlit/server.py index 6cafb597a5..bb08986b24 100644 --- a/backend/chainlit/server.py +++ b/backend/chainlit/server.py @@ -139,7 +139,10 @@ async def watch_files_for_changes(): def get_build_dir(local_target: str, packaged_target: str): local_build_dir = os.path.join(PACKAGE_ROOT, local_target, "dist") packaged_build_dir = os.path.join(BACKEND_ROOT, packaged_target, "dist") - if os.path.exists(local_build_dir): + + if config.ui.custom_build and os.path.exists(os.path.join(APP_ROOT, config.ui.custom_build, packaged_target, "dist")): + return os.path.join(APP_ROOT, config.ui.custom_build, packaged_target, "dist") + elif os.path.exists(local_build_dir): return local_build_dir elif os.path.exists(packaged_build_dir): return packaged_build_dir diff --git a/cypress/e2e/custom_build/.chainlit/config.toml b/cypress/e2e/custom_build/.chainlit/config.toml new file mode 100644 index 0000000000..639be07a76 --- /dev/null +++ b/cypress/e2e/custom_build/.chainlit/config.toml @@ -0,0 +1,101 @@ +[project] +# Whether to enable telemetry (default: true). No personal data is collected. +enable_telemetry = true + + +# List of environment variables to be provided by each user to use the app. +user_env = [] + +# Duration (in seconds) during which the session is saved when the connection is lost +session_timeout = 3600 + +# Enable third parties caching (e.g LangChain cache) +cache = false + +# Authorized origins +allow_origins = ["*"] + +# Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317) +# follow_symlink = false + +[features] +# Show the prompt playground +prompt_playground = true + +# Process and display HTML in messages. This can be a security risk (see https://stackoverflow.com/questions/19603097/why-is-it-dangerous-to-render-user-generated-html-or-javascript) +unsafe_allow_html = false + +# Process and display mathematical expressions. This can clash with "$" characters in messages. +latex = false + +# Authorize users to upload files with messages +multi_modal = true + +# Allows user to use speech to text +[features.speech_to_text] + enabled = false + # See all languages here https://github.com/JamesBrill/react-speech-recognition/blob/HEAD/docs/API.md#language-string + # language = "en-US" + +[UI] +# Name of the app and chatbot. +name = "Chatbot" + +# Show the readme while the thread is empty. +show_readme_as_default = true + +# Description of the app and chatbot. This is used for HTML tags. +# description = "" + +# Large size content are by default collapsed for a cleaner ui +default_collapse_content = true + +# The default value for the expand messages settings. +default_expand_messages = false + +# Hide the chain of thought details from the user in the UI. +hide_cot = false + +# Link to your github repo. This will add a github button in the UI's header. +# github = "" + +# Specify a CSS file that can be used to customize the user interface. +# The CSS file can be served from the public directory or via an external link. +# custom_css = "/public/test.css" + +# Specify a Javascript file that can be used to customize the user interface. +# The Javascript file can be served from the public directory. +# custom_js = "/public/test.js" + +# Specify a custom font url. +# custom_font = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" + +# Specify a custom build directory for the frontend. +# This can be used to customize the frontend code. +custom_build = "./public/build" + +# Override default MUI light theme. (Check theme.ts) +[UI.theme] + #font_family = "Inter, sans-serif" +[UI.theme.light] + #background = "#FAFAFA" + #paper = "#FFFFFF" + + [UI.theme.light.primary] + #main = "#F80061" + #dark = "#980039" + #light = "#FFE7EB" + +# Override default MUI dark theme. (Check theme.ts) +[UI.theme.dark] + #background = "#FAFAFA" + #paper = "#FFFFFF" + + [UI.theme.dark.primary] + #main = "#F80061" + #dark = "#980039" + #light = "#FFE7EB" + + +[meta] +generated_by = "1.0.301" \ No newline at end of file diff --git a/cypress/e2e/custom_build/main.py b/cypress/e2e/custom_build/main.py new file mode 100644 index 0000000000..6df413bcaf --- /dev/null +++ b/cypress/e2e/custom_build/main.py @@ -0,0 +1,6 @@ +import chainlit as cl + + +@cl.on_chat_start +async def main(): + await cl.Message(content="Hello!").send() diff --git a/cypress/e2e/custom_build/public/.gitignore b/cypress/e2e/custom_build/public/.gitignore new file mode 100644 index 0000000000..23886d7c19 --- /dev/null +++ b/cypress/e2e/custom_build/public/.gitignore @@ -0,0 +1,2 @@ +!build +!dist \ No newline at end of file diff --git a/cypress/e2e/custom_build/public/build/frontend/dist/assets/.PLACEHOLDER b/cypress/e2e/custom_build/public/build/frontend/dist/assets/.PLACEHOLDER new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cypress/e2e/custom_build/public/build/frontend/dist/index.html b/cypress/e2e/custom_build/public/build/frontend/dist/index.html new file mode 100644 index 0000000000..bf39c8566a --- /dev/null +++ b/cypress/e2e/custom_build/public/build/frontend/dist/index.html @@ -0,0 +1,8 @@ + + + Custom Build + + +

This is a test page for custom build configuration.

+ + \ No newline at end of file diff --git a/cypress/e2e/custom_build/spec.cy.ts b/cypress/e2e/custom_build/spec.cy.ts new file mode 100644 index 0000000000..88bb249f87 --- /dev/null +++ b/cypress/e2e/custom_build/spec.cy.ts @@ -0,0 +1,11 @@ +import { runTestServer } from "../../support/testUtils"; + +describe("Custom Build", () => { + before(() => { + runTestServer(); + }); + + it("should correctly serve the custom build page", () => { + cy.get("body").contains("This is a test page for custom build configuration."); + }); +});