Merge branch 'dev' into docs-cli-commands
This commit is contained in:
commit
964afd3de4
177 changed files with 1636 additions and 1683 deletions
|
|
@ -9,7 +9,7 @@ The `NotionUserList` component retrieves users from Notion. It provides a conven
|
|||
|
||||
[Notion Reference](https://developers.notion.com/reference/get-users)
|
||||
|
||||
The `NotionUserList` component enables you to:
|
||||
The `NotionUserList` component enables you to:
|
||||
|
||||
- Retrieve user data from Notion
|
||||
- Access user information such as ID, type, name, and avatar URL
|
||||
|
|
|
|||
|
|
@ -71,9 +71,7 @@ async def login_to_get_access_token(
|
|||
|
||||
@router.get("/auto_login")
|
||||
async def auto_login(
|
||||
response: Response,
|
||||
db: Session = Depends(get_session),
|
||||
settings_service=Depends(get_settings_service)
|
||||
response: Response, db: Session = Depends(get_session), settings_service=Depends(get_settings_service)
|
||||
):
|
||||
auth_settings = settings_service.auth_settings
|
||||
if settings_service.auth_settings.AUTO_LOGIN:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
from typing import List, Optional
|
||||
from uuid import UUID
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
|
||||
from langflow.services.deps import get_monitor_service
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ def read_text_file(file_path: str) -> str:
|
|||
with open(file_path, "rb") as f:
|
||||
raw_data = f.read()
|
||||
result = chardet.detect(raw_data)
|
||||
encoding = result['encoding']
|
||||
encoding = result["encoding"]
|
||||
|
||||
with open(file_path, "r", encoding=encoding) as f:
|
||||
return f.read()
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@ async def run_flow(
|
|||
|
||||
fallback_to_env_vars = get_settings_service().settings.fallback_to_env_var
|
||||
|
||||
return await graph.arun(inputs_list, inputs_components=inputs_components, types=types, fallback_to_env_vars=fallback_to_env_vars)
|
||||
return await graph.arun(
|
||||
inputs_list, inputs_components=inputs_components, types=types, fallback_to_env_vars=fallback_to_env_vars
|
||||
)
|
||||
|
||||
|
||||
def generate_function_for_flow(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from langflow.services.database.models.user.crud import get_user_by_username
|
|||
from langflow.services.deps import get_settings_service, session_scope
|
||||
|
||||
from langflow.services.database.models.folder.utils import create_default_folder_if_it_doesnt_exist
|
||||
from langflow.services.deps import get_settings_service, session_scope, get_variable_service
|
||||
from langflow.services.deps import get_variable_service
|
||||
|
||||
|
||||
STARTER_FOLDER_NAME = "Starter Projects"
|
||||
|
|
@ -221,6 +221,7 @@ def _is_valid_uuid(val):
|
|||
return False
|
||||
return str(uuid_obj) == val
|
||||
|
||||
|
||||
def load_flows_from_directory():
|
||||
settings_service = get_settings_service()
|
||||
flows_path = settings_service.settings.load_flows_path
|
||||
|
|
@ -262,6 +263,7 @@ def load_flows_from_directory():
|
|||
session.add(flow)
|
||||
session.commit()
|
||||
|
||||
|
||||
def find_existing_flow(session, flow_id, flow_endpoint_name):
|
||||
if flow_endpoint_name:
|
||||
stmt = select(Flow).where(Flow.endpoint_name == flow_endpoint_name)
|
||||
|
|
@ -271,6 +273,8 @@ def find_existing_flow(session, flow_id, flow_endpoint_name):
|
|||
if existing := session.exec(stmt).first():
|
||||
return existing
|
||||
return None
|
||||
|
||||
|
||||
def create_or_update_starter_projects():
|
||||
components_paths = get_settings_service().settings.components_path
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ async def run_graph_internal(
|
|||
outputs or [],
|
||||
stream=stream,
|
||||
session_id=session_id_str or "",
|
||||
fallback_to_env_vars=fallback_to_env_vars
|
||||
fallback_to_env_vars=fallback_to_env_vars,
|
||||
)
|
||||
if session_id_str and session_service:
|
||||
await session_service.update_session(session_id_str, (graph, artifacts))
|
||||
|
|
|
|||
|
|
@ -215,10 +215,7 @@ def create_user_longterm_token(db: Session = Depends(get_session)) -> tuple[UUID
|
|||
username = settings_service.auth_settings.SUPERUSER
|
||||
super_user = get_user_by_username(db, username)
|
||||
if not super_user:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Super user hasn't been created"
|
||||
)
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Super user hasn't been created")
|
||||
access_token_expires_longterm = timedelta(days=365)
|
||||
access_token = create_token(
|
||||
data={"sub": str(super_user.id)},
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class ApiKeyRead(ApiKeyBase):
|
|||
id: UUID
|
||||
api_key: str = Field(schema_extra={"validate_default": True})
|
||||
user_id: UUID = Field()
|
||||
created_at: datetime = Field()
|
||||
|
||||
@field_validator("api_key")
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -115,7 +115,9 @@ class MonitorService(Service):
|
|||
return self.exec_query(query)
|
||||
|
||||
def update_message(self, message_id: int, **kwargs):
|
||||
query = f"""UPDATE messages SET {', '.join(f"{k} = '{v}'" for k, v in kwargs.items())} WHERE index = {message_id}"""
|
||||
query = (
|
||||
f"""UPDATE messages SET {', '.join(f"{k} = '{v}'" for k, v in kwargs.items())} WHERE index = {message_id}"""
|
||||
)
|
||||
|
||||
return self.exec_query(query)
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ class Settings(BaseSettings):
|
|||
langchain_cache: str = "InMemoryCache"
|
||||
load_flows_path: Optional[str] = None
|
||||
|
||||
|
||||
# Redis
|
||||
redis_host: str = "localhost"
|
||||
redis_port: int = 6379
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import os
|
||||
from typing import Optional
|
||||
|
||||
import yaml
|
||||
from loguru import logger
|
||||
|
|
@ -8,6 +7,7 @@ from langflow.services.base import Service
|
|||
from langflow.services.settings.auth import AuthSettings
|
||||
from langflow.services.settings.base import Settings
|
||||
|
||||
|
||||
class SettingsService(Service):
|
||||
name = "settings_service"
|
||||
|
||||
|
|
|
|||
18
src/frontend/package-lock.json
generated
18
src/frontend/package-lock.json
generated
|
|
@ -44,6 +44,7 @@
|
|||
"debounce-promise": "^3.1.2",
|
||||
"dompurify": "^3.0.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"emoji-regex": "^10.3.0",
|
||||
"esbuild": "^0.17.19",
|
||||
"file-saver": "^2.0.5",
|
||||
"framer-motion": "^11.0.6",
|
||||
|
|
@ -479,6 +480,7 @@
|
|||
},
|
||||
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
|
||||
"version": "1.3.0",
|
||||
"extraneous": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
|
|
@ -5997,9 +5999,9 @@
|
|||
"integrity": "sha512-C6q/xcUJf/2yODRxAVCfIk4j3y3LMsD0ehiE2RQNV2cxc8XU62gR6vvYh3+etSUzlgTfil+qDHI1vubpdf0TOA=="
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
|
||||
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw=="
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
|
|
@ -12204,6 +12206,16 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width-cjs/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/string-width/node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"debounce-promise": "^3.1.2",
|
||||
"dompurify": "^3.0.5",
|
||||
"dotenv": "^16.4.5",
|
||||
"emoji-regex": "^10.3.0",
|
||||
"esbuild": "^0.17.19",
|
||||
"file-saver": "^2.0.5",
|
||||
"framer-motion": "^11.0.6",
|
||||
|
|
|
|||
|
|
@ -164,3 +164,13 @@ body {
|
|||
.ag-body-vertical-scroll-viewport::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
/* This CSS is to not apply the border for the column having 'no-border' class */
|
||||
.no-border.ag-cell:focus {
|
||||
border: none !important;
|
||||
outline: none;
|
||||
}
|
||||
.no-border.ag-cell {
|
||||
border: none !important;
|
||||
outline: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import axios from "axios";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
|
@ -30,10 +29,10 @@ export default function App() {
|
|||
useTrackLastVisitedPath();
|
||||
|
||||
const removeFromTempNotificationList = useAlertStore(
|
||||
(state) => state.removeFromTempNotificationList,
|
||||
(state) => state.removeFromTempNotificationList
|
||||
);
|
||||
const tempNotificationList = useAlertStore(
|
||||
(state) => state.tempNotificationList,
|
||||
(state) => state.tempNotificationList
|
||||
);
|
||||
const [fetchError, setFetchError] = useState(false);
|
||||
const isLoading = useFlowsManagerStore((state) => state.isLoading);
|
||||
|
|
@ -51,7 +50,7 @@ export default function App() {
|
|||
const refreshVersion = useDarkStore((state) => state.refreshVersion);
|
||||
const refreshStars = useDarkStore((state) => state.refreshStars);
|
||||
const setGlobalVariables = useGlobalVariablesStore(
|
||||
(state) => state.setGlobalVariables,
|
||||
(state) => state.setGlobalVariables
|
||||
);
|
||||
const checkHasStore = useStoreStore((state) => state.checkHasStore);
|
||||
const navigate = useNavigate();
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ export default function AlertDropdown({
|
|||
}: AlertDropdownType): JSX.Element {
|
||||
const notificationList = useAlertStore((state) => state.notificationList);
|
||||
const clearNotificationList = useAlertStore(
|
||||
(state) => state.clearNotificationList,
|
||||
(state) => state.clearNotificationList
|
||||
);
|
||||
const removeFromNotificationList = useAlertStore(
|
||||
(state) => state.removeFromNotificationList,
|
||||
(state) => state.removeFromNotificationList
|
||||
);
|
||||
const setNotificationCenter = useAlertStore(
|
||||
(state) => state.setNotificationCenter,
|
||||
(state) => state.setNotificationCenter
|
||||
);
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
|
|
|||
|
|
@ -31,14 +31,14 @@ export default function ImageViewer({ image }) {
|
|||
const fullPageButton = document.getElementById("full-page-button");
|
||||
|
||||
zoomInButton!.addEventListener("click", () =>
|
||||
viewer.viewport.zoomBy(1.2),
|
||||
viewer.viewport.zoomBy(1.2)
|
||||
);
|
||||
zoomOutButton!.addEventListener("click", () =>
|
||||
viewer.viewport.zoomBy(0.8),
|
||||
viewer.viewport.zoomBy(0.8)
|
||||
);
|
||||
homeButton!.addEventListener("click", () => viewer.viewport.goHome());
|
||||
fullPageButton!.addEventListener("click", () =>
|
||||
viewer.setFullScreen(true),
|
||||
viewer.setFullScreen(true)
|
||||
);
|
||||
|
||||
// Optionally, you can set additional viewer options here
|
||||
|
|
@ -47,16 +47,16 @@ export default function ImageViewer({ image }) {
|
|||
return () => {
|
||||
viewer.destroy();
|
||||
zoomInButton!.removeEventListener("click", () =>
|
||||
viewer.viewport.zoomBy(1.2),
|
||||
viewer.viewport.zoomBy(1.2)
|
||||
);
|
||||
zoomOutButton!.removeEventListener("click", () =>
|
||||
viewer.viewport.zoomBy(0.8),
|
||||
viewer.viewport.zoomBy(0.8)
|
||||
);
|
||||
homeButton!.removeEventListener("click", () =>
|
||||
viewer.viewport.goHome(),
|
||||
viewer.viewport.goHome()
|
||||
);
|
||||
fullPageButton!.removeEventListener("click", () =>
|
||||
viewer.setFullScreen(true),
|
||||
viewer.setFullScreen(true)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export default function FolderAccordionComponent({
|
|||
options,
|
||||
}: AccordionComponentType): JSX.Element {
|
||||
const [value, setValue] = useState(
|
||||
open.length === 0 ? "" : getOpenAccordion(),
|
||||
open.length === 0 ? "" : getOpenAccordion()
|
||||
);
|
||||
|
||||
function getOpenAccordion(): string {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import {
|
|||
} from "../../components/ui/accordion";
|
||||
import { AccordionComponentType } from "../../types/components";
|
||||
import { cn } from "../../utils/utils";
|
||||
import ShadTooltip from "../shadTooltipComponent";
|
||||
|
||||
export default function AccordionComponent({
|
||||
trigger,
|
||||
|
|
@ -18,7 +17,7 @@ export default function AccordionComponent({
|
|||
sideBar,
|
||||
}: AccordionComponentType): JSX.Element {
|
||||
const [value, setValue] = useState(
|
||||
open.length === 0 ? "" : getOpenAccordion(),
|
||||
open.length === 0 ? "" : getOpenAccordion()
|
||||
);
|
||||
|
||||
function getOpenAccordion(): string {
|
||||
|
|
@ -53,7 +52,7 @@ export default function AccordionComponent({
|
|||
disabled={disabled}
|
||||
className={cn(
|
||||
sideBar ? "w-full bg-muted px-[0.75rem] py-[0.5rem]" : "ml-3",
|
||||
disabled ? "cursor-not-allowed" : "cursor-pointer",
|
||||
disabled ? "cursor-not-allowed" : "cursor-pointer"
|
||||
)}
|
||||
>
|
||||
{trigger}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue