Better serrver start (#461)
This commit is contained in:
commit
f9528591d9
7 changed files with 167 additions and 55 deletions
|
|
@ -1,20 +1,28 @@
|
|||
import multiprocessing
|
||||
import sys
|
||||
import time
|
||||
import httpx
|
||||
from multiprocess import Process, cpu_count # type: ignore
|
||||
import platform
|
||||
from pathlib import Path
|
||||
|
||||
from rich.panel import Panel
|
||||
from rich import box
|
||||
from rich import print as rprint
|
||||
import typer
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
|
||||
from langflow.main import create_app
|
||||
from langflow.settings import settings
|
||||
from langflow.utils.logger import configure
|
||||
from langflow.utils.logger import configure, logger
|
||||
import webbrowser
|
||||
|
||||
|
||||
app = typer.Typer()
|
||||
|
||||
|
||||
def get_number_of_workers(workers=None):
|
||||
if workers == -1:
|
||||
workers = (multiprocessing.cpu_count() * 2) + 1
|
||||
workers = (cpu_count() * 2) + 1
|
||||
return workers
|
||||
|
||||
|
||||
|
|
@ -77,10 +85,17 @@ def serve(
|
|||
timeout: int = typer.Option(60, help="Worker timeout in seconds."),
|
||||
port: int = typer.Option(7860, help="Port to listen on."),
|
||||
config: str = typer.Option("config.yaml", help="Path to the configuration file."),
|
||||
log_level: str = typer.Option("info", help="Logging level."),
|
||||
log_level: str = typer.Option("critical", help="Logging level."),
|
||||
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."),
|
||||
jcloud: bool = typer.Option(False, help="Deploy on Jina AI Cloud"),
|
||||
dev: bool = typer.Option(False, help="Run in development mode (may contain bugs)"),
|
||||
path: str = typer.Option(
|
||||
None,
|
||||
help="Path to the frontend directory containing build files. This is for development purposes only.",
|
||||
),
|
||||
open_browser: bool = typer.Option(
|
||||
True, help="Open the browser after starting the server."
|
||||
),
|
||||
):
|
||||
"""
|
||||
Run the Langflow server.
|
||||
|
|
@ -93,8 +108,11 @@ def serve(
|
|||
update_settings(config, dev=dev)
|
||||
app = create_app()
|
||||
# get the directory of the current file
|
||||
path = Path(__file__).parent
|
||||
static_files_dir = path / "frontend"
|
||||
if not path:
|
||||
frontend_path = Path(__file__).parent
|
||||
static_files_dir = frontend_path / "frontend"
|
||||
else:
|
||||
static_files_dir = Path(path)
|
||||
app.mount(
|
||||
"/",
|
||||
StaticFiles(directory=static_files_dir, html=True),
|
||||
|
|
@ -107,17 +125,74 @@ def serve(
|
|||
"timeout": timeout,
|
||||
}
|
||||
|
||||
if platform.system() in ["Darwin", "Windows"]:
|
||||
# Run using uvicorn on MacOS and Windows
|
||||
# Windows doesn't support gunicorn
|
||||
# MacOS requires an env variable to be set to use gunicorn
|
||||
import uvicorn
|
||||
webapp_process = Process(
|
||||
target=run_langflow, args=(host, port, log_level, options, app)
|
||||
)
|
||||
webapp_process.start()
|
||||
status_code = 0
|
||||
while status_code != 200:
|
||||
try:
|
||||
status_code = httpx.get(f"http://{host}:{port}").status_code
|
||||
except Exception:
|
||||
time.sleep(1)
|
||||
|
||||
uvicorn.run(app, host=host, port=port, log_level=log_level)
|
||||
else:
|
||||
from langflow.server import LangflowApplication
|
||||
print_banner(host, port)
|
||||
if open_browser:
|
||||
webbrowser.open(f"http://{host}:{port}")
|
||||
|
||||
LangflowApplication(app, options).run()
|
||||
|
||||
def print_banner(host, port):
|
||||
# console = Console()
|
||||
|
||||
word = "LangFlow"
|
||||
colors = ["#690080", "#660099", "#4d00b3", "#3300cc", "#1a00e6", "#0000ff"]
|
||||
|
||||
styled_word = ""
|
||||
|
||||
for i, char in enumerate(word):
|
||||
color = colors[i % len(colors)]
|
||||
styled_word += f"[{color}]{char}[/]"
|
||||
|
||||
# Title with emojis and gradient text
|
||||
title = (
|
||||
f"[bold]Welcome to :chains: {styled_word} [/bold]\n\n"
|
||||
f"Access [link=http://{host}:{port}]http://{host}:{port}[/link]"
|
||||
)
|
||||
info_text = (
|
||||
"Collaborate, and contribute at our "
|
||||
"[bold][link=https://github.com/logspace-ai/langflow]GitHub Repo[/link][/bold] :rocket:"
|
||||
)
|
||||
|
||||
# Create a panel with the title and the info text, and a border around it
|
||||
panel = Panel(
|
||||
f"{title}\n{info_text}", box=box.ROUNDED, border_style="blue", expand=False
|
||||
)
|
||||
|
||||
# Print the banner with a separator line before and after
|
||||
rprint(panel)
|
||||
|
||||
|
||||
def run_langflow(host, port, log_level, options, app):
|
||||
"""
|
||||
Run Langflow server on localhost
|
||||
"""
|
||||
try:
|
||||
if platform.system() in ["Darwin", "Windows"]:
|
||||
# Run using uvicorn on MacOS and Windows
|
||||
# Windows doesn't support gunicorn
|
||||
# MacOS requires an env variable to be set to use gunicorn
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run(app, host=host, port=port, log_level=log_level)
|
||||
else:
|
||||
from langflow.server import LangflowApplication
|
||||
|
||||
LangflowApplication(app, options).run()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ export default function App() {
|
|||
// Initialize state variable for the version
|
||||
const [version, setVersion] = useState("");
|
||||
useEffect(() => {
|
||||
fetch("/version")
|
||||
fetch("api/v1/version")
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
setVersion(data.version);
|
||||
|
|
|
|||
|
|
@ -89,42 +89,47 @@ export function TabsProvider({ children }: { children: ReactNode }) {
|
|||
let cookie = window.localStorage.getItem("tabsData");
|
||||
if (cookie && Object.keys(templates).length > 0) {
|
||||
let cookieObject: LangFlowState = JSON.parse(cookie);
|
||||
cookieObject.flows.forEach((flow) => {
|
||||
if (!flow.data) {
|
||||
return;
|
||||
}
|
||||
flow.data.edges.forEach((edge) => {
|
||||
edge.className = "";
|
||||
edge.style = { stroke: "#555555" };
|
||||
});
|
||||
flow.data.nodes.forEach((node) => {
|
||||
const template = templates[node.data.type];
|
||||
if (!template) {
|
||||
setErrorData({ title: `Unknown node type: ${node.data.type}` });
|
||||
try {
|
||||
cookieObject.flows.forEach((flow) => {
|
||||
if (!flow.data) {
|
||||
return;
|
||||
}
|
||||
if (Object.keys(template["template"]).length > 0) {
|
||||
node.data.node.base_classes = template["base_classes"];
|
||||
flow.data.edges.forEach((edge) => {
|
||||
if (edge.source === node.id) {
|
||||
edge.sourceHandle = edge.sourceHandle
|
||||
.split("|")
|
||||
.slice(0, 2)
|
||||
.concat(template["base_classes"])
|
||||
.join("|");
|
||||
}
|
||||
});
|
||||
node.data.node.description = template["description"];
|
||||
node.data.node.template = updateTemplate(
|
||||
template["template"] as unknown as APITemplateType,
|
||||
node.data.node.template as APITemplateType
|
||||
);
|
||||
}
|
||||
flow.data.edges.forEach((edge) => {
|
||||
edge.className = "";
|
||||
edge.style = { stroke: "#555555" };
|
||||
});
|
||||
|
||||
flow.data.nodes.forEach((node) => {
|
||||
const template = templates[node.data.type];
|
||||
if (!template) {
|
||||
setErrorData({ title: `Unknown node type: ${node.data.type}` });
|
||||
return;
|
||||
}
|
||||
if (Object.keys(template["template"]).length > 0) {
|
||||
node.data.node.base_classes = template["base_classes"];
|
||||
flow.data.edges.forEach((edge) => {
|
||||
if (edge.source === node.id) {
|
||||
edge.sourceHandle = edge.sourceHandle
|
||||
.split("|")
|
||||
.slice(0, 2)
|
||||
.concat(template["base_classes"])
|
||||
.join("|");
|
||||
}
|
||||
});
|
||||
node.data.node.description = template["description"];
|
||||
node.data.node.template = updateTemplate(
|
||||
template["template"] as unknown as APITemplateType,
|
||||
node.data.node.template as APITemplateType
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
setTabIndex(cookieObject.tabIndex);
|
||||
setFlows(cookieObject.flows);
|
||||
setId(cookieObject.id);
|
||||
setTabIndex(cookieObject.tabIndex);
|
||||
setFlows(cookieObject.flows);
|
||||
setId(cookieObject.id);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}, [templates]);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@ export async function sendAll(data: sendAllProps) {
|
|||
export async function checkCode(
|
||||
code: string
|
||||
): Promise<AxiosResponse<errorsTypeAPI>> {
|
||||
return await axios.post("api/v1/validate/code", { code });
|
||||
return await axios.post("/validate/code", { code });
|
||||
}
|
||||
|
||||
export async function checkPrompt(
|
||||
template: string
|
||||
): Promise<AxiosResponse<PromptTypeAPI>> {
|
||||
return await axios.post("api/v1/validate/prompt", { template });
|
||||
return await axios.post("/validate/prompt", { template });
|
||||
}
|
||||
|
||||
export async function getExamples(): Promise<FlowType[]> {
|
||||
|
|
@ -37,7 +37,5 @@ export async function getExamples(): Promise<FlowType[]> {
|
|||
return contentResponse.data;
|
||||
});
|
||||
|
||||
const contents = await Promise.all(contentsPromises);
|
||||
|
||||
return contents;
|
||||
return await Promise.all(contentsPromises);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue