Merge branch 'db' of https://github.com/logspace-ai/langflow into db
This commit is contained in:
commit
1b0c173f39
7 changed files with 86 additions and 12 deletions
|
|
@ -27,12 +27,19 @@ def get_number_of_workers(workers=None):
|
|||
return workers
|
||||
|
||||
|
||||
def update_settings(config: str, dev: bool = False, database_url: Optional[str] = None):
|
||||
def update_settings(
|
||||
config: str,
|
||||
dev: bool = False,
|
||||
database_url: Optional[str] = None,
|
||||
remove_api_keys: bool = False,
|
||||
):
|
||||
"""Update the settings from a config file."""
|
||||
if config:
|
||||
settings.update_from_yaml(config, dev=dev)
|
||||
if database_url:
|
||||
settings.update_database_url(database_url)
|
||||
settings.update_settings(database_url=database_url)
|
||||
if remove_api_keys:
|
||||
settings.update_settings(remove_api_keys=remove_api_keys)
|
||||
|
||||
|
||||
def serve_on_jcloud():
|
||||
|
|
@ -107,6 +114,9 @@ def serve(
|
|||
open_browser: bool = typer.Option(
|
||||
True, help="Open the browser after starting the server."
|
||||
),
|
||||
remove_api_keys: bool = typer.Option(
|
||||
False, help="Remove API keys from the projects saved in the database."
|
||||
),
|
||||
):
|
||||
"""
|
||||
Run the Langflow server.
|
||||
|
|
@ -132,7 +142,9 @@ def serve(
|
|||
load_dotenv(env_file)
|
||||
|
||||
configure(log_level=log_level, log_file=log_file)
|
||||
update_settings(config, dev=dev, database_url=database_url)
|
||||
update_settings(
|
||||
config, dev=dev, database_url=database_url, remove_api_keys=remove_api_keys
|
||||
)
|
||||
app = create_app()
|
||||
# get the directory of the current file
|
||||
if not path:
|
||||
|
|
|
|||
24
src/backend/langflow/api/utils.py
Normal file
24
src/backend/langflow/api/utils.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
API_WORDS = ["api", "key", "token"]
|
||||
|
||||
|
||||
def has_api_terms(word: str):
|
||||
return "api" in word and (
|
||||
"key" in word or ("token" in word and "tokens" not in word)
|
||||
)
|
||||
|
||||
|
||||
def remove_api_keys(flow: dict):
|
||||
"""Remove api keys from flow data."""
|
||||
if flow.get("data") and flow["data"].get("nodes"):
|
||||
for node in flow["data"]["nodes"]:
|
||||
node_data = node.get("data").get("node")
|
||||
template = node_data.get("template")
|
||||
for value in template.values():
|
||||
if (
|
||||
isinstance(value, dict)
|
||||
and has_api_terms(value["name"])
|
||||
and value.get("password")
|
||||
):
|
||||
value["value"] = None
|
||||
|
||||
return flow
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
from typing import List
|
||||
from uuid import UUID
|
||||
from langflow.settings import settings
|
||||
from langflow.api.utils import remove_api_keys
|
||||
from langflow.api.v1.schemas import FlowListCreate, FlowListRead
|
||||
from langflow.database.models.flow import (
|
||||
Flow,
|
||||
|
|
@ -54,10 +56,13 @@ def update_flow(
|
|||
*, session: Session = Depends(get_session), flow_id: UUID, flow: FlowUpdate
|
||||
):
|
||||
"""Update a flow."""
|
||||
|
||||
db_flow = session.get(Flow, flow_id)
|
||||
if not db_flow:
|
||||
raise HTTPException(status_code=404, detail="Flow not found")
|
||||
flow_data = flow.dict(exclude_unset=True)
|
||||
if not settings.remove_api_keys:
|
||||
flow_data = remove_api_keys(flow_data)
|
||||
for key, value in flow_data.items():
|
||||
setattr(db_flow, key, value)
|
||||
session.add(db_flow)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import os
|
||||
from typing import List, Optional
|
||||
from typing import List
|
||||
|
||||
import yaml
|
||||
from pydantic import BaseSettings, root_validator
|
||||
|
|
@ -21,6 +21,7 @@ class Settings(BaseSettings):
|
|||
utilities: List[str] = []
|
||||
dev: bool = False
|
||||
database_url: str = "sqlite:///./langflow.db"
|
||||
remove_api_keys: bool = False
|
||||
|
||||
class Config:
|
||||
validate_assignment = True
|
||||
|
|
@ -48,9 +49,10 @@ class Settings(BaseSettings):
|
|||
self.utilities = new_settings.utilities or []
|
||||
self.dev = dev
|
||||
|
||||
def update_database_url(self, database_url: Optional[str] = None):
|
||||
if database_url:
|
||||
self.database_url = database_url
|
||||
def update_settings(self, **kwargs):
|
||||
for key, value in kwargs.items():
|
||||
if hasattr(self, key):
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
def save_settings_to_yaml(settings: Settings, file_path: str):
|
||||
|
|
|
|||
|
|
@ -46,7 +46,10 @@ class LLMFrontendNode(FrontendNode):
|
|||
if field.name in SHOW_FIELDS:
|
||||
field.show = True
|
||||
|
||||
if "api" in field.name and ("key" in field.name or "token" in field.name):
|
||||
if "api" in field.name and (
|
||||
"key" in field.name
|
||||
or ("token" in field.name and "tokens" not in field.name)
|
||||
):
|
||||
field.password = True
|
||||
field.show = True
|
||||
# Required should be False to support
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ BASE_API_URL = "${window.location.protocol}//${
|
|||
window.location.host
|
||||
}/ap1/v1/predict"
|
||||
FLOW_ID = "${flowId}"
|
||||
# You can tweak the flow by adding a tweaks dictionary
|
||||
# e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}}
|
||||
TWEAKS = ${JSON.stringify(tweaks, null, 2)}
|
||||
|
||||
def run_flow(message: str, flow_id: str, tweaks: dict = None) -> dict:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import _ from "lodash";
|
||||
import _, { set } from "lodash";
|
||||
import { useContext, useRef, useState, useEffect, useCallback } from "react";
|
||||
import ReactFlow, {
|
||||
OnSelectionChangeParams,
|
||||
|
|
@ -15,6 +15,7 @@ import ReactFlow, {
|
|||
updateEdge,
|
||||
Background,
|
||||
Controls,
|
||||
NodeChange,
|
||||
} from "reactflow";
|
||||
import GenericNode from "../../../../CustomNodes/GenericNode";
|
||||
import Chat from "../../../../components/chatComponent";
|
||||
|
|
@ -43,7 +44,9 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
lastCopiedSelection,
|
||||
setLastCopiedSelection,
|
||||
tabsState,
|
||||
saveFlow
|
||||
saveFlow,
|
||||
setTabsState,
|
||||
tabId
|
||||
} = useContext(TabsContext);
|
||||
const { types, reactFlowInstance, setReactFlowInstance, templates } =
|
||||
useContext(typesContext);
|
||||
|
|
@ -145,8 +148,31 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
let newX = _.cloneDeep(x);
|
||||
return newX;
|
||||
});
|
||||
setTabsState((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
[tabId]: {
|
||||
isPending: true,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
[onEdgesChange, setNodes]
|
||||
[onEdgesChange, setNodes,setTabsState,tabId]
|
||||
);
|
||||
|
||||
const onNodesChangeMod = useCallback(
|
||||
(s: NodeChange[]) => {
|
||||
onNodesChange(s);
|
||||
setTabsState((prev) => {
|
||||
return {
|
||||
...prev,
|
||||
[tabId]: {
|
||||
isPending: true,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
[onNodesChange,setTabsState,tabId]
|
||||
);
|
||||
|
||||
const onConnect = useCallback(
|
||||
|
|
@ -345,7 +371,7 @@ export default function Page({ flow }: { flow: FlowType }) {
|
|||
onPaneMouseLeave={() => {
|
||||
setDisableCopyPaste(true);
|
||||
}}
|
||||
onNodesChange={onNodesChange}
|
||||
onNodesChange={onNodesChangeMod}
|
||||
onEdgesChange={onEdgesChangeMod}
|
||||
onConnect={onConnect}
|
||||
disableKeyboardA11y={true}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue