Chainlit / chainlit

Build Conversational AI in minutes ⚡️
https://docs.chainlit.io
Apache License 2.0
7.1k stars 931 forks source link

Build frontend as part of backend build #1224

Open dokterbob opened 2 months ago

dokterbob commented 2 months ago

Is your feature request related to a problem? An increasing amount of users are using mount_chainlit() to deploy from within another FastAPI app.

Some of them are running into issues with dependencies (#731 #950) and many of them (including the undersigned) want to make improvements or changes and test them locally.

As it stands, the Python package can be installed from a subdirectory (e.g. poetry add git+https://github.com/myorg/mypackage_with_subdirs.git@main#subdirectory=subdir) but in this case it seems that the frontend is not distributed alongside the package as it would be for PyPI.

Describe the solution you'd like Ideally, I would suggest that the Python install automatically builds the frontend on install. Alternatively, we should at least have instructions on how to proceed in such a case.

Approaches

Build on install

It's not evidently clear how to call arbitrary code (like pnpm run buildUi to build the frontend) during the Python package installation process, especially not when installing as editable/from source.

Example: https://sam.hooke.me/note/2023/08/poetry-build-py-example/

Build on first launch

One approach might be to build the frontend on first application launch.

We'd check for existence of the frontend dir and if not, we build.

Package frontend separately

Another could be to package the frontend as a separate (binary/blob) type of dependency, so that it can be separately installed.

An example of this: https://pypi.org/project/vite-project/ (source: https://github.com/itayB/vite-project)

Resources/references https://discuss.python.org/t/running-custom-code-on-package-install/16160/2

dokterbob commented 2 months ago

Based on my research, we should be able to do this with a builds script, as follows (untested):

pyproject.toml:

[build-system]
requires = ["poetry-core", "setuptools"]

[tool.poetry.build]
script = "scripts/build_frontend.py"
generate-setup-file = true

build_frontend.py:

import subprocess
import sys

def build_frontend():
    try:
        subprocess.run(["npm", "install"], cwd="src/your_package/frontend", check=True)
        subprocess.run(["npm", "run", "build"], cwd="src/your_package/frontend", check=True)
    except subprocess.CalledProcessError:
        print("Error: Failed to build frontend. Make sure Node.js and npm are installed.")
        sys.exit(1)
    except FileNotFoundError:
        print("Error: Node.js or npm not found. Please install Node.js to build the frontend.")
        sys.exit(1)

if __name__ == "__main__":
    build_frontend()

Reference: https://github.com/python-poetry/poetry/issues/2740#issuecomment-1668981210