Merge branch 'fix/minor_bugs' of https://github.com/langflow-ai/langflow into fix/minor_bugs
This commit is contained in:
commit
e6c65aff0b
16 changed files with 114 additions and 77 deletions
4
Makefile
4
Makefile
|
|
@ -48,8 +48,8 @@ coverage:
|
||||||
|
|
||||||
# allow passing arguments to pytest
|
# allow passing arguments to pytest
|
||||||
tests:
|
tests:
|
||||||
poetry run pytest tests --instafail $(args)
|
poetry run pytest tests --instafail -ra -n auto -m "not api_key_required" $(args)
|
||||||
# Use like:
|
|
||||||
|
|
||||||
format:
|
format:
|
||||||
poetry run ruff check . --fix
|
poetry run ruff check . --fix
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ Its intuitive interface allows for easy manipulation of AI building blocks, enab
|
||||||
<ZoomableImage
|
<ZoomableImage
|
||||||
alt="Docusaurus themed image"
|
alt="Docusaurus themed image"
|
||||||
sources={{
|
sources={{
|
||||||
light: "img/new_langflow_demo.gif",
|
light: "img/langflow_basic_howto.gif",
|
||||||
dark: "img/new_langflow_demo.gif",
|
dark: "img/langflow_basic_howto.gif",
|
||||||
}}
|
}}
|
||||||
style={{ width: "100%" }}
|
style={{ width: "100%" }}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ testpaths = ["tests", "integration"]
|
||||||
console_output_style = "progress"
|
console_output_style = "progress"
|
||||||
filterwarnings = ["ignore::DeprecationWarning"]
|
filterwarnings = ["ignore::DeprecationWarning"]
|
||||||
log_cli = true
|
log_cli = true
|
||||||
markers = ["async_test"]
|
markers = ["async_test", "api_key_required"]
|
||||||
|
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.ruff]
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ from sqlmodel import Session, select
|
||||||
from langflow.graph.schema import RunOutputs
|
from langflow.graph.schema import RunOutputs
|
||||||
from langflow.schema.schema import INPUT_FIELD_NAME, Record
|
from langflow.schema.schema import INPUT_FIELD_NAME, Record
|
||||||
from langflow.services.database.models.flow import Flow
|
from langflow.services.database.models.flow import Flow
|
||||||
from langflow.services.deps import get_session, session_scope
|
from langflow.services.deps import get_session, get_settings_service, session_scope
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from langflow.graph.graph.base import Graph
|
from langflow.graph.graph.base import Graph
|
||||||
|
|
@ -88,7 +88,9 @@ async def run_flow(
|
||||||
inputs_components.append(input_dict.get("components", []))
|
inputs_components.append(input_dict.get("components", []))
|
||||||
types.append(input_dict.get("type", "chat"))
|
types.append(input_dict.get("type", "chat"))
|
||||||
|
|
||||||
return await graph.arun(inputs_list, inputs_components=inputs_components, types=types)
|
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)
|
||||||
|
|
||||||
|
|
||||||
def generate_function_for_flow(
|
def generate_function_for_flow(
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from langflow.graph.schema import RunOutputs
|
||||||
from langflow.graph.vertex.base import Vertex
|
from langflow.graph.vertex.base import Vertex
|
||||||
from langflow.schema.graph import InputValue, Tweaks
|
from langflow.schema.graph import InputValue, Tweaks
|
||||||
from langflow.schema.schema import INPUT_FIELD_NAME
|
from langflow.schema.schema import INPUT_FIELD_NAME
|
||||||
|
from langflow.services.deps import get_settings_service
|
||||||
from langflow.services.session.service import SessionService
|
from langflow.services.session.service import SessionService
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -49,6 +50,8 @@ async def run_graph_internal(
|
||||||
inputs_list.append({INPUT_FIELD_NAME: input_value_request.input_value})
|
inputs_list.append({INPUT_FIELD_NAME: input_value_request.input_value})
|
||||||
types.append(input_value_request.type)
|
types.append(input_value_request.type)
|
||||||
|
|
||||||
|
fallback_to_env_vars = get_settings_service().settings.fallback_to_env_var
|
||||||
|
|
||||||
run_outputs = await graph.arun(
|
run_outputs = await graph.arun(
|
||||||
inputs_list,
|
inputs_list,
|
||||||
components,
|
components,
|
||||||
|
|
@ -56,6 +59,7 @@ async def run_graph_internal(
|
||||||
outputs or [],
|
outputs or [],
|
||||||
stream=stream,
|
stream=stream,
|
||||||
session_id=session_id_str or "",
|
session_id=session_id_str or "",
|
||||||
|
fallback_to_env_vars=fallback_to_env_vars
|
||||||
)
|
)
|
||||||
if session_id_str and session_service:
|
if session_id_str and session_service:
|
||||||
await session_service.update_session(session_id_str, (graph, artifacts))
|
await session_service.update_session(session_id_str, (graph, artifacts))
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ class Settings(BaseSettings):
|
||||||
langchain_cache: str = "InMemoryCache"
|
langchain_cache: str = "InMemoryCache"
|
||||||
load_flows_path: Optional[str] = None
|
load_flows_path: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
# Redis
|
# Redis
|
||||||
redis_host: str = "localhost"
|
redis_host: str = "localhost"
|
||||||
redis_port: int = 6379
|
redis_port: int = 6379
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ export const EditFlowSettings: React.FC<InputProps> = ({
|
||||||
type="text"
|
type="text"
|
||||||
name="endpoint_name"
|
name="endpoint_name"
|
||||||
value={endpointName ?? ""}
|
value={endpointName ?? ""}
|
||||||
placeholder="An alternative name for the run endpoint"
|
placeholder="An alternative name to run the endpoint"
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
id="endpoint_name"
|
id="endpoint_name"
|
||||||
onDoubleClickCapture={(event) => {
|
onDoubleClickCapture={(event) => {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { cn } from "../../../../utils/utils";
|
import { cn } from "../../../../utils/utils";
|
||||||
import { buttonVariants } from "../../../ui/button";
|
import { buttonVariants } from "../../../ui/button";
|
||||||
|
import ForwardedIconComponent from "../../../genericIconComponent";
|
||||||
|
|
||||||
type SideBarButtonsComponentProps = {
|
type SideBarButtonsComponentProps = {
|
||||||
items: {
|
items: {
|
||||||
|
|
@ -16,7 +17,7 @@ const SideBarButtonsComponent = ({
|
||||||
pathname,
|
pathname,
|
||||||
}: SideBarButtonsComponentProps) => {
|
}: SideBarButtonsComponentProps) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="flex gap-2 overflow-auto lg:h-[70vh] lg:flex-col">
|
||||||
{items.map((item) => (
|
{items.map((item) => (
|
||||||
<Link to={item.href!}>
|
<Link to={item.href!}>
|
||||||
<div
|
<div
|
||||||
|
|
@ -27,14 +28,17 @@ const SideBarButtonsComponent = ({
|
||||||
pathname === item.href
|
pathname === item.href
|
||||||
? "border border-border bg-muted hover:bg-muted"
|
? "border border-border bg-muted hover:bg-muted"
|
||||||
: "border border-transparent hover:border-border hover:bg-transparent",
|
: "border border-transparent hover:border-border hover:bg-transparent",
|
||||||
"w-full justify-start gap-2",
|
"flex w-full shrink-0 justify-start gap-4",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{item.title}
|
{item.icon}
|
||||||
|
<span className="block max-w-full truncate opacity-100">
|
||||||
|
{item.title}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
export default SideBarButtonsComponent;
|
export default SideBarButtonsComponent;
|
||||||
|
|
|
||||||
|
|
@ -175,11 +175,11 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}}
|
}}
|
||||||
className="flex w-full items-center gap-2"
|
className="flex w-full items-center gap-4"
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name={"folder"}
|
name={"folder"}
|
||||||
className="mr-2 w-4 flex-shrink-0 justify-start stroke-[1.5] opacity-100"
|
className="w-4 flex-shrink-0 justify-start stroke-[1.5] opacity-100"
|
||||||
/>
|
/>
|
||||||
{editFolderName?.edit ? (
|
{editFolderName?.edit ? (
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -265,7 +265,6 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
{item.name}
|
{item.name}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
<div className="flex-1" />
|
|
||||||
{index > 0 && (
|
{index > 0 && (
|
||||||
<Button
|
<Button
|
||||||
className="hidden p-0 hover:bg-white group-hover:block hover:dark:bg-[#0c101a00]"
|
className="hidden p-0 hover:bg-white group-hover:block hover:dark:bg-[#0c101a00]"
|
||||||
|
|
@ -304,7 +303,8 @@ const SideBarFoldersButtonsComponent = ({
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}}
|
}}
|
||||||
variant={"ghost"}
|
size="none"
|
||||||
|
variant="none"
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
name={"Download"}
|
name={"Download"}
|
||||||
|
|
|
||||||
|
|
@ -41,16 +41,20 @@ export default function SidebarNav({
|
||||||
return (
|
return (
|
||||||
<nav className={cn(className)} {...props}>
|
<nav className={cn(className)} {...props}>
|
||||||
<HorizontalScrollFadeComponent>
|
<HorizontalScrollFadeComponent>
|
||||||
<SideBarButtonsComponent items={items} pathname={pathname} />
|
{items.length > 0 ? (
|
||||||
|
<SideBarButtonsComponent items={items} pathname={pathname} />
|
||||||
{!loadingFolders && folders?.length > 0 && isFolderPath && (
|
) : (
|
||||||
<SideBarFoldersButtonsComponent
|
!loadingFolders &&
|
||||||
folders={folders}
|
folders?.length > 0 &&
|
||||||
pathname={pathname}
|
isFolderPath && (
|
||||||
handleChangeFolder={handleChangeFolder}
|
<SideBarFoldersButtonsComponent
|
||||||
handleEditFolder={handleEditFolder}
|
folders={folders}
|
||||||
handleDeleteFolder={handleDeleteFolder}
|
pathname={pathname}
|
||||||
/>
|
handleChangeFolder={handleChangeFolder}
|
||||||
|
handleEditFolder={handleEditFolder}
|
||||||
|
handleDeleteFolder={handleDeleteFolder}
|
||||||
|
/>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
</HorizontalScrollFadeComponent>
|
</HorizontalScrollFadeComponent>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ const buttonVariants = cva(
|
||||||
"border border-muted bg-muted text-secondary-foreground hover:bg-secondary-foreground/5",
|
"border border-muted bg-muted text-secondary-foreground hover:bg-secondary-foreground/5",
|
||||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||||
link: "underline-offset-4 hover:underline text-primary",
|
link: "underline-offset-4 hover:underline text-primary",
|
||||||
|
none: "",
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: "h-10 py-2 px-4",
|
default: "h-10 py-2 px-4",
|
||||||
|
|
@ -27,6 +28,7 @@ const buttonVariants = cva(
|
||||||
xs: "py-0.5 px-3 rounded-md",
|
xs: "py-0.5 px-3 rounded-md",
|
||||||
lg: "h-11 px-8 rounded-md",
|
lg: "h-11 px-8 rounded-md",
|
||||||
icon: "py-1 px-1 rounded-md",
|
icon: "py-1 px-1 rounded-md",
|
||||||
|
none: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
|
|
@ -61,24 +63,29 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
newChildren = toTitleCase(children);
|
newChildren = toTitleCase(children);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Comp className={"relative"} ref={ref} {...props}>
|
<>
|
||||||
<div
|
<Comp
|
||||||
className={cn(
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
loading ? "opacity-100" : "opacity-0",
|
ref={ref}
|
||||||
"absolute self-center",
|
{...props}
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<ForwardedIconComponent name={"Loader2"} className={"animate-spin"} />
|
{loading ? (
|
||||||
</div>
|
<span className={cn("relative")}>
|
||||||
<div
|
<span className={loading ? "invisible" : "hidden"}>
|
||||||
className={cn(
|
{newChildren}
|
||||||
loading ? "opacity-0" : "opacity-100",
|
</span>
|
||||||
buttonVariants({ variant, size, className }),
|
<span className="absolute inset-0 flex items-center justify-center">
|
||||||
|
<ForwardedIconComponent
|
||||||
|
name={"Loader2"}
|
||||||
|
className={"animate-spin"}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
newChildren
|
||||||
)}
|
)}
|
||||||
>
|
</Comp>
|
||||||
{newChildren}
|
</>
|
||||||
</div>
|
|
||||||
</Comp>
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export default function SettingsPage(): JSX.Element {
|
||||||
icon: (
|
icon: (
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
name="SlidersHorizontal"
|
name="SlidersHorizontal"
|
||||||
className="mx-[0.08rem] w-[1.1rem] stroke-[1.5]"
|
className="w-4 flex-shrink-0 justify-start stroke-[1.5]"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
@ -32,7 +32,7 @@ export default function SettingsPage(): JSX.Element {
|
||||||
icon: (
|
icon: (
|
||||||
<ForwardedIconComponent
|
<ForwardedIconComponent
|
||||||
name="Globe"
|
name="Globe"
|
||||||
className="mx-[0.08rem] w-[1.1rem] stroke-[1.5]"
|
className="w-4 flex-shrink-0 justify-start stroke-[1.5]"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
@ -40,7 +40,10 @@ export default function SettingsPage(): JSX.Element {
|
||||||
title: "Shortcuts",
|
title: "Shortcuts",
|
||||||
href: "/settings/shortcuts",
|
href: "/settings/shortcuts",
|
||||||
icon: (
|
icon: (
|
||||||
<ForwardedIconComponent name="Keyboard" className="w-5 stroke-[1.5]" />
|
<ForwardedIconComponent
|
||||||
|
name="Keyboard"
|
||||||
|
className="w-4 flex-shrink-0 justify-start stroke-[1.5]"
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
@ -50,7 +53,7 @@ export default function SettingsPage(): JSX.Element {
|
||||||
description="Manage the general settings for Langflow."
|
description="Manage the general settings for Langflow."
|
||||||
>
|
>
|
||||||
<div className="flex h-full w-full space-y-8 lg:flex-row lg:space-x-8 lg:space-y-0">
|
<div className="flex h-full w-full space-y-8 lg:flex-row lg:space-x-8 lg:space-y-0">
|
||||||
<aside className="flex h-full flex-col space-y-6 lg:w-1/5">
|
<aside className="flex h-full shrink-0 flex-col space-y-6 lg:w-[20vw]">
|
||||||
<SidebarNav items={sidebarNavItems} />
|
<SidebarNav items={sidebarNavItems} />
|
||||||
</aside>
|
</aside>
|
||||||
<div className="h-full w-full flex-1 pb-8">
|
<div className="h-full w-full flex-1 pb-8">
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,23 @@ import {
|
||||||
} from "../../../../types/components";
|
} from "../../../../types/components";
|
||||||
import { gradients } from "../../../../utils/styleUtils";
|
import { gradients } from "../../../../utils/styleUtils";
|
||||||
import { useStoreStore } from "../../../../stores/storeStore";
|
import { useStoreStore } from "../../../../stores/storeStore";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
export default function GeneralPage() {
|
export default function GeneralPage() {
|
||||||
const setCurrentFlowId = useFlowsManagerStore(
|
const setCurrentFlowId = useFlowsManagerStore(
|
||||||
(state) => state.setCurrentFlowId,
|
(state) => state.setCurrentFlowId,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { scrollId } = useParams();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const element = document.getElementById(scrollId ?? "null");
|
||||||
|
if (element) {
|
||||||
|
// 👇 Will scroll smoothly to the top of the next section
|
||||||
|
element.scrollIntoView({ behavior: "smooth" });
|
||||||
|
}
|
||||||
|
}, [scrollId]);
|
||||||
|
|
||||||
const [inputState, setInputState] = useState<patchUserInputStateType>(
|
const [inputState, setInputState] = useState<patchUserInputStateType>(
|
||||||
CONTROL_PATCH_USER_STATE,
|
CONTROL_PATCH_USER_STATE,
|
||||||
);
|
);
|
||||||
|
|
@ -272,9 +283,9 @@ export default function GeneralPage() {
|
||||||
handleSaveKey();
|
handleSaveKey();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Card x-chunk="dashboard-04-chunk-2">
|
<Card x-chunk="dashboard-04-chunk-2" id="api">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>API Key</CardTitle>
|
<CardTitle>Store API Key</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
{(hasApiKey && !validApiKey
|
{(hasApiKey && !validApiKey
|
||||||
? INVALID_API_KEY
|
? INVALID_API_KEY
|
||||||
|
|
|
||||||
|
|
@ -180,24 +180,21 @@ export default function StorePage(): JSX.Element {
|
||||||
title={STORE_TITLE}
|
title={STORE_TITLE}
|
||||||
description={STORE_DESC}
|
description={STORE_DESC}
|
||||||
button={
|
button={
|
||||||
<>
|
<Button
|
||||||
{StoreApiKeyModal && (
|
data-testid="api-key-button-store"
|
||||||
<StoreApiKeyModal disabled={loading}>
|
disabled={loading}
|
||||||
<Button
|
className={cn(
|
||||||
data-testid="api-key-button-store"
|
`${!validApiKey ? "animate-pulse border-error" : ""}`,
|
||||||
disabled={loading}
|
loading ? "cursor-not-allowed" : "",
|
||||||
className={cn(
|
|
||||||
`${!validApiKey ? "animate-pulse border-error" : ""}`,
|
|
||||||
loading ? "cursor-not-allowed" : "",
|
|
||||||
)}
|
|
||||||
variant="primary"
|
|
||||||
>
|
|
||||||
<IconComponent name="Key" className="mr-2 w-4" />
|
|
||||||
API Key
|
|
||||||
</Button>
|
|
||||||
</StoreApiKeyModal>
|
|
||||||
)}
|
)}
|
||||||
</>
|
variant="primary"
|
||||||
|
onClick={() => {
|
||||||
|
navigate("/settings/general/api");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<IconComponent name="Key" className="mr-2 w-4" />
|
||||||
|
API Key
|
||||||
|
</Button>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="flex h-full w-full flex-col justify-between">
|
<div className="flex h-full w-full flex-col justify-between">
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ const Router = () => {
|
||||||
>
|
>
|
||||||
<Route index element={<Navigate replace to={"general"} />} />
|
<Route index element={<Navigate replace to={"general"} />} />
|
||||||
<Route path="global-variables" element={<GlobalVariablesPage />} />
|
<Route path="global-variables" element={<GlobalVariablesPage />} />
|
||||||
<Route path="general" element={<GeneralPage />} />
|
<Route path="general/:scrollId?" element={<GeneralPage />} />
|
||||||
<Route path="shortcuts" element={<ShortcutsPage />} />
|
<Route path="shortcuts" element={<ShortcutsPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route
|
<Route
|
||||||
|
|
@ -80,17 +80,14 @@ const Router = () => {
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route path="/playground/:id/">
|
<Route path="/playground/:id/">
|
||||||
element=
|
<Route
|
||||||
{
|
path=""
|
||||||
<Route
|
element={
|
||||||
path=""
|
<ProtectedRoute>
|
||||||
element={
|
<PlaygroundPage />
|
||||||
<ProtectedRoute>
|
</ProtectedRoute>
|
||||||
<PlaygroundPage />
|
}
|
||||||
</ProtectedRoute>
|
/>
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/flow/:id/">
|
<Route path="/flow/:id/">
|
||||||
<Route
|
<Route
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ from uuid import UUID, uuid4
|
||||||
import pytest
|
import pytest
|
||||||
from fastapi import status
|
from fastapi import status
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from langflow.custom.directory_reader.directory_reader import DirectoryReader
|
from langflow.custom.directory_reader.directory_reader import DirectoryReader
|
||||||
from langflow.services.deps import get_settings_service
|
from langflow.services.deps import get_settings_service
|
||||||
|
|
||||||
|
|
@ -632,6 +633,7 @@ def test_successful_run_with_input_type_any(client, starter_project, created_api
|
||||||
assert all([output.get("results").get("result") == "value1" for output in any_input_outputs]), any_input_outputs
|
assert all([output.get("results").get("result") == "value1" for output in any_input_outputs]), any_input_outputs
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_with_inputs_and_outputs(client, starter_project, created_api_key):
|
def test_run_with_inputs_and_outputs(client, starter_project, created_api_key):
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
|
|
@ -659,6 +661,7 @@ def test_invalid_flow_id(client, created_api_key):
|
||||||
# Check if the error detail is as expected
|
# Check if the error detail is as expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_caching_success(client: TestClient, starter_project, created_api_key):
|
def test_run_flow_with_caching_success(client: TestClient, starter_project, created_api_key):
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
|
|
@ -676,6 +679,7 @@ def test_run_flow_with_caching_success(client: TestClient, starter_project, crea
|
||||||
assert "session_id" in data
|
assert "session_id" in data
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_caching_invalid_flow_id(client: TestClient, created_api_key):
|
def test_run_flow_with_caching_invalid_flow_id(client: TestClient, created_api_key):
|
||||||
invalid_flow_id = uuid4()
|
invalid_flow_id = uuid4()
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
|
|
@ -687,6 +691,7 @@ def test_run_flow_with_caching_invalid_flow_id(client: TestClient, created_api_k
|
||||||
assert f"Flow identifier {invalid_flow_id} not found" in data["detail"]
|
assert f"Flow identifier {invalid_flow_id} not found" in data["detail"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_caching_invalid_input_format(client: TestClient, starter_project, created_api_key):
|
def test_run_flow_with_caching_invalid_input_format(client: TestClient, starter_project, created_api_key):
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
|
|
@ -695,6 +700,7 @@ def test_run_flow_with_caching_invalid_input_format(client: TestClient, starter_
|
||||||
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
assert response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_session_id(client, starter_project, created_api_key):
|
def test_run_flow_with_session_id(client, starter_project, created_api_key):
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
|
|
@ -726,6 +732,7 @@ def test_run_flow_with_invalid_session_id(client, starter_project, created_api_k
|
||||||
assert f"Session {payload['session_id']} not found" in data["detail"]
|
assert f"Session {payload['session_id']} not found" in data["detail"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.api_key_required
|
||||||
def test_run_flow_with_invalid_tweaks(client, starter_project, created_api_key):
|
def test_run_flow_with_invalid_tweaks(client, starter_project, created_api_key):
|
||||||
headers = {"x-api-key": created_api_key.api_key}
|
headers = {"x-api-key": created_api_key.api_key}
|
||||||
flow_id = starter_project["id"]
|
flow_id = starter_project["id"]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue