浏览代码

Add support for `ec runserver` command (#1112)

Deshraj Yadav 1 年之前
父节点
当前提交
60bbc180ba
共有 6 个文件被更改,包括 156 次插入1 次删除
  1. 35 0
      docs/get-started/full-stack.mdx
  2. 二进制
      docs/images/fullstack-chunks.png
  3. 二进制
      docs/images/fullstack.png
  4. 1 0
      docs/mint.json
  5. 119 0
      embedchain/cli.py
  6. 1 1
      pyproject.toml

+ 35 - 0
docs/get-started/full-stack.mdx

@@ -0,0 +1,35 @@
+---
+title: '💻 Full stack'
+---
+
+Embedchain provides a clean and simple cli utility that lets you create full-stack RAG applications locally with a single comand. 
+
+## Prerequisite
+
+Make sure that you have installed the following:
+- Embedchain python package (`pip install embedchain`)
+- [Node.js](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) and [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/)
+
+## Get started
+
+For the purpose of the demo, you have to set `OPENAI_API_KEY` to start with but you can choose any llm by changing the configuration easily.
+
+Now run the following command:
+
+```bash
+ec runserver
+```
+
+Once you run this command, Embedchain does the following:
+
+1. Fetch full stack template that uses FastAPI for backend, and Next.JS template for frontend
+2. Install necessary requirements
+3. Launch the frontend and backend server for you to interact with.
+
+Once you are done, visit `http://localhost:3000` and you will see a chat UI as shown below.
+
+![full stack example](/images/fullstack.png)
+
+You can navigate to [Embedchain admin panel] where  you can see the chunks created for your documents that you ingested for your RAG application. Below is a screenshot for the same:
+
+![full stack chunks](/images/fullstack-chunks.png)

二进制
docs/images/fullstack-chunks.png


二进制
docs/images/fullstack.png


+ 1 - 0
docs/mint.json

@@ -63,6 +63,7 @@
         "get-started/quickstart",
         "get-started/introduction",
         "get-started/faq",
+        "get-started/full-stack",
         {
           "group": "🔗 Integrations",
           "pages": [

+ 119 - 0
embedchain/cli.py

@@ -2,10 +2,16 @@ import json
 import os
 import re
 import shutil
+import signal
 import subprocess
+import sys
+import tempfile
+import zipfile
+from pathlib import Path
 
 import click
 import pkg_resources
+import requests
 from rich.console import Console
 
 from embedchain.telemetry.posthog import AnonymousTelemetry
@@ -21,6 +27,23 @@ def cli():
 anonymous_telemetry = AnonymousTelemetry()
 
 
+api_process = None
+ui_process = None
+
+
+def signal_handler(sig, frame):
+    """Signal handler to catch termination signals and kill server processes."""
+    global api_process, ui_process
+    console.print("\n🛑 [bold yellow]Stopping servers...[/bold yellow]")
+    if api_process:
+        api_process.terminate()
+        console.print("🛑 [bold yellow]API server stopped.[/bold yellow]")
+    if ui_process:
+        ui_process.terminate()
+        console.print("🛑 [bold yellow]UI server stopped.[/bold yellow]")
+    sys.exit(0)
+
+
 def get_pkg_path_from_name(template: str):
     try:
         # Determine the installation location of the embedchain package
@@ -414,3 +437,99 @@ def deploy():
         deploy_hf_spaces(ec_app_name)
     else:
         console.print("❌ [bold red]No recognized deployment platform found.[/bold red]")
+
+
+@cli.command()
+def runserver():
+    # Set up signal handling
+    signal.signal(signal.SIGINT, signal_handler)
+    signal.signal(signal.SIGTERM, signal_handler)
+
+    # Check if 'api' and 'ui' directories exist
+    if os.path.exists("api") and os.path.exists("ui"):
+        pass
+    else:
+        # Step 1: Download the zip file
+        zip_url = "http://github.com/embedchain/ec-admin/archive/main.zip"
+        try:
+            response = requests.get(zip_url)
+            response.raise_for_status()
+            with tempfile.NamedTemporaryFile(delete=False) as tmp_file:
+                tmp_file.write(response.content)
+                zip_file_path = tmp_file.name
+            console.print("✅ [bold green]Downloaded zip file successfully.[/bold green]")
+        except requests.RequestException as e:
+            console.print(f"❌ [bold red]Failed to download zip file: {e}[/bold red]")
+            return
+
+        # Step 2: Extract the zip file
+        try:
+            with zipfile.ZipFile(zip_file_path, "r") as zip_ref:
+                # Get the name of the root directory inside the zip file
+                root_dir = Path(zip_ref.namelist()[0])
+                for member in zip_ref.infolist():
+                    # Build the path to extract the file to, skipping the root directory
+                    target_file = Path(member.filename).relative_to(root_dir)
+                    source_file = zip_ref.open(member, "r")
+                    if member.is_dir():
+                        # Create directory if it doesn't exist
+                        os.makedirs(target_file, exist_ok=True)
+                    else:
+                        with open(target_file, "wb") as file:
+                            # Write the file
+                            shutil.copyfileobj(source_file, file)
+                console.print("✅ [bold green]Extracted zip file successfully.[/bold green]")
+        except zipfile.BadZipFile:
+            console.print("❌ [bold red]Error in extracting zip file. The file might be corrupted.[/bold red]")
+            return
+
+        # Step 3: Install API requirements
+        try:
+            os.chdir("api")
+            subprocess.run(["pip", "install", "-r", "requirements.txt"], check=True)
+            os.chdir("..")
+            console.print("✅ [bold green]Installed API requirements successfully.[/bold green]")
+        except Exception as e:
+            console.print(f"❌ [bold red]Failed to install API requirements: {e}[/bold red]")
+            return
+
+    # Step 4: Start the API server
+    try:
+        os.chdir("api")
+        api_process = subprocess.Popen(
+            ["uvicorn", "main:app", "--reload", "--host", "127.0.0.1", "--port", "8000"], stdout=None, stderr=None
+        )
+        os.chdir("..")
+        console.print("✅ [bold green]API server started successfully.[/bold green]")
+    except Exception as e:
+        console.print(f"❌ [bold red]Failed to start the API server: {e}[/bold red]")
+        return
+
+    # Step 5: Install UI requirements and start the UI server
+    try:
+        os.chdir("ui")
+        subprocess.run(["yarn"], check=True)
+        ui_process = subprocess.Popen(["yarn", "dev"], stdout=None, stderr=None)
+        console.print("✅ [bold green]UI server started successfully.[/bold green]")
+    except Exception as e:
+        console.print(f"❌ [bold red]Failed to start the UI server: {e}[/bold red]")
+
+    # Wait for the subprocesses to complete
+    api_process.wait()
+    ui_process.wait()
+
+    # Step 6: Install UI requirements and start the UI server
+    try:
+        os.chdir("ui")
+        subprocess.run(["yarn"], check=True)
+        subprocess.Popen(["yarn", "dev"])
+        console.print("✅ [bold green]UI server started successfully.[/bold green]")
+    except Exception as e:
+        console.print(f"❌ [bold red]Failed to start the UI server: {e}[/bold red]")
+
+    # Keep the script running until it receives a kill signal
+    try:
+        api_process.wait()
+        ui_process.wait()
+    except KeyboardInterrupt:
+        console.print("\n🛑 [bold yellow]Stopping server...[/bold yellow]")

+ 1 - 1
pyproject.toml

@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "embedchain"
-version = "0.1.51"
+version = "0.1.52"
 description = "Data platform for LLMs - Load, index, retrieve and sync any unstructured data"
 authors = [
     "Taranjeet Singh <taranjeet@embedchain.ai>",