From d6f9124405be066237b003d98ebc261af8af72e5 Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Tue, 29 Aug 2023 18:34:55 -0300 Subject: [PATCH 01/71] Feat[DropdownButtonComponent]: Create Dropdown Button component --- src/backend/langflow/api/v1/users.py | 4 +- .../DropdownButtonComponent/index.tsx | 49 ++ .../src/components/headerComponent/index.tsx | 28 +- src/frontend/src/pages/AdminPage/index.tsx | 471 +++++++++--------- .../components/PageComponent/index.tsx | 2 +- src/frontend/src/pages/loginPage/index.tsx | 3 +- src/frontend/src/types/components/index.ts | 2 +- src/frontend/src/utils/styleUtils.ts | 2 + 8 files changed, 310 insertions(+), 251 deletions(-) create mode 100644 src/frontend/src/components/DropdownButtonComponent/index.tsx diff --git a/src/backend/langflow/api/v1/users.py b/src/backend/langflow/api/v1/users.py index 7365e7cc1..5094409cb 100644 --- a/src/backend/langflow/api/v1/users.py +++ b/src/backend/langflow/api/v1/users.py @@ -43,7 +43,9 @@ def add_user( db.refresh(new_user) except IntegrityError as e: db.rollback() - raise HTTPException(status_code=400, detail="This username is unavailable.") from e + raise HTTPException( + status_code=400, detail="This username is unavailable." + ) from e return new_user diff --git a/src/frontend/src/components/DropdownButtonComponent/index.tsx b/src/frontend/src/components/DropdownButtonComponent/index.tsx new file mode 100644 index 000000000..20c956365 --- /dev/null +++ b/src/frontend/src/components/DropdownButtonComponent/index.tsx @@ -0,0 +1,49 @@ +import { useState } from "react"; +import IconComponent from "../genericIconComponent"; +import { Button } from "../ui/button"; + +export default function DropdownButton({ + firstButtonName, + onFirstBtnClick, + options, +}): JSX.Element { + const [showOptions, setShowOptions] = useState(false); + + return ( +
+
+ +
+
+ +
+ {showOptions && ( +
+ {options.map((optionName) => ( + + ))} +
+ )} +
+ ); +} diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index c74cdaa76..039b8895c 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -33,14 +33,14 @@ export default function Header(): JSX.Element { )} {!autoLogin && location.pathname !== `/flow/${tabId}` && ( { - logout(); - navigate("/login"); - }} - className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer mx-5" - > - Sign out - + onClick={() => { + logout(); + navigate("/login"); + }} + className="mx-5 cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary" + > + Sign out + )} {location.pathname === "/admin" && ( @@ -48,7 +48,7 @@ export default function Header(): JSX.Element { onClick={() => { navigate("/"); }} - className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer" + className="cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary" > Home @@ -59,11 +59,11 @@ export default function Header(): JSX.Element { location.pathname !== "/admin" && location.pathname !== `/flow/${tabId}` && ( navigate("/admin")} - > - Admin page - + className="cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary" + onClick={() => navigate("/admin")} + > + Admin page + )}
diff --git a/src/frontend/src/pages/AdminPage/index.tsx b/src/frontend/src/pages/AdminPage/index.tsx index fc963fee8..08e83f700 100644 --- a/src/frontend/src/pages/AdminPage/index.tsx +++ b/src/frontend/src/pages/AdminPage/index.tsx @@ -4,6 +4,7 @@ import { useContext, useEffect, useRef, useState } from "react"; import PaginatorComponent from "../../components/PaginatorComponent"; import ShadTooltip from "../../components/ShadTooltipComponent"; import IconComponent from "../../components/genericIconComponent"; +import Header from "../../components/headerComponent"; import { Button } from "../../components/ui/button"; import { Checkbox } from "../../components/ui/checkbox"; import { Input } from "../../components/ui/input"; @@ -25,9 +26,8 @@ import { } from "../../controllers/API"; import ConfirmationModal from "../../modals/ConfirmationModal"; import UserManagementModal from "../../modals/UserManagementModal"; -import { UserInputType } from "../../types/components"; -import Header from "../../components/headerComponent"; import { Users } from "../../types/api"; +import { UserInputType } from "../../types/components"; export default function AdminPage() { const [inputValue, setInputValue] = useState(""); @@ -89,7 +89,7 @@ export default function AdminPage() { if (input === "") { setFilterUserList(userList.current); } else { - const filteredList = userList.current.filter((user:Users) => + const filteredList = userList.current.filter((user: Users) => user.username.toLowerCase().includes(input.toLowerCase()) ); setFilterUserList(filteredList); @@ -183,249 +183,254 @@ export default function AdminPage() { return ( <> -
-
- {userData && ( -
-
-
-
-
-
-

- Welcome back! -

-

- Navigate through this section to efficiently oversee all - application users. From here, you can seamlessly manage - user accounts. -

+
+
+ {userData && ( +
+
+
+
+
+
+

+ Welcome back! +

+

+ Navigate through this section to efficiently oversee all + application users. From here, you can seamlessly manage + user accounts. +

+
+
-
-
- {userList.current.length === 0 && !loadingUsers && ( + {userList.current.length === 0 && !loadingUsers && ( + <> +
+

There's no users registered :)

+
+ + )} <>
-

There's no users registered :)

-
- - )} - <> -
-
- handleFilterUsers(e.target.value)} - /> - {inputValue.length > 0 && ( - + )} +
+
+ { + handleNewUser(user); }} - variant="ghost" - className="h-8 px-2 lg:px-3" > - Reset - - - )} + + +
-
- { - handleNewUser(user); - }} - > - - -
-
- {loadingUsers && ( -
- Loading... -
- )} -
- - - - Id - Username - Active - Superuser - Created At - Updated At - - - - {!loadingUsers && ( - - {filterUserList.map((user:UserInputType, index) => ( - - - - - {user.id} - - - - - - - {user.username} - - - - - { - handleDisableUser( - user.is_active, - user.id, - user - ); - }} - > - - - - - { - handleSuperUserEdit( - user.is_superuser, - user.id, - user - ); - }} - > - - - - - { - new Date(user.create_at!) - .toISOString() - .split("T")[0] - } - - - { - new Date(user.updated_at!) - .toISOString() - .split("T")[0] - } - - -
- { - handleEditUser(user.id, editUser); - }} - > - - + {loadingUsers && ( +
+ Loading... +
+ )} +
+
+ + + Id + Username + Active + Superuser + Created At + Updated At + + + + {!loadingUsers && ( + + {filterUserList.map( + (user: UserInputType, index) => ( + + + + + {user.id} + - - - { - handleDeleteUser(user); - }} - > - - + + + + + {user.username} + - - - - - ))} - - )} -
-
+ + + { + handleDisableUser( + user.is_active, + user.id, + user + ); + }} + > + + + + + { + handleSuperUserEdit( + user.is_superuser, + user.id, + user + ); + }} + > + + + + + { + new Date(user.create_at!) + .toISOString() + .split("T")[0] + } + + + { + new Date(user.updated_at!) + .toISOString() + .split("T")[0] + } + + +
+ { + handleEditUser(user.id, editUser); + }} + > + + + + - { - handleChangePagination(pageSize, pageIndex); - }} - > - + { + handleDeleteUser(user); + }} + > + + + + +
+
+ + ) + )} + + )} + +
+ + { + handleChangePagination(pageSize, pageIndex); + }} + > + +
-
- )} + )}
); diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index 058be6e5c..620170fbb 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -421,7 +421,7 @@ export default function Page({ zoomOnScroll={!view} zoomOnPinch={!view} panOnDrag={!view} - proOptions={{hideAttribution: true}} + proOptions={{ hideAttribution: true }} > {!view && ( diff --git a/src/frontend/src/pages/loginPage/index.tsx b/src/frontend/src/pages/loginPage/index.tsx index 14e04708b..a3ac0fbcd 100644 --- a/src/frontend/src/pages/loginPage/index.tsx +++ b/src/frontend/src/pages/loginPage/index.tsx @@ -19,7 +19,8 @@ export default function LoginPage(): JSX.Element { useState(CONTROL_LOGIN_STATE); const { password, username } = inputState; - const { login, getAuthentication, setUserData, setIsAdmin } = useContext(AuthContext); + const { login, getAuthentication, setUserData, setIsAdmin } = + useContext(AuthContext); const navigate = useNavigate(); const { setErrorData } = useContext(alertContext); diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index f7b974a93..24e538e98 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -268,7 +268,7 @@ export type UserInputType = { is_superuser?: boolean; id?: string; create_at?: string; - updated_at?:string; + updated_at?: string; }; export type ApiKeyType = { diff --git a/src/frontend/src/utils/styleUtils.ts b/src/frontend/src/utils/styleUtils.ts index 31a7adf7e..e74bb0e34 100644 --- a/src/frontend/src/utils/styleUtils.ts +++ b/src/frontend/src/utils/styleUtils.ts @@ -5,6 +5,7 @@ import { ChevronDown, ChevronLeft, ChevronRight, + ChevronUp, ChevronsLeft, ChevronsRight, ChevronsUpDown, @@ -300,4 +301,5 @@ export const nodeIconsLucide: iconsType = { UserCog2, Key, Unplug, + ChevronUp, }; From 6240991e0c29dcff852511c9d67f4dcc8d70578e Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Tue, 29 Aug 2023 18:47:36 -0300 Subject: [PATCH 02/71] Feat: Add Dropdown Button to main page --- .../components/DropdownButtonComponent/index.tsx | 11 ++++++++--- src/frontend/src/pages/MainPage/index.tsx | 13 ++++++------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/frontend/src/components/DropdownButtonComponent/index.tsx b/src/frontend/src/components/DropdownButtonComponent/index.tsx index 20c956365..20865e12d 100644 --- a/src/frontend/src/components/DropdownButtonComponent/index.tsx +++ b/src/frontend/src/components/DropdownButtonComponent/index.tsx @@ -37,9 +37,14 @@ export default function DropdownButton({
{showOptions && (
- {options.map((optionName) => ( - ))}
diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index 67412401a..007298f29 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -6,6 +6,7 @@ import Header from "../../components/headerComponent"; import { Button } from "../../components/ui/button"; import { USER_PROJECTS_HEADER } from "../../constants/constants"; import { TabsContext } from "../../contexts/tabsContext"; +import DropdownButton from "../../components/DropdownButtonComponent"; export default function HomePage(): JSX.Element { const { flows, setTabId, downloadFlows, uploadFlows, addFlow, removeFlow } = useContext(TabsContext); @@ -45,17 +46,15 @@ export default function HomePage(): JSX.Element { Upload Collection - + options={[{name: "yesyes", onBtnClick: () => console.log('dips')}, {name: "dips", onBtnClick: () => console.log('yesyes')}]} + />
From da703d65e3d6f94c5066765bae5589f27c418385 Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Tue, 29 Aug 2023 18:53:39 -0300 Subject: [PATCH 03/71] Feat: Add DropdownButton prop type --- .../src/components/DropdownButtonComponent/index.tsx | 3 ++- src/frontend/src/pages/MainPage/index.tsx | 2 +- src/frontend/src/types/components/index.ts | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/components/DropdownButtonComponent/index.tsx b/src/frontend/src/components/DropdownButtonComponent/index.tsx index 20865e12d..71e02c43b 100644 --- a/src/frontend/src/components/DropdownButtonComponent/index.tsx +++ b/src/frontend/src/components/DropdownButtonComponent/index.tsx @@ -1,12 +1,13 @@ import { useState } from "react"; import IconComponent from "../genericIconComponent"; import { Button } from "../ui/button"; +import { dropdownButtonPropsType } from "../../types/components"; export default function DropdownButton({ firstButtonName, onFirstBtnClick, options, -}): JSX.Element { +}: dropdownButtonPropsType): JSX.Element { const [showOptions, setShowOptions] = useState(false); return ( diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index 007298f29..bdcf76c19 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -53,7 +53,7 @@ export default function HomePage(): JSX.Element { navigate("/flow/" + id); }); }} - options={[{name: "yesyes", onBtnClick: () => console.log('dips')}, {name: "dips", onBtnClick: () => console.log('yesyes')}]} + options={[{name: "Import from JSON", onBtnClick: () => console.log('imported')}]} />
diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 24e538e98..b61ddf07d 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -544,3 +544,9 @@ export type fetchErrorComponentType = { message: string; description: string; }; + +export type dropdownButtonPropsType = { + firstButtonName: string; + onFirstBtnClick: () => void; + options: Array<{ name: string; onBtnClick: () => void; }>; +}; From 8a772086e21d553ff8518f66bb38f51afd09a854 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 29 Aug 2023 22:03:54 -0300 Subject: [PATCH 04/71] fix(api): make frontend_node field optional in ValidatePromptRequest to allow for a tweak call without a frontend_node fix(api): handle case where frontend_node is None in post_validate_prompt to avoid attempting to update a non-existent node --- src/backend/langflow/api/v1/base.py | 7 +++++-- src/backend/langflow/api/v1/validate.py | 7 ++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/backend/langflow/api/v1/base.py b/src/backend/langflow/api/v1/base.py index 71cac5412..39c8b0b9f 100644 --- a/src/backend/langflow/api/v1/base.py +++ b/src/backend/langflow/api/v1/base.py @@ -1,3 +1,4 @@ +from typing import Optional from langflow.template.frontend_node.base import FrontendNode from pydantic import BaseModel, validator @@ -20,7 +21,8 @@ class FrontendNodeRequest(FrontendNode): class ValidatePromptRequest(BaseModel): name: str template: str - frontend_node: FrontendNodeRequest + #optional for tweak call + frontend_node: Optional[FrontendNodeRequest] # Build ValidationResponse class for {"imports": {"errors": []}, "function": {"errors": []}} @@ -39,7 +41,8 @@ class CodeValidationResponse(BaseModel): class PromptValidationResponse(BaseModel): input_variables: list - frontend_node: FrontendNodeRequest + #object return for tweak call + frontend_node: FrontendNodeRequest | object INVALID_CHARACTERS = { diff --git a/src/backend/langflow/api/v1/validate.py b/src/backend/langflow/api/v1/validate.py index 2a5bdd673..da76d25bc 100644 --- a/src/backend/langflow/api/v1/validate.py +++ b/src/backend/langflow/api/v1/validate.py @@ -31,7 +31,12 @@ def post_validate_code(code: Code): def post_validate_prompt(prompt_request: ValidatePromptRequest): try: input_variables = validate_prompt(prompt_request.template) - + # Check if frontend_node is None before proceeding to avoid attempting to update a non-existent node. + if prompt_request.frontend_node is None: + return PromptValidationResponse( + input_variables=input_variables, + frontend_node={}, + ) old_custom_fields = get_old_custom_fields(prompt_request) add_new_variables_to_template(input_variables, prompt_request) From 89a0918dc57f5b9950c4b590e3081e3747cae66a Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa Date: Tue, 29 Aug 2023 22:07:18 -0300 Subject: [PATCH 05/71] =?UTF-8?q?=F0=9F=94=A7=20fix(codeTabsComponent):=20?= =?UTF-8?q?remove=20unused=20useContext=20for=20isTweakPage=20in=20codeTab?= =?UTF-8?q?sComponent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔧 fix(alertContext): remove isTweakPage and setIsTweakPage from alertContext 🔧 fix(genericModal): add null check for nodeClass before calling postValidatePrompt 🔧 fix(extraSidebarComponent): remove setIsTweakPage from extraSidebarComponent 🔧 fix(typesContext): remove isTweakPage and setIsTweakPage from typesContext --- .../components/codeTabsComponent/index.tsx | 19 ++++++++----------- src/frontend/src/contexts/alertContext.tsx | 6 +----- .../src/modals/genericModal/index.tsx | 3 ++- .../extraSidebarComponent/index.tsx | 3 +-- src/frontend/src/types/typesContext/index.ts | 2 -- 5 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/frontend/src/components/codeTabsComponent/index.tsx b/src/frontend/src/components/codeTabsComponent/index.tsx index fcd7385d7..2fa6563a6 100644 --- a/src/frontend/src/components/codeTabsComponent/index.tsx +++ b/src/frontend/src/components/codeTabsComponent/index.tsx @@ -49,7 +49,6 @@ export default function CodeTabsComponent({ const [openAccordion, setOpenAccordion] = useState([]); const { dark } = useContext(darkContext); const { reactFlowInstance } = useContext(typesContext); - const { isTweakPage, setIsTweakPage } = useContext(alertContext); useEffect(() => { if (flow && flow["data"]!["nodes"]) { @@ -58,16 +57,14 @@ export default function CodeTabsComponent({ }, [flow]); useEffect(() => { - unselectAllNodes({ - data, - updateNodes: (nodes) => { - reactFlowInstance?.setNodes(nodes); - }, - }); - - return () => { - if (isTweakPage) setIsTweakPage(false); - }; + if(tweaks){ + unselectAllNodes({ + data, + updateNodes: (nodes) => { + reactFlowInstance?.setNodes(nodes); + }, + }); + } }, []); const copyToClipboard = () => { diff --git a/src/frontend/src/contexts/alertContext.tsx b/src/frontend/src/contexts/alertContext.tsx index 98b2fdef8..ba46dddac 100644 --- a/src/frontend/src/contexts/alertContext.tsx +++ b/src/frontend/src/contexts/alertContext.tsx @@ -25,9 +25,7 @@ const initialValue: alertContextType = { notificationList: [], pushNotificationList: () => {}, clearNotificationList: () => {}, - removeFromNotificationList: () => {}, - isTweakPage: false, - setIsTweakPage: () => {}, + removeFromNotificationList: () => {} }; export const alertContext = createContext(initialValue); @@ -123,8 +121,6 @@ export function AlertProvider({ children }: { children: ReactNode }) { return ( { - if (apiReturn.data) { + if (apiReturn.data && nodeClass) { let inputVariables = apiReturn.data.input_variables ?? []; if (inputVariables && inputVariables.length === 0) { setIsEdit(true); diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index c506975ae..c8dd34628 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -21,7 +21,7 @@ export default function ExtraSidebar(): JSX.Element { const { data, templates } = useContext(typesContext); const { flows, tabId, uploadFlow, tabsState, saveFlow, isBuilt } = useContext(TabsContext); - const { setSuccessData, setErrorData, setIsTweakPage } = + const { setSuccessData, setErrorData } = useContext(alertContext); const [dataFilter, setFilterData] = useState(data); const [search, setSearch] = useState(""); @@ -103,7 +103,6 @@ export default function ExtraSidebar(): JSX.Element {
setIsTweakPage(true)} > void; loading: boolean; setLoading: (newState: boolean) => void; - isTweakPage: boolean; - setIsTweakPage: (newState: boolean) => void; }; export type darkContextType = { From f86c7c16895ae294599bb20953b2b5ac08367c44 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa Date: Tue, 29 Aug 2023 22:13:28 -0300 Subject: [PATCH 06/71] =?UTF-8?q?=F0=9F=90=9B=20fix(genericModal/index.tsx?= =?UTF-8?q?):=20add=20conditional=20check=20before=20setting=20nodeClass?= =?UTF-8?q?=20to=20prevent=20potential=20null=20or=20undefined=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/modals/genericModal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx index 8ac3c01de..7e48635ba 100644 --- a/src/frontend/src/modals/genericModal/index.tsx +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -136,7 +136,7 @@ export default function GenericModal({ setSuccessData({ title: "Prompt is ready", }); - setNodeClass!(apiReturn.data?.frontend_node); + if(apiReturn.data?.frontend_node) setNodeClass!(apiReturn.data?.frontend_node); setModalOpen(closeModal); setValue(inputValue); } From 6457725d13f9a0a7e0ed3cbd4c1ce31d0ac54d4f Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 29 Aug 2023 22:29:41 -0300 Subject: [PATCH 07/71] fix(genericModal/index.tsx): remove debugger statement for cleaner code fix(genericModal/index.tsx): update condition for setting nodeClass to avoid unnecessary re-rendering --- src/frontend/package-lock.json | 12 ++++++------ src/frontend/src/modals/genericModal/index.tsx | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 93805f8ef..b8af76667 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -5514,9 +5514,9 @@ } }, "node_modules/fraction.js": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.0.tgz", - "integrity": "sha512-btalnXjFelOv2cy86KzHWhUuMb622/AD8ce/MCH9C36xe7QRXjJZA+19fP+G5LT0fdRcbOHErMI3SPM11ZaVDg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.1.tgz", + "integrity": "sha512-nx0cki48JBA6ThPeUpeKCNpdhEl/9bRS+dAEYnRUod+Z1jhFfC3K/mBLorZZntqHM+GTH3/dkkpfoT3QITYe7g==", "dev": true, "engines": { "node": "*" @@ -14721,9 +14721,9 @@ } }, "fraction.js": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.0.tgz", - "integrity": "sha512-btalnXjFelOv2cy86KzHWhUuMb622/AD8ce/MCH9C36xe7QRXjJZA+19fP+G5LT0fdRcbOHErMI3SPM11ZaVDg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.1.tgz", + "integrity": "sha512-nx0cki48JBA6ThPeUpeKCNpdhEl/9bRS+dAEYnRUod+Z1jhFfC3K/mBLorZZntqHM+GTH3/dkkpfoT3QITYe7g==", "dev": true }, "fs-extra": { diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx index 7e48635ba..ee0431108 100644 --- a/src/frontend/src/modals/genericModal/index.tsx +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -124,7 +124,8 @@ export default function GenericModal({ //nodeClass is always null on tweaks postValidatePrompt(field_name, inputValue, nodeClass!) .then((apiReturn) => { - if (apiReturn.data && nodeClass) { + // debugger; + if (apiReturn.data) { let inputVariables = apiReturn.data.input_variables ?? []; if (inputVariables && inputVariables.length === 0) { setIsEdit(true); @@ -136,7 +137,8 @@ export default function GenericModal({ setSuccessData({ title: "Prompt is ready", }); - if(apiReturn.data?.frontend_node) setNodeClass!(apiReturn.data?.frontend_node); + + if(JSON.stringify(apiReturn.data?.frontend_node)!==JSON.stringify({})) setNodeClass!(apiReturn.data?.frontend_node); setModalOpen(closeModal); setValue(inputValue); } From c64594c0a81544ebc0f99abfe108733638a2c21b Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 29 Aug 2023 22:33:19 -0300 Subject: [PATCH 08/71] removed dead code --- src/frontend/src/modals/genericModal/index.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx index ee0431108..e0875eba3 100644 --- a/src/frontend/src/modals/genericModal/index.tsx +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -124,7 +124,6 @@ export default function GenericModal({ //nodeClass is always null on tweaks postValidatePrompt(field_name, inputValue, nodeClass!) .then((apiReturn) => { - // debugger; if (apiReturn.data) { let inputVariables = apiReturn.data.input_variables ?? []; if (inputVariables && inputVariables.length === 0) { @@ -137,7 +136,6 @@ export default function GenericModal({ setSuccessData({ title: "Prompt is ready", }); - if(JSON.stringify(apiReturn.data?.frontend_node)!==JSON.stringify({})) setNodeClass!(apiReturn.data?.frontend_node); setModalOpen(closeModal); setValue(inputValue); From 34da83121357350a9b08ebe222f80cedc24ed43b Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Wed, 30 Aug 2023 10:34:30 -0300 Subject: [PATCH 09/71] Reset flows cache when logged out --- src/frontend/src/contexts/tabsContext.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index ac0d676e0..114c1ff93 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -72,7 +72,7 @@ export const TabsContext = createContext( export function TabsProvider({ children }: { children: ReactNode }) { const { setErrorData, setNoticeData, setSuccessData } = useContext(alertContext); - const { getAuthentication } = useContext(AuthContext); + const { getAuthentication, isAuthenticated } = useContext(AuthContext); const [tabId, setTabId] = useState(""); @@ -86,6 +86,12 @@ export function TabsProvider({ children }: { children: ReactNode }) { const [tabsState, setTabsState] = useState({}); const [getTweak, setTweak] = useState([]); + useEffect(() => { + if(!isAuthenticated){ + hardReset(); + } + }, [isAuthenticated]) + const newNodeId = useRef(uid()); function incrementNodeId() { newNodeId.current = uid(); From 3c9a6af4cdfe8fb9140b3327458c22bdda2e161b Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Wed, 30 Aug 2023 11:42:58 -0300 Subject: [PATCH 10/71] Autocomplete style fix and input type fixed for signup and login --- .../src/components/inputComponent/index.tsx | 4 ++++ src/frontend/src/pages/loginPage/index.tsx | 5 +++-- src/frontend/src/pages/signUpPage/index.tsx | 2 ++ src/frontend/src/style/classes.css | 15 +++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx index 987c53a8f..46acdc1b0 100644 --- a/src/frontend/src/components/inputComponent/index.tsx +++ b/src/frontend/src/components/inputComponent/index.tsx @@ -30,6 +30,7 @@ export default function InputComponent({ {isForm ? ( ) : ( { handleInput({ target: { name: "username", value } }); }} @@ -129,12 +130,12 @@ export default function LoginPage(): JSX.Element {
- +
- diff --git a/src/frontend/src/pages/signUpPage/index.tsx b/src/frontend/src/pages/signUpPage/index.tsx index 92f3eff97..c15a905c0 100644 --- a/src/frontend/src/pages/signUpPage/index.tsx +++ b/src/frontend/src/pages/signUpPage/index.tsx @@ -84,6 +84,7 @@ export default function SignUp(): JSX.Element { { handleInput({ target: { name: "username", value } }); }} @@ -157,6 +158,7 @@ export default function SignUp(): JSX.Element {
- {showOptions && ( -
- {options.map(({ name, onBtnClick }) => ( + +
+ {options.map(({ name, onBtnClick }, index) => ( ))}
- )} +
); } diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index bdcf76c19..f3fe68a6c 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -8,8 +8,9 @@ import { USER_PROJECTS_HEADER } from "../../constants/constants"; import { TabsContext } from "../../contexts/tabsContext"; import DropdownButton from "../../components/DropdownButtonComponent"; export default function HomePage(): JSX.Element { - const { flows, setTabId, downloadFlows, uploadFlows, addFlow, removeFlow } = + const { flows, setTabId, downloadFlows, uploadFlows, addFlow, removeFlow, uploadFlow } = useContext(TabsContext); + const dropdownOptions = [{name: "Import from JSON", onBtnClick: () => uploadFlow(true)}] // Set a null id useEffect(() => { @@ -53,12 +54,12 @@ export default function HomePage(): JSX.Element { navigate("/flow/" + id); }); }} - options={[{name: "Import from JSON", onBtnClick: () => console.log('imported')}]} + options={dropdownOptions} />
- Manage your personal projects. Download or upload your collection. + Manage your personal projects. Download or upload your collection.
{flows.map((flow, idx) => ( From e2e890464fe553aa60a417c5a21239663e538019 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 15:53:32 -0300 Subject: [PATCH 12/71] =?UTF-8?q?=F0=9F=94=A7=20fix(base.py):=20import=20s?= =?UTF-8?q?et=5Fsecure=5Fpermissions=20function=20from=20utils=20module=20?= =?UTF-8?q?to=20fix=20NameError=20=F0=9F=94=92=20feat(utils.py):=20add=20s?= =?UTF-8?q?et=5Fsecure=5Fpermissions=20function=20to=20set=20secure=20file?= =?UTF-8?q?=20permissions=20based=20on=20the=20operating=20system?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/services/settings/base.py | 38 +++++++++++++++++-- .../langflow/services/settings/utils.py | 30 +++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/backend/langflow/services/settings/utils.py diff --git a/src/backend/langflow/services/settings/base.py b/src/backend/langflow/services/settings/base.py index 15a675b8b..788c025b1 100644 --- a/src/backend/langflow/services/settings/base.py +++ b/src/backend/langflow/services/settings/base.py @@ -1,14 +1,15 @@ import contextlib import json +import secrets +from langflow.services.settings.utils import set_secure_permissions import orjson import os from shutil import copy2 -import secrets from typing import Optional, List from pathlib import Path import yaml -from pydantic import BaseSettings, root_validator, validator +from pydantic import BaseSettings, Field, root_validator, validator from langflow.utils.logger import logger # BASE_COMPONENTS_PATH = str(Path(__file__).parent / "components") @@ -43,7 +44,8 @@ class Settings(BaseSettings): COMPONENTS_PATH: List[str] = [] # Login settings - SECRET_KEY: str = secrets.token_hex(32) + SECRET_KEY: Optional[str] = Field(None, env="LANGFLOW_SECRET_KEY") + ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 REFRESH_TOKEN_EXPIRE_MINUTES: int = 70 @@ -51,6 +53,36 @@ class Settings(BaseSettings): # > The application does not request login and logs in automatically as a super user. AUTO_LOGIN: bool = True + @validator("SECRET_KEY", pre=True) + def get_secret_key(cls, value, values): + if not value: + logger.debug("No secret key provided, generating a random one") + + if config_dir := values.get("CONFIG_DIR"): + secret_key_path = Path(config_dir) / "secret_key" + + if secret_key_path.exists(): + with open(secret_key_path, "rb") as f: + value = f.read() + logger.debug("Loaded secret key") + else: + value = secrets.token_urlsafe(32) + + with open(secret_key_path, "wb") as f: + f.write(value) + + # Limit the file permissions + try: + set_secure_permissions(secret_key_path) + except Exception: + logger.error("Failed to set secure permissions on secret key") + + logger.debug("Saved secret key") + else: + logger.debug("No CONFIG_DIR provided, not saving secret key") + + return value + @validator("CONFIG_DIR", pre=True, allow_reuse=True) def set_langflow_dir(cls, value): if not value: diff --git a/src/backend/langflow/services/settings/utils.py b/src/backend/langflow/services/settings/utils.py new file mode 100644 index 000000000..e9dc5d964 --- /dev/null +++ b/src/backend/langflow/services/settings/utils.py @@ -0,0 +1,30 @@ +import os +import platform + + +def set_secure_permissions(file_path): + if platform.system() in ["Linux", "Darwin"]: # Unix/Linux/Mac + os.chmod(file_path, 0o600) + elif platform.system() == "Windows": + import win32api + import win32con + import win32security + + user, domain, _ = win32security.LookupAccountName("", win32api.GetUserName()) + sd = win32security.GetFileSecurity( + file_path, win32security.DACL_SECURITY_INFORMATION + ) + dacl = win32security.ACL() + + # Set the new DACL for the file: read and write access for the owner, no access for everyone else + dacl.AddAccessAllowedAce( + win32security.ACL_REVISION, + win32con.GENERIC_READ | win32con.GENERIC_WRITE, + user, + ) + sd.SetSecurityDescriptorDacl(1, dacl, 0) + win32security.SetFileSecurity( + file_path, win32security.DACL_SECURITY_INFORMATION, sd + ) + else: + print("Unsupported OS") From 971d77707426a3ebcfd5817fb4cdbba61584b363 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 16:05:53 -0300 Subject: [PATCH 13/71] =?UTF-8?q?=F0=9F=94=A7=20chore(pyproject.toml):=20a?= =?UTF-8?q?dd=20markupsafe=20dependency=20to=20improve=20compatibility=20a?= =?UTF-8?q?nd=20security=20=F0=9F=94=A7=20chore(pyproject.toml):=20add=20p?= =?UTF-8?q?ywin32=20dependency=20for=20Windows=20platform=20to=20support?= =?UTF-8?q?=20specific=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 433 ++++++++++++++++++++++++------------------------- pyproject.toml | 2 + 2 files changed, 214 insertions(+), 221 deletions(-) diff --git a/poetry.lock b/poetry.lock index d775029c8..cd84dead7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -165,13 +165,13 @@ tz = ["python-dateutil"] [[package]] name = "anthropic" -version = "0.3.10" +version = "0.3.11" description = "Client library for the anthropic API" optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "anthropic-0.3.10-py3-none-any.whl", hash = "sha256:95cd73168296a4f91a5899a28660991e044322cf94442d07b99901d4ca74acd6"}, - {file = "anthropic-0.3.10.tar.gz", hash = "sha256:d1f66efc541fbff0ecfd37fd4d3690f9daaa748fc42d9ded5863a10815a5d97b"}, + {file = "anthropic-0.3.11-py3-none-any.whl", hash = "sha256:5c81105cd9ee7388bff3fdb739aaddedc83bbae9b95d51c2d50c13b1ad106138"}, + {file = "anthropic-0.3.11.tar.gz", hash = "sha256:2e0fa5351c9b368cbed0bbd7217deaa9409b82b56afaf244e2196e99eb4fe20e"}, ] [package.dependencies] @@ -703,76 +703,76 @@ click = "*" [[package]] name = "clickhouse-connect" -version = "0.6.9" +version = "0.6.10" description = "ClickHouse Database Core Driver for Python, Pandas, and Superset" optional = false python-versions = "~=3.7" files = [ - {file = "clickhouse-connect-0.6.9.tar.gz", hash = "sha256:ba735bcb73c4743788e7c8bfeb865edd887da28a253bd189c449df20d9abff64"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:74fb1bc9eea037db1361d75adb6482ce6d8c22e4a47a37735edd8e3862d931f7"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fb5e4a489b5960fc4bc48fdda052b3a446a736ee4be74105ae7663307da8a063"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e954bfe759fd437595732a15a40356e9e29035a83f485a23601f863aab2f7c6f"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e2f4ada702a933f2ffc38e77bf948f11d745f3467191d6b6fc2190683d02bb8"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d06a56e2be745adb692fbf1eedd9fb6d5dbb46ce325c1d9e57b53ba99eee95"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5dcbd145ad907e9bc7dbbc5e80440888201de8f1622f755032595c8b8302e4ef"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f155d1f214c81c5d8e72cbe325dfec72340c082156108db06c862ddd76771d7e"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0b47ec963b9d9cf1674490385183dc988d6e4d33287bb9d81e23373012232223"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-win32.whl", hash = "sha256:59dc14e47fa287578495835e4c5efdff90e40430b5b27a3c1453bb83d65e17cb"}, - {file = "clickhouse_connect-0.6.9-cp310-cp310-win_amd64.whl", hash = "sha256:bcabfaa3fbef4ea9ba723d16e9f50e5e02a3c871b3afc8106b6a04a53a7b19d7"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:93025ec43ffc25ae3e5111c0da65f8227dc6ae68834beeda3b0256c22baedd9f"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac72323af794b4c79a804f4f311cfe4ae28426f92ac1b7f390aabbab6a93a4bd"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d8c1e71b34e870d8cd4805c3be86678e19a63931a718f3bf657b48da82c74df"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c286a6814facf3fa5bf492863e99b300154b33c3ecedf7799070ef9b8cd12474"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9924d53302f3333bcc40b9f5238bea4c29c107a6a82e22dc5ba24ce7c1cdb75"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:adf29b7319e5cdb9b6cb8ec3d4e85056e588ac51265b92ffaf6c69481283e643"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6fc2d4e428af2be8c9db23b37f4493848696417376f0eaba23b0e8f053f6a0d4"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b3793d26cabd88bad6f4a3fe9f93974e480cc785f137158be8b58d700baaeb4f"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-win32.whl", hash = "sha256:1fa2fddd00d019b4593b194a303339268699808c5ebeab2d331b2ee0d29eabc0"}, - {file = "clickhouse_connect-0.6.9-cp311-cp311-win_amd64.whl", hash = "sha256:536df34ecb49ddd7c61ebd6b900a7d06b3a246fbe30441cb68c568ea42e292d3"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d61337ca4c48b78a959627e9c0de58b86a8399510de184bd6d4c27b8b7e93c17"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69449ee694ed9aa4ee5f290c13ce5038efe394ff99b43eeee8e8190f3e4aa909"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b97ee1de55fea90f12e1f04ea6521dd827f2ed25361cfb99374cb0649222a8f0"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:adc42d8970b322bf78053a62e6c555fd8e03b29aecffe21521efaf5bad4e2ba4"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:064a27bd8d92f413ddcf20926a6c868a0482f7e757f9d412c0778b875d20c536"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a4aaf279efc5e8e13c6b4ac7ce41a3700f786dd34a58d3686ddf29660364dc62"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:022e0438728cc323d1817ade5105e4458acf71be822dffee130934140524fcbd"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-win32.whl", hash = "sha256:e7a9c511f680e0f40b8765e7fbb8bde6b101cbf0a5b180f6ccc18ad59c9776ea"}, - {file = "clickhouse_connect-0.6.9-cp37-cp37m-win_amd64.whl", hash = "sha256:c2bd8fc5767fd883d5d1ca2e35e3034e590994ea64f76b11a3814ab20862a0b0"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:159cba55d55ea85cea310a8781144559deade5c8cee6b13bc720253e6a6e4a5c"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f4a34a7e3d16c0e4c34a11b7d8cbd633f22ee48e1a193f1977f64fe470ad9c79"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:026b9363553a6bd22f5c9f4b65cacd3c3fc0b50d5d0159c47bb34f63dc87ccff"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaec4e9dc5110bf6f17a0abbb61e286293400d2c3450e29040fd100dc075dc89"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0224509fd36637ccf1add66f4ec12d464e2e80e4a5521e846f4d7602b6664a0c"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aa5b9b5699ae385d4f7c1f493e1029d7803b47c74ecb2502f01fb79135253d2"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1b0418b347f4e7a27e692f6947b9788759b23ee4f4aabccbb376b5241190f8a7"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:80778a118f5b2c52daf64c051fdbc5df23a8c37e9e385205e4942fdd60925d25"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-win32.whl", hash = "sha256:841838e793cd4283d3a245e278b136ea5681e636dcdc816c27c4ff77e4bb2077"}, - {file = "clickhouse_connect-0.6.9-cp38-cp38-win_amd64.whl", hash = "sha256:63de88cf244adda961742c1e05e051340de09714b38cc33d757138af6033b364"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47216788f28fa8d1c225acdd366f5eab53c00b131ca246c7f004d94b1aff7cef"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8b6669ba538b6fe18cbe01f4451c4e5d5674471cd55aec7af3d6f1a8e064b8f"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43de9421a8f91e82efec5f9bffe366fb341e2fb7c7dce89e303061ba7065baa3"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62b184813807112a8ef2853df93b6c07899bdf04f188e547f92c54fc2e056be3"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5c869d6761f38bfb940fa0992078bd7d8ece1c1c47a330ab3e8390ca8b2ba980"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b83f62002ae8a19102f05868639217fe3dddabf4c099dc0ddf1586901f1501fb"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:442f9119a223c4f97608d3e4f38debc9c62873e0e9dc948cb1b21691be35af55"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cef80d7596887eff39256e29a31c23297a1a65aac735b3e0e323c702dd95d2ee"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-win32.whl", hash = "sha256:f9cdccf6fa12349e4c25d099bed1d80274104cc4e4a8110f6692e553f4491b99"}, - {file = "clickhouse_connect-0.6.9-cp39-cp39-win_amd64.whl", hash = "sha256:067b5b104e0ac1e16255313766cd97cccd06285ab36f7a2bea7960bd643f5c13"}, - {file = "clickhouse_connect-0.6.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e08de57aeb1272897208f91873511090d3f904fede4e509f9b2a0ff00db4d49"}, - {file = "clickhouse_connect-0.6.9-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5318b4ac3fbf91ed3ab766bfa55b5ce72ba520181ad6f61fbf37ed63150033f4"}, - {file = "clickhouse_connect-0.6.9-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df27dfab1565dce2dad8d6ff41a9bc35fb52ed56fba857f26faffac05ffe201"}, - {file = "clickhouse_connect-0.6.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71319fde3214e2382bc7ec402268b9b8c320a2eb86ea764e79a29f7562de06fd"}, - {file = "clickhouse_connect-0.6.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:7e0910ac23e7c1ba9af00818f52cdfc812210b4ab10c2be54f1f6456e144e0a7"}, - {file = "clickhouse_connect-0.6.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8566b0b57537b570bbef6736d461108c2354e40bd1b7166f9f51cc2e0d8124cb"}, - {file = "clickhouse_connect-0.6.9-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c7a0f9c9dcb3bb482043a2b0e3ceb371b17d7ad320317529c2834960649fd20"}, - {file = "clickhouse_connect-0.6.9-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70ae9442b369fa6365018ee92cda1fa26eade3b87640c744b8e3d327872cd8ae"}, - {file = "clickhouse_connect-0.6.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c018fcf03428f940dfa52eea7ff443dea9eee20c2e161486d0a6d2509693904"}, - {file = "clickhouse_connect-0.6.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:adb7d4a449af756ad9c5b2074ce7844ef34981827cce7510151a8a01493e68f3"}, - {file = "clickhouse_connect-0.6.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:66a1d90bcd837734efbe3060f17b98a071f773cac50183efc9a6d2dc40bdbce6"}, - {file = "clickhouse_connect-0.6.9-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41fbc4a75f7098d38246528af34a17b9b7411fb63914787141c82d178bc189be"}, - {file = "clickhouse_connect-0.6.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39b6da9732b26cd98b8ed672bc7684ccf7a589f8d7f56faa7439f8d78b5f4c32"}, - {file = "clickhouse_connect-0.6.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c1954ba9735bf4af6737adc9da68179b6c49b698e288e839705c5c0a260ce85"}, - {file = "clickhouse_connect-0.6.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fa6b01af8c82b860fb4799651dc10a79645b88c8ee103bb14c6e8cdd8b00d8bd"}, + {file = "clickhouse-connect-0.6.10.tar.gz", hash = "sha256:5d4fc0deff7151db66670f289bb2fe714eecc75352eb1d19b3144e267b21456d"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f13409dbd1bf06e13e4d24c0e6ef40dcf8a452f26bebf1b5ef2ca096acd6c357"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5e47206073d8714bc872bceebbbd0580f25cf02d3a5c3a298d19ebc6939876c5"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b0c6253e4be25c9ae65e5aafe0a35fb9d98ac8f22e41884abaeeefb37d432ed"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7c073c936672c918b440207bef0f40b691140646a3ab7a65f02d71de719dd53"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f901bca0f4a19cad08cd111a42c339ccf7682af6aae154f72454ec2032d0f422"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0214c4bc5f7aaae3e14cd67bd24f6bccd7bc97ec2e96e1ec8d69094ed3ffd399"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bdebd13aceeef172f88c6f717cbcf1546c6b916fc601547cfdf4e56a2a129191"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:535a92a2e45a9e64be6cfc1aa85b51ba66ec2cc5e753758f56bd4fdbaa9a7990"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-win32.whl", hash = "sha256:a45cf355a56aca90aca01d74d92bf8c94e1c853fc4c474ee3f8450701dbf6973"}, + {file = "clickhouse_connect-0.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:aa98d776a86495f31a7641b7f31313292a37e0765f0821e82f7c54b3ff9d1325"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66dcf77fc062fe7d8134308ad8b4ddfdbeda2be81cc84147c8090cdb8743f11d"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9bc615e5df873e11dc034af56ec7fc96e7b95d29899188098a1dcba4852542b6"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a919e9d6d3e830a6dde38fd28785f3070531e468be9128bcc84ca80d0b0caa07"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eab582154a8204d1e2bd309f01c6e75c7d5a66370573069d969e4d8d6596f3ee"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cc9c22bd234ad76a3f7ff5493276254e6d94dae75476ce92aebba294c52ed30"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fc13116b43a37674db3641ba325ccb7abdfc45aa4c81c0d60a04d9b03c2a4e07"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2ed439110a634348af432ba891fc53b69eeb0f456867f279b440f73ef1ee243d"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a7442ea25c7c2447c2efe7c81642f038470d65e70bf07f6d620fc9cd92459e1"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-win32.whl", hash = "sha256:e2e1248ce2b0b6dc00c04a183d0e5c5f5ff2e51d5b782d7095f7747ea38e0493"}, + {file = "clickhouse_connect-0.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:995335519d79ea692160beaa98f9717c3c14170fe43a7ff3c19470b930ec8d81"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9becc18719e393afa840dfcf04e5645d7ae413cd66ef68fb5dadf1affe4b8616"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4878ec5ef82e09401418b9dd47e228d50f3100aabc15564193430e13c3ceb6c2"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed71b85f3b8fd66a57d55732981f0d478322c59346b31c5a733c3aaae99e8218"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe2d0af7165059e20c82dc663dc8c446d844282e4fac5f9673d1c63a4db4c23f"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:00c1480cce60e58ae0857f19134c84856bc033b496baaeb920be258e306200e4"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d9450ef2ffd09d01e4485bb6b41b3cb49c92a310d7ddf3c7aaa33abb12b924db"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b7ffcd268abf59e23757cb79e9279dcdea4dcfd5ea6603d3c994e7df5e94c6b5"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-win32.whl", hash = "sha256:29dc07e8d48580b8dfa8a4c2bbb8a6343d5d2f8e64120dca854bc31c2faea45a"}, + {file = "clickhouse_connect-0.6.10-cp37-cp37m-win_amd64.whl", hash = "sha256:17e47909d02623e762d941b82237f6aa457985058b65aea4a46ceed2d7235919"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bb29eefe4c7899f85f7c675160ba973f780284a2baadf1f7ba8b09d3d6955aa9"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bf119182bdb6069d99ff70ad8d9603b888f070d7efae8792820be78333df566"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c131001f3143f8265fc5a0147590d103e26b04cf16877c045e490a48e577985"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c4cd828f669a13c1fe8179796277d0a66a647f5acf3add87d6f53dfb69a74dc"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9992ee252ca78c84b0fd9f3c1c102f9ce51be11e3908a0419fb7c44d7df6bab"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7a1c81a6cc8d46865162699c1832cbfd8af5923b8516820415e7b5d7078e5df6"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a2e2e847ab5ca88761c0736fbc70b22f612406e3b3b6478907defe321415ddc"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:937c1dc1457935778909058e8527f9c1b91bfa0ef943ec4fb3b214f2b81da863"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-win32.whl", hash = "sha256:23a819007930be03bfef325742f0bfb51ce42bce7cf1adb203f879a5ccd9b16a"}, + {file = "clickhouse_connect-0.6.10-cp38-cp38-win_amd64.whl", hash = "sha256:876134ded05bee9168d2c76eef49f7719501496a2ba440778649240e906017b6"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:816efe8f178fa212520a0f1f0c9f9899d03732b73aff33a875368e28bb4b8b06"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:891048c48dbcce7ff096fa0a338c763e3c2fe4768e41bcc7a27223133ba58101"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f7106ad09f736676e57987039de95817e260eeeb1cae1931e41b4362ea13b5f"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88d3edf76fb4d6ebd38c8ce4c84e7a7489c226592e9e5b8664156b3aac726a51"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1287a32fc28fd8b32401810948366c50a7a25c74074ab2f98c369804c6366743"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f2a8ac16f5750ee219960e68003a43dc25b873f0d608ad379035e9d642cd5a30"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9c36e19fd418ef41b4162fbbe658d2d579d590685c3f3db7ad55aca9cc2fb0f6"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4de6ce7bcb8da818929aaac03bb2c0c6d68d13702d79d1348d123ebf868c6917"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-win32.whl", hash = "sha256:bd498329370c3551c7dbc6013018b0521da102f63e40d554485a29e07ff57cf3"}, + {file = "clickhouse_connect-0.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:128fba3e62292e340194d271883d049f63f2fdb6fc56513f776df3fccc81cfab"}, + {file = "clickhouse_connect-0.6.10-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ba12b89e19be14c9aeb1042ec72fa0ba0eb892e4c9d6bfb6ffc52a0e1a628fb1"}, + {file = "clickhouse_connect-0.6.10-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:227a6cc07c372778909c55d114b238616c46ae70d99fed4647e960aba2d189ff"}, + {file = "clickhouse_connect-0.6.10-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cecbee657bb902b0baa6d2b768166b967d1edba0e3ba77f22ddc8338ce588c46"}, + {file = "clickhouse_connect-0.6.10-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fbeca9ba2529bea8ac32f8e6fa35c43f61d8c3b4883b56668c712a1065a58b2e"}, + {file = "clickhouse_connect-0.6.10-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:7238fdbafdec8fb60f8a0e3e5f2237ae3ded8bad372216df82c0d94709815136"}, + {file = "clickhouse_connect-0.6.10-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7984d9b55927e6fbdcd774790327aa3abba2f12020caa7a422ef0ca0f95080ae"}, + {file = "clickhouse_connect-0.6.10-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:496cbc65916e83cb4c5175f22e678427b6aef75b582d04e73f3f6303ee674bf9"}, + {file = "clickhouse_connect-0.6.10-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e57182bb96fded997c526160626a1258ff050910ffa6e7eac21c6591f74f2d0"}, + {file = "clickhouse_connect-0.6.10-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:193b9e78a190814e36f1570466eb372e3981ce2c2c0536ef03d728ea6504af0f"}, + {file = "clickhouse_connect-0.6.10-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3e4e4aa9e83d7c73a347becba3ab5c4c7a0abde7c01d57edd0c2bb6399585946"}, + {file = "clickhouse_connect-0.6.10-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:56962ec499d25bd0cb33c90cdf52c9220691be30a587faf45ba346add679168b"}, + {file = "clickhouse_connect-0.6.10-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abf77febdf4e98990bd1e775c3909f9db62fd544a759298fc8b03e72167a2375"}, + {file = "clickhouse_connect-0.6.10-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d773e048635223ccd974ebbcac84190682772bcf7ed89333f7a2c3f42da5cc1"}, + {file = "clickhouse_connect-0.6.10-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29365f01bee352e0b0ed3ef145d41c6b642d3ffc54b85c8a743c75398a752384"}, + {file = "clickhouse_connect-0.6.10-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ce55154bb1d6911e865bd95d2af935bbb1eb3d66da7b5631d6c42369383eb36d"}, ] [package.dependencies] @@ -969,13 +969,13 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "ctransformers" -version = "0.2.23" +version = "0.2.25" description = "Python bindings for the Transformer models implemented in C/C++ using GGML library." optional = true python-versions = "*" files = [ - {file = "ctransformers-0.2.23-py3-none-any.whl", hash = "sha256:ebbba968c81a71919f9c3975b20d9b6c85e6fd5f640d1f7b86cb8d5d56c3d347"}, - {file = "ctransformers-0.2.23.tar.gz", hash = "sha256:de665dfbd529cf369059e52b277dcbdd6761a0547c8931b3cfbf89ea1eeb3d3c"}, + {file = "ctransformers-0.2.25-py3-none-any.whl", hash = "sha256:a97405373c61c8d8f0279b88f96543caec638773a4fe82ff2ed8d993844830f1"}, + {file = "ctransformers-0.2.25.tar.gz", hash = "sha256:59d654a4be8a51f0c5b7976d8d39a1e410f5e808f8cdabad02da4957001053d8"}, ] [package.dependencies] @@ -1435,18 +1435,21 @@ zstandard = ["zstandard"] [[package]] name = "filelock" -version = "3.12.2" +version = "3.12.3" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.12.3-py3-none-any.whl", hash = "sha256:f067e40ccc40f2b48395a80fcbd4728262fab54e232e090a4063ab804179efeb"}, + {file = "filelock-3.12.3.tar.gz", hash = "sha256:0ecc1dd2ec4672a10c8550a8182f1bd0c0a5088470ecd5a125e45f49472fac3d"}, ] +[package.dependencies] +typing-extensions = {version = ">=4.7.1", markers = "python_version < \"3.11\""} + [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.7.26)", "sphinx (>=7.1.2)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3)", "diff-cover (>=7.7)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)", "pytest-timeout (>=2.1)"] [[package]] name = "filetype" @@ -1688,13 +1691,13 @@ six = "*" [[package]] name = "google-cloud-aiplatform" -version = "1.31.0" +version = "1.31.1" description = "Vertex AI API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-aiplatform-1.31.0.tar.gz", hash = "sha256:a5de8f5cb9bcd66db08a404cf74e7ed252d5d4038649a58f37588ccb4e2785f0"}, - {file = "google_cloud_aiplatform-1.31.0-py2.py3-none-any.whl", hash = "sha256:19429dfb6098414f758810fde1690d8e8170aff7add4281681dc61de79b4112b"}, + {file = "google-cloud-aiplatform-1.31.1.tar.gz", hash = "sha256:6de8d7d647990cc0ee601d938d3a1693e3ef50f3d54d735397b2e31ca8eeb946"}, + {file = "google_cloud_aiplatform-1.31.1-py2.py3-none-any.whl", hash = "sha256:360d95c4c6f6a27fc2a4a071741a66588f0f0ca245509315839cfa320d6862e2"}, ] [package.dependencies] @@ -2834,13 +2837,13 @@ files = [ [[package]] name = "jupyter-client" -version = "8.3.0" +version = "8.3.1" description = "Jupyter protocol implementation and client libraries" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.3.0-py3-none-any.whl", hash = "sha256:7441af0c0672edc5d28035e92ba5e32fadcfa8a4e608a434c228836a89df6158"}, - {file = "jupyter_client-8.3.0.tar.gz", hash = "sha256:3af69921fe99617be1670399a0b857ad67275eefcfa291e2c81a160b7b650f5f"}, + {file = "jupyter_client-8.3.1-py3-none-any.whl", hash = "sha256:5eb9f55eb0650e81de6b7e34308d8b92d04fe4ec41cd8193a913979e33d8e1a5"}, + {file = "jupyter_client-8.3.1.tar.gz", hash = "sha256:60294b2d5b869356c893f57b1a877ea6510d60d45cf4b38057f1672d85699ac9"}, ] [package.dependencies] @@ -2978,13 +2981,13 @@ test = ["psutil", "pytest", "pytest-asyncio"] [[package]] name = "langsmith" -version = "0.0.26" +version = "0.0.29" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langsmith-0.0.26-py3-none-any.whl", hash = "sha256:61c1d4582104d96edde04e1eea1dae347645b691c44489a5871341a2a1a2a1eb"}, - {file = "langsmith-0.0.26.tar.gz", hash = "sha256:80a4ef1b663a24a460d25b9986ab2010c5d06b6061c65be473abafc0647d191a"}, + {file = "langsmith-0.0.29-py3-none-any.whl", hash = "sha256:1b8fa032bf1671d80fed027545aa822ef8f39fec0381b799a9c511120e8e8258"}, + {file = "langsmith-0.0.29.tar.gz", hash = "sha256:d389a0199937cb219d7cb90d4adbed7f3902818b22b604bb1ced5b74c571cfe5"}, ] [package.dependencies] @@ -3013,18 +3016,18 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "llama-cpp-python" -version = "0.1.78" +version = "0.1.83" description = "A Python wrapper for llama.cpp" optional = true python-versions = ">=3.7" files = [ - {file = "llama_cpp_python-0.1.78.tar.gz", hash = "sha256:cffdcbc4b5fca2bceb1f6bf3590460ebc898c69295a02439dfc6327566e10367"}, + {file = "llama_cpp_python-0.1.83.tar.gz", hash = "sha256:9f40656e46a85a3c3427790246e03490bb90202c37cb99732a095ffcb99efe54"}, ] [package.dependencies] -diskcache = ">=5.6.1" -numpy = ">=1.20.0" -typing-extensions = ">=4.5.0" +diskcache = ">=5.6.1,<6.0.0" +numpy = ">=1.24.4,<2.0.0" +typing-extensions = ">=4.7.1,<5.0.0" [package.extras] server = ["fastapi (>=0.100.0)", "pydantic-settings (>=2.0.1)", "sse-starlette (>=1.6.1)", "uvicorn (>=0.23.2,<0.24.0)"] @@ -3057,8 +3060,6 @@ files = [ {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"}, {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"}, {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"}, - {file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"}, - {file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"}, {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"}, {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"}, {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"}, @@ -3261,7 +3262,7 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." -optional = true +optional = false python-versions = ">=3.7" files = [ {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, @@ -3801,13 +3802,13 @@ sympy = "*" [[package]] name = "openai" -version = "0.27.9" +version = "0.27.10" description = "Python client library for the OpenAI API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-0.27.9-py3-none-any.whl", hash = "sha256:6a3cf8e276d1a6262b50562fbc0cba7967cfebb78ed827d375986b48fdad6475"}, - {file = "openai-0.27.9.tar.gz", hash = "sha256:b687761c82f5ebb6f61efc791b2083d2d068277b94802d4d1369efe39851813d"}, + {file = "openai-0.27.10-py3-none-any.whl", hash = "sha256:beabd1757e3286fa166dde3b70ebb5ad8081af046876b47c14c41e203ed22a14"}, + {file = "openai-0.27.10.tar.gz", hash = "sha256:60e09edf7100080283688748c6803b7b3b52d5a55d21890f3815292a0552d83b"}, ] [package.dependencies] @@ -4202,69 +4203,61 @@ files = [ [[package]] name = "pandas" -version = "2.0.3" +version = "2.1.0" description = "Powerful data structures for data analysis, time series, and statistics" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" files = [ - {file = "pandas-2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8"}, - {file = "pandas-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0"}, - {file = "pandas-2.0.3-cp310-cp310-win32.whl", hash = "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210"}, - {file = "pandas-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df"}, - {file = "pandas-2.0.3-cp311-cp311-win32.whl", hash = "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd"}, - {file = "pandas-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0"}, - {file = "pandas-2.0.3-cp38-cp38-win32.whl", hash = "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02"}, - {file = "pandas-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641"}, - {file = "pandas-2.0.3-cp39-cp39-win32.whl", hash = "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682"}, - {file = "pandas-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc"}, - {file = "pandas-2.0.3.tar.gz", hash = "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c"}, + {file = "pandas-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:40dd20439ff94f1b2ed55b393ecee9cb6f3b08104c2c40b0cb7186a2f0046242"}, + {file = "pandas-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d4f38e4fedeba580285eaac7ede4f686c6701a9e618d8a857b138a126d067f2f"}, + {file = "pandas-2.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e6a0fe052cf27ceb29be9429428b4918f3740e37ff185658f40d8702f0b3e09"}, + {file = "pandas-2.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d81e1813191070440d4c7a413cb673052b3b4a984ffd86b8dd468c45742d3cc"}, + {file = "pandas-2.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eb20252720b1cc1b7d0b2879ffc7e0542dd568f24d7c4b2347cb035206936421"}, + {file = "pandas-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:38f74ef7ebc0ffb43b3d633e23d74882bce7e27bfa09607f3c5d3e03ffd9a4a5"}, + {file = "pandas-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cda72cc8c4761c8f1d97b169661f23a86b16fdb240bdc341173aee17e4d6cedd"}, + {file = "pandas-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d97daeac0db8c993420b10da4f5f5b39b01fc9ca689a17844e07c0a35ac96b4b"}, + {file = "pandas-2.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8c58b1113892e0c8078f006a167cc210a92bdae23322bb4614f2f0b7a4b510f"}, + {file = "pandas-2.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:629124923bcf798965b054a540f9ccdfd60f71361255c81fa1ecd94a904b9dd3"}, + {file = "pandas-2.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:70cf866af3ab346a10debba8ea78077cf3a8cd14bd5e4bed3d41555a3280041c"}, + {file = "pandas-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:d53c8c1001f6a192ff1de1efe03b31a423d0eee2e9e855e69d004308e046e694"}, + {file = "pandas-2.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:86f100b3876b8c6d1a2c66207288ead435dc71041ee4aea789e55ef0e06408cb"}, + {file = "pandas-2.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28f330845ad21c11db51e02d8d69acc9035edfd1116926ff7245c7215db57957"}, + {file = "pandas-2.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9a6ccf0963db88f9b12df6720e55f337447aea217f426a22d71f4213a3099a6"}, + {file = "pandas-2.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99e678180bc59b0c9443314297bddce4ad35727a1a2656dbe585fd78710b3b9"}, + {file = "pandas-2.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b31da36d376d50a1a492efb18097b9101bdbd8b3fbb3f49006e02d4495d4c644"}, + {file = "pandas-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:0164b85937707ec7f70b34a6c3a578dbf0f50787f910f21ca3b26a7fd3363437"}, + {file = "pandas-2.1.0.tar.gz", hash = "sha256:62c24c7fc59e42b775ce0679cfa7b14a5f9bfb7643cfbe708c960699e05fb918"}, ] [package.dependencies] -numpy = [ - {version = ">=1.20.3", markers = "python_version < \"3.10\""}, - {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, -] +numpy = {version = ">=1.22.4", markers = "python_version < \"3.11\""} python-dateutil = ">=2.8.2" pytz = ">=2020.1" tzdata = ">=2022.1" [package.extras] -all = ["PyQt5 (>=5.15.1)", "SQLAlchemy (>=1.4.16)", "beautifulsoup4 (>=4.9.3)", "bottleneck (>=1.3.2)", "brotlipy (>=0.7.0)", "fastparquet (>=0.6.3)", "fsspec (>=2021.07.0)", "gcsfs (>=2021.07.0)", "html5lib (>=1.1)", "hypothesis (>=6.34.2)", "jinja2 (>=3.0.0)", "lxml (>=4.6.3)", "matplotlib (>=3.6.1)", "numba (>=0.53.1)", "numexpr (>=2.7.3)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pandas-gbq (>=0.15.0)", "psycopg2 (>=2.8.6)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "python-snappy (>=0.6.0)", "pyxlsb (>=1.0.8)", "qtpy (>=2.2.0)", "s3fs (>=2021.08.0)", "scipy (>=1.7.1)", "tables (>=3.6.1)", "tabulate (>=0.8.9)", "xarray (>=0.21.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)", "zstandard (>=0.15.2)"] -aws = ["s3fs (>=2021.08.0)"] -clipboard = ["PyQt5 (>=5.15.1)", "qtpy (>=2.2.0)"] -compression = ["brotlipy (>=0.7.0)", "python-snappy (>=0.6.0)", "zstandard (>=0.15.2)"] -computation = ["scipy (>=1.7.1)", "xarray (>=0.21.0)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.7)", "pyxlsb (>=1.0.8)", "xlrd (>=2.0.1)", "xlsxwriter (>=1.4.3)"] +all = ["PyQt5 (>=5.15.6)", "SQLAlchemy (>=1.4.36)", "beautifulsoup4 (>=4.11.1)", "bottleneck (>=1.3.4)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=0.8.1)", "fsspec (>=2022.05.0)", "gcsfs (>=2022.05.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.8.0)", "matplotlib (>=3.6.1)", "numba (>=0.55.2)", "numexpr (>=2.8.0)", "odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pandas-gbq (>=0.17.5)", "psycopg2 (>=2.9.3)", "pyarrow (>=7.0.0)", "pymysql (>=1.0.2)", "pyreadstat (>=1.1.5)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)", "pyxlsb (>=1.0.9)", "qtpy (>=2.2.0)", "s3fs (>=2022.05.0)", "scipy (>=1.8.1)", "tables (>=3.7.0)", "tabulate (>=0.8.10)", "xarray (>=2022.03.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)", "zstandard (>=0.17.0)"] +aws = ["s3fs (>=2022.05.0)"] +clipboard = ["PyQt5 (>=5.15.6)", "qtpy (>=2.2.0)"] +compression = ["zstandard (>=0.17.0)"] +computation = ["scipy (>=1.8.1)", "xarray (>=2022.03.0)"] +consortium-standard = ["dataframe-api-compat (>=0.1.7)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.0.10)", "pyxlsb (>=1.0.9)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.3)"] feather = ["pyarrow (>=7.0.0)"] -fss = ["fsspec (>=2021.07.0)"] -gcp = ["gcsfs (>=2021.07.0)", "pandas-gbq (>=0.15.0)"] -hdf5 = ["tables (>=3.6.1)"] -html = ["beautifulsoup4 (>=4.9.3)", "html5lib (>=1.1)", "lxml (>=4.6.3)"] -mysql = ["SQLAlchemy (>=1.4.16)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.0.0)", "tabulate (>=0.8.9)"] +fss = ["fsspec (>=2022.05.0)"] +gcp = ["gcsfs (>=2022.05.0)", "pandas-gbq (>=0.17.5)"] +hdf5 = ["tables (>=3.7.0)"] +html = ["beautifulsoup4 (>=4.11.1)", "html5lib (>=1.1)", "lxml (>=4.8.0)"] +mysql = ["SQLAlchemy (>=1.4.36)", "pymysql (>=1.0.2)"] +output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.8.10)"] parquet = ["pyarrow (>=7.0.0)"] -performance = ["bottleneck (>=1.3.2)", "numba (>=0.53.1)", "numexpr (>=2.7.1)"] +performance = ["bottleneck (>=1.3.4)", "numba (>=0.55.2)", "numexpr (>=2.8.0)"] plot = ["matplotlib (>=3.6.1)"] -postgresql = ["SQLAlchemy (>=1.4.16)", "psycopg2 (>=2.8.6)"] -spss = ["pyreadstat (>=1.1.2)"] -sql-other = ["SQLAlchemy (>=1.4.16)"] -test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.6.3)"] +postgresql = ["SQLAlchemy (>=1.4.36)", "psycopg2 (>=2.9.3)"] +spss = ["pyreadstat (>=1.1.5)"] +sql-other = ["SQLAlchemy (>=1.4.36)"] +test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] +xml = ["lxml (>=4.8.0)"] [[package]] name = "pandas-stubs" @@ -4408,7 +4401,6 @@ files = [ {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3b08d4cc24f471b2c8ca24ec060abf4bebc6b144cb89cba638c720546b1cf538"}, {file = "Pillow-10.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737a602fbd82afd892ca746392401b634e278cb65d55c4b7a8f48e9ef8d008d"}, {file = "Pillow-10.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:3a82c40d706d9aa9734289740ce26460a11aeec2d9c79b7af87bb35f0073c12f"}, - {file = "Pillow-10.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:bc2ec7c7b5d66b8ec9ce9f720dbb5fa4bace0f545acd34870eff4a369b44bf37"}, {file = "Pillow-10.0.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:d80cf684b541685fccdd84c485b31ce73fc5c9b5d7523bf1394ce134a60c6883"}, {file = "Pillow-10.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76de421f9c326da8f43d690110f0e79fe3ad1e54be811545d7d91898b4c8493e"}, {file = "Pillow-10.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81ff539a12457809666fef6624684c008e00ff6bf455b4b89fd00a140eecd640"}, @@ -4418,7 +4410,6 @@ files = [ {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d50b6aec14bc737742ca96e85d6d0a5f9bfbded018264b3b70ff9d8c33485551"}, {file = "Pillow-10.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:00e65f5e822decd501e374b0650146063fbb30a7264b4d2744bdd7b913e0cab5"}, {file = "Pillow-10.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:f31f9fdbfecb042d046f9d91270a0ba28368a723302786c0009ee9b9f1f60199"}, - {file = "Pillow-10.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:1ce91b6ec08d866b14413d3f0bbdea7e24dfdc8e59f562bb77bc3fe60b6144ca"}, {file = "Pillow-10.0.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:349930d6e9c685c089284b013478d6f76e3a534e36ddfa912cde493f235372f3"}, {file = "Pillow-10.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3a684105f7c32488f7153905a4e3015a3b6c7182e106fe3c37fbb5ef3e6994c3"}, {file = "Pillow-10.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4f69b3700201b80bb82c3a97d5e9254084f6dd5fb5b16fc1a7b974260f89f43"}, @@ -4508,13 +4499,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pluggy" -version = "1.2.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] [package.extras] @@ -4850,41 +4841,41 @@ files = [ [[package]] name = "pulsar-client" -version = "3.2.0" +version = "3.3.0" description = "Apache Pulsar Python client library" optional = false python-versions = "*" files = [ - {file = "pulsar_client-3.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:da53bbe1903026ca1253d36a67bde0ae88513497091658aee8c5514c3e567483"}, - {file = "pulsar_client-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec595a71b7a25f1a72a1350efd6680a511b53253c3cac1911ba3d6c4d71fa64c"}, - {file = "pulsar_client-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3557c65463d74ec8d2864752389beb06761ab591dd134a164e0b1303c66719b"}, - {file = "pulsar_client-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d51dc76fec48217489bde95754ad58288c9389361de42f5a27d64e19840d27fb"}, - {file = "pulsar_client-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9ef2baf85311e0fe1b98342fdafbb93a1818a08ef999eaa524234fedf6f3b941"}, - {file = "pulsar_client-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:0928b02beda0c98e77178f4e30e962ddb8ee8c3320e4c7304a78b0796e976523"}, - {file = "pulsar_client-3.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:584f44b03474a69906be711a597a4d516263a55be31e49fc07be503dc8406821"}, - {file = "pulsar_client-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a637b9a3b30860c61e68a7b8ea650e0987d89e82f73b6a3df1ab662a6438fdda"}, - {file = "pulsar_client-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4a187fdc5febcf16f725179dcf2c476f31eeebd8353794d91754a3202dd5072"}, - {file = "pulsar_client-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5ff879f868cf1fd29db99f39fdb22b3ec3e749c648aca28526689756d922d1c5"}, - {file = "pulsar_client-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a5f85d0cc414f739a5b51d843f213b54b2cd768c3a34f7c27cca410712b1f81"}, - {file = "pulsar_client-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:4fe748283848d829a80c0323558faeebea4c240d69fa58314ac90344f6999d17"}, - {file = "pulsar_client-3.2.0-cp37-cp37m-macosx_10_15_universal2.whl", hash = "sha256:06b91c26def86dbbc35be15257999fd8a2afbadf32983916ea3eef44f4d4cab4"}, - {file = "pulsar_client-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39ec897bc8d232e6b118793378fc662a844334b829a28a1b4ad1c5fe8d019135"}, - {file = "pulsar_client-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa37c96c25c1b5aff3bad0fd0194b385ec190b2c67a2f439ac91577f81ae18d3"}, - {file = "pulsar_client-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d49cdd4d1b7fc2e80d100acf14e6fd3898f6e099e403fc56ed22a690245b2fec"}, - {file = "pulsar_client-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0058ca3191fd24528ccf94dba6f12e4093831454a2597166f96900d0717271bf"}, - {file = "pulsar_client-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:cb69b0411008e0b56df51de0aab20aa1c1a12aef3019b9ceba89afbae1f07fe2"}, - {file = "pulsar_client-3.2.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:f7d33e99602352df7a30707eab4e5781654602212fb618928bffb5523f2bcf35"}, - {file = "pulsar_client-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad1ac15a175ca90555c681a4d0134568771c6346b97a172f3ef14006556a50ae"}, - {file = "pulsar_client-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369e08ef1d5cb196dd9271039928800f90b4701a9c9df90bc068b44260d2fb11"}, - {file = "pulsar_client-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a52ba2b6736a2ebeed31b590e75d417dda149e333461655860efa84d898a3eb4"}, - {file = "pulsar_client-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c801334b3b569b23976481a2922bcea0c6dd990fc26544658dd9e9c8f78ca36"}, - {file = "pulsar_client-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:cd01fd419280e9013d1655bc53662248be2656b623b1506480e1a985aa7dadd2"}, - {file = "pulsar_client-3.2.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:0abe54d84db76435a6cd88ce27610352cabc7efae9fa3e7f874e032ec2ca0b3f"}, - {file = "pulsar_client-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9a1b6a806eb4819d8cbab1c4ae44ebf2110a94204a46c365f5757e1455252f2"}, - {file = "pulsar_client-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34ea2a6b75ae0e303d522e5b57c75a4ff03dc18b9bfc14151fb14dfaf5866f17"}, - {file = "pulsar_client-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:be6d3a9b2e1db3b6d1a7db5e13f7b4ed420674cf072cdb520fb004c4cd54c0af"}, - {file = "pulsar_client-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6b733e6239ffb505f7084df0175baf9d0215f14d0a02e9bbd1fdf71a2d6ea17"}, - {file = "pulsar_client-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:edc2135d02b4793efb086edca0ffaa6e8ac9133961c2cdc17ae487e0a53da481"}, + {file = "pulsar_client-3.3.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:c31afd3e67a044ff93177df89e08febf214cc965e95ede097d9fe8755af00e01"}, + {file = "pulsar_client-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f66982284571674b215324cc26b5c2f7c56c7043113c47a7084cb70d67a8afb"}, + {file = "pulsar_client-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fe50a06f81c48a75a9b95c27a6446260039adca71d9face273740de96b2efca"}, + {file = "pulsar_client-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d4c46a4b96a6e9919cfe220156d69a2ede8053d9ea1add4ada108abcf2ba9775"}, + {file = "pulsar_client-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1e4b5d44b992c9b036286b483f3588c10b89c6047fb59d80c7474445997f4e10"}, + {file = "pulsar_client-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:497a59ac6b650835a3b2c502f53477e5c98e5226998ca3f17c0b0a3eb4d67d08"}, + {file = "pulsar_client-3.3.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:386e78ff52058d881780bae1f6e84ac9434ae0b01a8581755ca8cc0dc844a332"}, + {file = "pulsar_client-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e4ecb780df58bcfd3918590bd3ff31ed79bccfbef3a1a60370642eb1e14a9d2"}, + {file = "pulsar_client-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ce1e215c252f22a6f26ca5e9076826041a04d88dc213b92c86b524be2774a64"}, + {file = "pulsar_client-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:88b0fd5be73a4103986b9dbe3a66468cf8829371e34af87ff8f216e3980f4cbe"}, + {file = "pulsar_client-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33656450536d83eed1563ff09692c2c415fb199d88e9ed97d701ca446a119e1b"}, + {file = "pulsar_client-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:ce33de700b06583df8777e139d68cb4b4b3d0a2eac168d74278d8935f357fb10"}, + {file = "pulsar_client-3.3.0-cp37-cp37m-macosx_10_15_universal2.whl", hash = "sha256:7b5dd25cf778d6c980d36c53081e843ea272afe7af4f0ad6394ae9513f94641b"}, + {file = "pulsar_client-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33c4e6865fda62a2e460f823dce4d49ac2973a4459b8ff99eda5fdd6aaaebf46"}, + {file = "pulsar_client-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1810ddc623c8de2675d17405ce47057a9a2b92298e708ce4d9564847f5ad904"}, + {file = "pulsar_client-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8259c3b856eb6deaa1f93dce893ab18d99d36d102da5612c8e97a4fb41b70ab1"}, + {file = "pulsar_client-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5e7a48b2e505cde758fd51a601b5da0671fa98c9baee38362aaaa3ab2b930c28"}, + {file = "pulsar_client-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ede264385d47257b2f2b08ecde9181ec5338bea5639cc543d1856f01736778d2"}, + {file = "pulsar_client-3.3.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:0f64c62746ccd5b65a0c505f5f40b9af1f147eb1fa2d8f9c90cd5c8b92dd8597"}, + {file = "pulsar_client-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b84a20c9012e3c4ef1b7085acd7467197118c090b378dec27d773fb79d91556"}, + {file = "pulsar_client-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e15fa696e275ccb66d0791fdc19c4dea0420d81349c8055e485b134125e14f"}, + {file = "pulsar_client-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:72cbb1bdcba2dd1265296b5ba65331622ee89c16db75edaad46dd7b90c6dd447"}, + {file = "pulsar_client-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d54dd12955bf587dd46d9184444af5e853d9da2a14bbfb739ed2c7c3b78ce280"}, + {file = "pulsar_client-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:43f98afdf0334b2b957a4d96f97a1fe8a7f7fd1e2631d40c3f00b4162f396485"}, + {file = "pulsar_client-3.3.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:efe7c1e6a96daccc522c3567b6847ffa54c13e0f510d9a427b4aeff9fbebe54b"}, + {file = "pulsar_client-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f28e94420090fceeb38e23fc744f3edf8710e48314ef5927d2b674a1d1e43ee0"}, + {file = "pulsar_client-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42c8f3eaa98e2351805ecb6efb6d5fedf47a314a3ce6af0e05ea1449ea7244ed"}, + {file = "pulsar_client-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5e69750f8ae57e55fddf97b459ce0d8b38b2bb85f464a71e871ee6a86d893be7"}, + {file = "pulsar_client-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7e147e5ba460c1818bc05254279a885b4e552bcafb8961d40e31f98d5ff46628"}, + {file = "pulsar_client-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:694530af1d6c75fb81456fb509778c1868adee31e997ddece6e21678200182ea"}, ] [package.dependencies] @@ -5187,17 +5178,17 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pypdf" -version = "3.15.2" +version = "3.15.4" description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" optional = false python-versions = ">=3.6" files = [ - {file = "pypdf-3.15.2-py3-none-any.whl", hash = "sha256:f6e598292be34187287a609c72815c1502b3dc2c997b374ba0870ce79d2e975a"}, - {file = "pypdf-3.15.2.tar.gz", hash = "sha256:cdf7d75ebb8901f3352cf9488c5f662c6de9c52e432c429d15cada67ba372fce"}, + {file = "pypdf-3.15.4-py3-none-any.whl", hash = "sha256:791f0a52ddf390709f1f1b0c05c4d8cde13829b4f7cb91b4003b9bdd352bc944"}, + {file = "pypdf-3.15.4.tar.gz", hash = "sha256:a2780ed01dc4da23ac1542209f58fd3d951d8dd37c3c0309d123cd2f2679fb03"}, ] [package.dependencies] -typing_extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} +typing_extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.10\""} [package.extras] crypto = ["PyCryptodome", "cryptography"] @@ -6531,13 +6522,13 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] [[package]] name = "textual" -version = "0.34.0" +version = "0.35.1" description = "Modern Text User Interface framework" optional = true python-versions = ">=3.7,<4.0" files = [ - {file = "textual-0.34.0-py3-none-any.whl", hash = "sha256:c695866acd8e85519eb0920cb921999ac5f58891ef7925e8b132e0eebc142e88"}, - {file = "textual-0.34.0.tar.gz", hash = "sha256:b66deee4afa9f6986c1bee973731d7dad2b169872377d238c9aad7141449b443"}, + {file = "textual-0.35.1-py3-none-any.whl", hash = "sha256:c4257ed3019cf8a2da2ac59ae59de5e66e04b95d482d065cfb3099f70fddd36f"}, + {file = "textual-0.35.1.tar.gz", hash = "sha256:70ca0bfe582f96dfa10179a9ab71329b8b15e750e26b7cee1fb4a67a981bbf36"}, ] [package.dependencies] @@ -6823,13 +6814,13 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "transformers" -version = "4.32.0" +version = "4.32.1" description = "State-of-the-art Machine Learning for JAX, PyTorch and TensorFlow" optional = true python-versions = ">=3.8.0" files = [ - {file = "transformers-4.32.0-py3-none-any.whl", hash = "sha256:32d8adf0ed76285508e7fd66657b4448ec1f882599ae6bf6f9c36bd7bf798402"}, - {file = "transformers-4.32.0.tar.gz", hash = "sha256:ca510f9688d2fe7347abbbfbd13f2f6dcd3c8349870c8d0ed98beed5f579b354"}, + {file = "transformers-4.32.1-py3-none-any.whl", hash = "sha256:b930d3dbd907a3f300cf49e54d63a56f8a0ab16b01a2c2a61ecff37c6de1da08"}, + {file = "transformers-4.32.1.tar.gz", hash = "sha256:1edc8ae1de357d97c3d36b04412aa63d55e6fc0c4b39b419a7d380ed947d2252"}, ] [package.dependencies] @@ -7257,33 +7248,33 @@ files = [ [[package]] name = "watchfiles" -version = "0.19.0" +version = "0.20.0" description = "Simple, modern and high performance file watching and code reload in python." optional = false python-versions = ">=3.7" files = [ - {file = "watchfiles-0.19.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7"}, - {file = "watchfiles-0.19.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056"}, - {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1"}, - {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e"}, - {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c"}, - {file = "watchfiles-0.19.0-cp37-abi3-win32.whl", hash = "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154"}, - {file = "watchfiles-0.19.0-cp37-abi3-win_amd64.whl", hash = "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8"}, - {file = "watchfiles-0.19.0-cp37-abi3-win_arm64.whl", hash = "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc"}, - {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193"}, - {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d"}, - {file = "watchfiles-0.19.0.tar.gz", hash = "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b"}, + {file = "watchfiles-0.20.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:3796312bd3587e14926013612b23066912cf45a14af71cf2b20db1c12dadf4e9"}, + {file = "watchfiles-0.20.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:d0002d81c89a662b595645fb684a371b98ff90a9c7d8f8630c82f0fde8310458"}, + {file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:570848706440373b4cd8017f3e850ae17f76dbdf1e9045fc79023b11e1afe490"}, + {file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a0351d20d03c6f7ad6b2e8a226a5efafb924c7755ee1e34f04c77c3682417fa"}, + {file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:007dcc4a401093010b389c044e81172c8a2520dba257c88f8828b3d460c6bb38"}, + {file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0d82dbc1832da83e441d112069833eedd4cf583d983fb8dd666fbefbea9d99c0"}, + {file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99f4c65fd2fce61a571b2a6fcf747d6868db0bef8a934e8ca235cc8533944d95"}, + {file = "watchfiles-0.20.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5392dd327a05f538c56edb1c6ebba6af91afc81b40822452342f6da54907bbdf"}, + {file = "watchfiles-0.20.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:08dc702529bb06a2b23859110c214db245455532da5eaea602921687cfcd23db"}, + {file = "watchfiles-0.20.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d4e66a857621584869cfbad87039e65dadd7119f0d9bb9dbc957e089e32c164"}, + {file = "watchfiles-0.20.0-cp37-abi3-win32.whl", hash = "sha256:a03d1e6feb7966b417f43c3e3783188167fd69c2063e86bad31e62c4ea794cc5"}, + {file = "watchfiles-0.20.0-cp37-abi3-win_amd64.whl", hash = "sha256:eccc8942bcdc7d638a01435d915b913255bbd66f018f1af051cd8afddb339ea3"}, + {file = "watchfiles-0.20.0-cp37-abi3-win_arm64.whl", hash = "sha256:b17d4176c49d207865630da5b59a91779468dd3e08692fe943064da260de2c7c"}, + {file = "watchfiles-0.20.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d97db179f7566dcf145c5179ddb2ae2a4450e3a634eb864b09ea04e68c252e8e"}, + {file = "watchfiles-0.20.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:835df2da7a5df5464c4a23b2d963e1a9d35afa422c83bf4ff4380b3114603644"}, + {file = "watchfiles-0.20.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:608cd94a8767f49521901aff9ae0c92cc8f5a24d528db7d6b0295290f9d41193"}, + {file = "watchfiles-0.20.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89d1de8218874925bce7bb2ae9657efc504411528930d7a83f98b1749864f2ef"}, + {file = "watchfiles-0.20.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:13f995d5152a8ba4ed7c2bbbaeee4e11a5944defc7cacd0ccb4dcbdcfd78029a"}, + {file = "watchfiles-0.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:9b5c8d3be7b502f8c43a33c63166ada8828dbb0c6d49c8f9ce990a96de2f5a49"}, + {file = "watchfiles-0.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e43af4464daa08723c04b43cf978ab86cc55c684c16172622bdac64b34e36af0"}, + {file = "watchfiles-0.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87d9e1f75c4f86c93d73b5bd1ebe667558357548f11b4f8af4e0e272f79413ce"}, + {file = "watchfiles-0.20.0.tar.gz", hash = "sha256:728575b6b94c90dd531514677201e8851708e6e4b5fe7028ac506a200b622019"}, ] [package.dependencies] @@ -7302,13 +7293,13 @@ files = [ [[package]] name = "weaviate-client" -version = "3.23.0" +version = "3.23.2" description = "A python native Weaviate client" optional = false python-versions = ">=3.8" files = [ - {file = "weaviate-client-3.23.0.tar.gz", hash = "sha256:3ffd7f1460c9e32755d84d4f5fc63dfc0bd990dbe2c3dc20d5c68119d467680e"}, - {file = "weaviate_client-3.23.0-py3-none-any.whl", hash = "sha256:3d3bb75c1d96b2b71e213c5eb885ae3e3f42e4304955383c467d100187d9ff8e"}, + {file = "weaviate-client-3.23.2.tar.gz", hash = "sha256:1c8c94df032dd2fa5a4ea615fc69ccb983ffad5cc02974f78c793839e61ac150"}, + {file = "weaviate_client-3.23.2-py3-none-any.whl", hash = "sha256:88ffc38cca07806d64726cc74bc194c7da50b222aa4e2cd129f4c1f5e53e9b61"}, ] [package.dependencies] @@ -7746,4 +7737,4 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.11" -content-hash = "8ad605e7ea30f2819dbc03eac6c2e67576a98d1efa4890912414a7568fc27441" +content-hash = "72ad24a89f3831382fe4b7c55dbd5c45dad1508ff6c1a723651fbb9e22ca3f65" diff --git a/pyproject.toml b/pyproject.toml index 01e04fd5d..6a908fb4b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,6 +82,7 @@ passlib = "^1.7.4" bcrypt = "^4.0.1" python-jose = "^3.3.0" metaphor-python = "^0.1.11" +markupsafe = "^2.1.3" [tool.poetry.group.dev.dependencies] black = "^23.1.0" @@ -99,6 +100,7 @@ types-appdirs = "^1.4.3.5" types-pyyaml = "^6.0.12.8" types-python-jose = "^3.3.4.8" types-passlib = "^1.7.7.13" +pywin32 = { version = "^306", markers = "sys_platform == 'win32'" } [tool.poetry.extras] From b3c2fd26a545547a4aa392f26cf137e04bbc2fef Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 16:14:27 -0300 Subject: [PATCH 14/71] =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20fix=20impo?= =?UTF-8?q?rt=20statements=20for=20read=5Fsecret=5Ffrom=5Ffile=20and=20wri?= =?UTF-8?q?te=5Fsecret=5Fto=5Ffile=20functions=20=F0=9F=94=92=20chore(util?= =?UTF-8?q?s.py):=20add=20write=5Fsecret=5Fto=5Ffile=20and=20read=5Fsecret?= =?UTF-8?q?=5Ffrom=5Ffile=20functions=20to=20handle=20secret=20key=20file?= =?UTF-8?q?=20read/write=20operations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/services/settings/base.py | 42 +++++++++---------- .../langflow/services/settings/utils.py | 17 ++++++++ 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/backend/langflow/services/settings/base.py b/src/backend/langflow/services/settings/base.py index 788c025b1..245f3aa9e 100644 --- a/src/backend/langflow/services/settings/base.py +++ b/src/backend/langflow/services/settings/base.py @@ -1,7 +1,7 @@ import contextlib import json import secrets -from langflow.services.settings.utils import set_secure_permissions +from langflow.services.settings.utils import read_secret_from_file, write_secret_to_file import orjson import os from shutil import copy2 @@ -55,31 +55,27 @@ class Settings(BaseSettings): @validator("SECRET_KEY", pre=True) def get_secret_key(cls, value, values): - if not value: + config_dir = values.get("CONFIG_DIR") + + if not config_dir: + logger.debug("No CONFIG_DIR provided, not saving secret key") + return value or secrets.token_urlsafe(32) + + secret_key_path = Path(config_dir) / "secret_key" + + if value: + logger.debug("Secret key provided") + write_secret_to_file(secret_key_path, value) + else: logger.debug("No secret key provided, generating a random one") - if config_dir := values.get("CONFIG_DIR"): - secret_key_path = Path(config_dir) / "secret_key" - - if secret_key_path.exists(): - with open(secret_key_path, "rb") as f: - value = f.read() - logger.debug("Loaded secret key") - else: - value = secrets.token_urlsafe(32) - - with open(secret_key_path, "wb") as f: - f.write(value) - - # Limit the file permissions - try: - set_secure_permissions(secret_key_path) - except Exception: - logger.error("Failed to set secure permissions on secret key") - - logger.debug("Saved secret key") + if secret_key_path.exists(): + value = read_secret_from_file(secret_key_path) + logger.debug("Loaded secret key") else: - logger.debug("No CONFIG_DIR provided, not saving secret key") + value = secrets.token_urlsafe(32) + write_secret_to_file(secret_key_path, value) + logger.debug("Saved secret key") return value diff --git a/src/backend/langflow/services/settings/utils.py b/src/backend/langflow/services/settings/utils.py index e9dc5d964..99b8d2ab8 100644 --- a/src/backend/langflow/services/settings/utils.py +++ b/src/backend/langflow/services/settings/utils.py @@ -1,6 +1,9 @@ import os +from pathlib import Path import platform +from langflow.utils.logger import logger + def set_secure_permissions(file_path): if platform.system() in ["Linux", "Darwin"]: # Unix/Linux/Mac @@ -28,3 +31,17 @@ def set_secure_permissions(file_path): ) else: print("Unsupported OS") + + +def write_secret_to_file(path: Path, value: str) -> None: + with path.open("wb") as f: + f.write(value) + try: + set_secure_permissions(path) + except Exception: + logger.error("Failed to set secure permissions on secret key") + + +def read_secret_from_file(path: Path) -> str: + with path.open("rb") as f: + return f.read() From 269116b8347de04cc22352305dfbc59ccd98d587 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 16:25:52 -0300 Subject: [PATCH 15/71] =?UTF-8?q?=F0=9F=90=9B=20fix(test=5Fcli.py):=20conv?= =?UTF-8?q?ert=20temp=5Fdir=20to=20string=20before=20checking=20if=20it=20?= =?UTF-8?q?is=20in=20COMPONENTS=5FPATH=20to=20ensure=20comparison=20correc?= =?UTF-8?q?tness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_cli.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index 408500d7a..c990ef9e8 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -27,4 +27,4 @@ def test_components_path(runner, client, default_settings): ) assert result.exit_code == 0, result.stdout settings_manager = utils.get_settings_manager() - assert temp_dir in settings_manager.settings.COMPONENTS_PATH + assert str(temp_dir) in settings_manager.settings.COMPONENTS_PATH From 35e24610aff53861149356f9524ee22cef7a0303 Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Wed, 30 Aug 2023 17:29:00 -0300 Subject: [PATCH 16/71] Refactor: Add trim() to login form --- src/frontend/src/pages/loginPage/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/loginPage/index.tsx b/src/frontend/src/pages/loginPage/index.tsx index 14e04708b..c64fc8325 100644 --- a/src/frontend/src/pages/loginPage/index.tsx +++ b/src/frontend/src/pages/loginPage/index.tsx @@ -31,8 +31,8 @@ export default function LoginPage(): JSX.Element { function signIn() { const user: LoginType = { - username: username, - password: password, + username: username.trim(), + password: password.trim(), }; onLogin(user) .then((user) => { From eacf558e70a4b92afa98b26f9ca5eba33b4556d5 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 17:29:07 -0300 Subject: [PATCH 17/71] =?UTF-8?q?=F0=9F=90=9B=20fix(chat.py):=20close=20we?= =?UTF-8?q?bsocket=20connection=20with=20status=20code=201008=20and=20reas?= =?UTF-8?q?on=20"Unauthorized"=20if=20user=20is=20not=20authenticated=20or?= =?UTF-8?q?=20inactive=20=F0=9F=90=9B=20fix(auth/utils.py):=20raise=20cred?= =?UTF-8?q?entials=5Fexception=20if=20token=20has=20expired?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 17 ++++++++++++++--- src/backend/langflow/services/auth/utils.py | 4 ++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 83d85b719..18c8a8a74 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -18,6 +18,10 @@ from langflow.services.utils import get_session from langflow.utils.logger import logger from cachetools import LRUCache from sqlmodel import Session +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from langflow.services.chat.manager import ChatManager router = APIRouter(tags=["Chat"]) @@ -33,16 +37,23 @@ async def chat( ): """Websocket endpoint for chat.""" try: + await websocket.accept() user = await get_current_user(token, db) + if not user: + await websocket.close( + code=status.WS_1008_POLICY_VIOLATION, reason="Unauthorized" + ) if not user.is_active: - raise HTTPException(status_code=401, detail="Invalid token") - chat_manager = service_manager.get(ServiceType.CHAT_MANAGER) + await websocket.close( + code=status.WS_1008_POLICY_VIOLATION, reason="Unauthorized" + ) + + chat_manager: "ChatManager" = service_manager.get(ServiceType.CHAT_MANAGER) if client_id in chat_manager.in_memory_cache: await chat_manager.handle_websocket(client_id, websocket) else: # We accept the connection but close it immediately # if the flow is not built yet - await websocket.accept() message = "Please, build the flow before sending messages" await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=message) except WebSocketException as exc: diff --git a/src/backend/langflow/services/auth/utils.py b/src/backend/langflow/services/auth/utils.py index a8e3e1790..a434fefcb 100644 --- a/src/backend/langflow/services/auth/utils.py +++ b/src/backend/langflow/services/auth/utils.py @@ -88,6 +88,10 @@ async def get_current_user( ) user_id: UUID = payload.get("sub") # type: ignore token_type: str = payload.get("type") # type: ignore + if expires := payload.get("exp", None): + expires_datetime = datetime.fromtimestamp(expires) + if datetime.now(timezone.utc) > expires_datetime: + raise credentials_exception if user_id is None or token_type: raise credentials_exception From a8b9c08a9d9674ea37c447d2d54d7471f65e3c1e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 17:39:51 -0300 Subject: [PATCH 18/71] =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20fix=20issu?= =?UTF-8?q?e=20with=20loading=20and=20saving=20secret=20key=20in=20Setting?= =?UTF-8?q?s=20class=20=F0=9F=90=9B=20fix(utils.py):=20fix=20issue=20with?= =?UTF-8?q?=20writing=20secret=20key=20to=20file=20in=20write=5Fsecret=5Ft?= =?UTF-8?q?o=5Ffile=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/settings/base.py | 4 ++++ src/backend/langflow/services/settings/utils.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/services/settings/base.py b/src/backend/langflow/services/settings/base.py index 245f3aa9e..4df77f8b2 100644 --- a/src/backend/langflow/services/settings/base.py +++ b/src/backend/langflow/services/settings/base.py @@ -72,6 +72,10 @@ class Settings(BaseSettings): if secret_key_path.exists(): value = read_secret_from_file(secret_key_path) logger.debug("Loaded secret key") + if not value: + value = secrets.token_urlsafe(32) + write_secret_to_file(secret_key_path, value) + logger.debug("Saved secret key") else: value = secrets.token_urlsafe(32) write_secret_to_file(secret_key_path, value) diff --git a/src/backend/langflow/services/settings/utils.py b/src/backend/langflow/services/settings/utils.py index 99b8d2ab8..5eb4cd787 100644 --- a/src/backend/langflow/services/settings/utils.py +++ b/src/backend/langflow/services/settings/utils.py @@ -35,7 +35,7 @@ def set_secure_permissions(file_path): def write_secret_to_file(path: Path, value: str) -> None: with path.open("wb") as f: - f.write(value) + f.write(value.encode("utf-8")) try: set_secure_permissions(path) except Exception: From 4739372e201a2b2028c5deb21556cda7f5aa4e7e Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Wed, 30 Aug 2023 17:40:18 -0300 Subject: [PATCH 19/71] Refactor: Add trim() to signUp page --- src/frontend/src/pages/signUpPage/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/pages/signUpPage/index.tsx b/src/frontend/src/pages/signUpPage/index.tsx index 92f3eff97..9a5de5991 100644 --- a/src/frontend/src/pages/signUpPage/index.tsx +++ b/src/frontend/src/pages/signUpPage/index.tsx @@ -33,8 +33,8 @@ export default function SignUp(): JSX.Element { function handleSignup(): void { const { username, password } = inputState; const newUser: UserInputType = { - username, - password, + username: username.trim(), + password: password.trim(), }; addUser(newUser) .then((user) => { From 61f0a93cc65a961195122a871e3a2a85342f4878 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 17:40:22 -0300 Subject: [PATCH 20/71] =?UTF-8?q?=F0=9F=94=A5=20refactor(manager.py):=20re?= =?UTF-8?q?move=20redundant=20code=20in=20connect=20method=20by=20removing?= =?UTF-8?q?=20unnecessary=20await=20websocket.accept()=20call?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/chat/manager.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/langflow/services/chat/manager.py b/src/backend/langflow/services/chat/manager.py index afc004d2d..6751e97e7 100644 --- a/src/backend/langflow/services/chat/manager.py +++ b/src/backend/langflow/services/chat/manager.py @@ -92,7 +92,6 @@ class ChatManager(Service): ) async def connect(self, client_id: str, websocket: WebSocket): - await websocket.accept() self.active_connections[client_id] = websocket def disconnect(self, client_id: str): From 158ef9a9eab7470eaf0d0d3c16dfbc97f91811bc Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Wed, 30 Aug 2023 17:48:17 -0300 Subject: [PATCH 21/71] Refactor: Remove duplicate login button and bring back button borders back --- .../src/components/headerComponent/index.tsx | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index c74cdaa76..8cbd5a591 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -32,7 +32,8 @@ export default function Header(): JSX.Element { )} {!autoLogin && location.pathname !== `/flow/${tabId}` && ( - { logout(); navigate("/login"); @@ -40,30 +41,20 @@ export default function Header(): JSX.Element { className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer mx-5" > Sign out - - )} - - {location.pathname === "/admin" && ( - { - navigate("/"); - }} - className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer" - > - Home - + )} {isAdmin && !autoLogin && location.pathname !== "/admin" && location.pathname !== `/flow/${tabId}` && ( - navigate("/admin")} > Admin page - + )}
From 163a7c49cd6384c6bb9a4d12b7b5d3f450ffcf79 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 17:51:57 -0300 Subject: [PATCH 22/71] =?UTF-8?q?=F0=9F=90=9B=20fix(utils.py):=20fix=20Typ?= =?UTF-8?q?eError=20when=20comparing=20offset-naive=20and=20offset-aware?= =?UTF-8?q?=20datetimes=20in=20get=5Fcurrent=5Fuser=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/auth/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/services/auth/utils.py b/src/backend/langflow/services/auth/utils.py index a434fefcb..1431ee615 100644 --- a/src/backend/langflow/services/auth/utils.py +++ b/src/backend/langflow/services/auth/utils.py @@ -89,7 +89,8 @@ async def get_current_user( user_id: UUID = payload.get("sub") # type: ignore token_type: str = payload.get("type") # type: ignore if expires := payload.get("exp", None): - expires_datetime = datetime.fromtimestamp(expires) + expires_datetime = datetime.fromtimestamp(expires, timezone.utc) + # TypeError: can't compare offset-naive and offset-aware datetimes if datetime.now(timezone.utc) > expires_datetime: raise credentials_exception From 9d7deccc533289c42773b6be8f077a1058bef823 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 17:54:58 -0300 Subject: [PATCH 23/71] =?UTF-8?q?=F0=9F=90=9B=20fix(chat.py):=20handle=20a?= =?UTF-8?q?nd=20log=20any=20exception=20that=20occurs=20in=20the=20chat=20?= =?UTF-8?q?websocket=20to=20prevent=20unhandled=20errors=20and=20provide?= =?UTF-8?q?=20better=20error=20messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 18c8a8a74..bd24806ff 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -59,6 +59,9 @@ async def chat( except WebSocketException as exc: logger.error(f"Websocket error: {exc}") await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) + except Exception as exc: + logger.error(f"Error in chat websocket: {exc}") + await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) @router.post("/build/init/{flow_id}", response_model=InitResponse, status_code=201) From 418bddd3222f3e15702dcfb7c2d731eab4adbe3c Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Wed, 30 Aug 2023 18:01:21 -0300 Subject: [PATCH 24/71] fix(formModal): encode the accessToken parameter in the chatEndpoint URL to handle special characters correctly The accessToken parameter in the chatEndpoint URL is now encoded using the encodeURIComponent function to handle special characters correctly. This ensures that the accessToken is properly passed to the chat endpoint without causing any issues. --- src/frontend/src/modals/formModal/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/modals/formModal/index.tsx b/src/frontend/src/modals/formModal/index.tsx index 01d6a0954..041132d0d 100644 --- a/src/frontend/src/modals/formModal/index.tsx +++ b/src/frontend/src/modals/formModal/index.tsx @@ -175,7 +175,7 @@ export default function FormModal({ return `${ isDevelopment ? "ws" : webSocketProtocol - }://${host}${chatEndpoint}?token=${accessToken}`; + }://${host}${chatEndpoint}?token=${encodeURIComponent(accessToken!)}`; } function handleWsMessage(data: any) { From 1407719f2fb8417d8b3a608ca29a727d7d0f27d7 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 18:12:03 -0300 Subject: [PATCH 25/71] =?UTF-8?q?=F0=9F=90=9B=20fix(chat.py):=20handle=20u?= =?UTF-8?q?nauthorized=20error=20in=20chat=20websocket=20to=20return=20WS?= =?UTF-8?q?=5F1008=5FPOLICY=5FVIOLATION=20status=20code=20and=20"Unauthori?= =?UTF-8?q?zed"=20reason?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index bd24806ff..eb6d13ef5 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -61,7 +61,12 @@ async def chat( await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) except Exception as exc: logger.error(f"Error in chat websocket: {exc}") - await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) + if "Could not validate credentials" in str(exc): + await websocket.close( + code=status.WS_1008_POLICY_VIOLATION, reason="Unauthorized" + ) + else: + await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) @router.post("/build/init/{flow_id}", response_model=InitResponse, status_code=201) From 3a90b0723517db7d20ed02e777b8671cf679f193 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 18:18:22 -0300 Subject: [PATCH 26/71] fix exception --- src/backend/langflow/api/v1/chat.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index eb6d13ef5..e4fc71343 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -61,6 +61,8 @@ async def chat( await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) except Exception as exc: logger.error(f"Error in chat websocket: {exc}") + if isinstance(exc, HTTPException): + exc = exc.detail if "Could not validate credentials" in str(exc): await websocket.close( code=status.WS_1008_POLICY_VIOLATION, reason="Unauthorized" From 60945ce883eb78a69f8bda27beceebe91e0deb50 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Wed, 30 Aug 2023 18:49:41 -0300 Subject: [PATCH 27/71] added check to onCloseWebsocket event --- src/frontend/src/controllers/API/index.ts | 2 +- src/frontend/src/modals/formModal/index.tsx | 175 ++++++++++---------- 2 files changed, 93 insertions(+), 84 deletions(-) diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 3e6c78801..780d784e5 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -312,7 +312,7 @@ export async function getHealth() { */ export async function getBuildStatus( flowId: string -): Promise { +): Promise> { return await api.get(`${BASE_URL_API}build/${flowId}/status`); } diff --git a/src/frontend/src/modals/formModal/index.tsx b/src/frontend/src/modals/formModal/index.tsx index 041132d0d..0a9bf7483 100644 --- a/src/frontend/src/modals/formModal/index.tsx +++ b/src/frontend/src/modals/formModal/index.tsx @@ -8,7 +8,7 @@ import { classNames } from "../../utils/utils"; import ChatInput from "./chatInput"; import ChatMessage from "./chatMessage"; -import _ from "lodash"; +import _, { set } from "lodash"; import AccordionComponent from "../../components/AccordionComponent"; import IconComponent from "../../components/genericIconComponent"; import ToggleShadComponent from "../../components/toggleShadComponent"; @@ -27,6 +27,7 @@ import { AuthContext } from "../../contexts/authContext"; import { TabsContext } from "../../contexts/tabsContext"; import { TabsState } from "../../types/tabs"; import { validateNodes } from "../../utils/reactflowUtils"; +import { getBuildStatus } from "../../controllers/API"; export default function FormModal({ flow, @@ -155,9 +156,21 @@ export default function FormModal({ function handleOnClose(event: CloseEvent): void { if (isOpen.current) { + getBuildStatus(flow.id).then((response) => { + if (response.data.built) { + connectWS(); + } + else { + setErrorData({ + title: "Please build the flow again before using the chat." + }) + } + }).catch((error) => { + setErrorData({title:error.data?.detail?error.data.detail:error.message}) + + }); setErrorData({ title: event.reason }); setTimeout(() => { - connectWS(); setLockChat(false); }, 1000); } @@ -173,9 +186,8 @@ export default function FormModal({ const host = isDevelopment ? "localhost:7860" : window.location.host; const chatEndpoint = `/api/v1/chat/${chatId}`; - return `${ - isDevelopment ? "ws" : webSocketProtocol - }://${host}${chatEndpoint}?token=${encodeURIComponent(accessToken!)}`; + return `${isDevelopment ? "ws" : webSocketProtocol + }://${host}${chatEndpoint}?token=${encodeURIComponent(accessToken!)}`; } function handleWsMessage(data: any) { @@ -197,20 +209,20 @@ export default function FormModal({ newChatHistory.push( chatItem.files ? { - isSend: !chatItem.is_bot, - message: chatItem.message, - template: chatItem.template, - thought: chatItem.intermediate_steps, - files: chatItem.files, - chatKey: chatItem.chatKey, - } + isSend: !chatItem.is_bot, + message: chatItem.message, + template: chatItem.template, + thought: chatItem.intermediate_steps, + files: chatItem.files, + chatKey: chatItem.chatKey, + } : { - isSend: !chatItem.is_bot, - message: chatItem.message, - template: chatItem.template, - thought: chatItem.intermediate_steps, - chatKey: chatItem.chatKey, - } + isSend: !chatItem.is_bot, + message: chatItem.message, + template: chatItem.template, + thought: chatItem.intermediate_steps, + chatKey: chatItem.chatKey, + } ); } } @@ -260,7 +272,6 @@ export default function FormModal({ }; newWs.onmessage = (event) => { const data = JSON.parse(event.data); - console.log("Received data:", data); handleWsMessage(data); //get chat history }; @@ -268,7 +279,6 @@ export default function FormModal({ handleOnClose(event); }; newWs.onerror = (ev) => { - console.log(ev, "error"); if (flow.id === "") { connectWS(); } else { @@ -294,7 +304,6 @@ export default function FormModal({ useEffect(() => { connectWS(); return () => { - console.log("unmount"); console.log(ws); if (ws.current) { ws.current.close(); @@ -433,73 +442,73 @@ export default function FormModal({ {tabsState[id.current]?.formKeysData?.input_keys ? Object.keys( - tabsState[id.current].formKeysData.input_keys! - ).map((key, index) => ( -
- - - {key} - + tabsState[id.current].formKeysData.input_keys! + ).map((key, index) => ( +
+ + + {key} + -
{ - event.stopPropagation(); - }} - > - - handleOnCheckedChange(value, key) - } - size="small" - disabled={tabsState[ - id.current - ].formKeysData.handle_keys!.some( - (t) => t === key - )} - /> -
+
{ + event.stopPropagation(); + }} + > + + handleOnCheckedChange(value, key) + } + size="small" + disabled={tabsState[ + id.current + ].formKeysData.handle_keys!.some( + (t) => t === key + )} + />
- } - key={index} - keyValue={key} - > -
- {tabsState[id.current].formKeysData.handle_keys!.some( - (t) => t === key - ) && ( +
+ } + key={index} + keyValue={key} + > +
+ {tabsState[id.current].formKeysData.handle_keys!.some( + (t) => t === key + ) && (
Source: Component
)} - -
-
-
- )) + +
+ +
+ )) : null} {tabsState[id.current].formKeysData.memory_keys!.map( (key, index) => ( @@ -513,7 +522,7 @@ export default function FormModal({
{}} + setEnabled={() => { }} size="small" disabled={true} /> From 98dfc019344facbf073a3933fef529ea079d19f0 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 30 Aug 2023 18:58:12 -0300 Subject: [PATCH 28/71] =?UTF-8?q?=F0=9F=94=92=20refactor(auth.py):=20move?= =?UTF-8?q?=20SECRET=5FKEY=20logic=20to=20AuthSettings=20class=20to=20impr?= =?UTF-8?q?ove=20code=20organization=20and=20reusability=20=F0=9F=94=92=20?= =?UTF-8?q?refactor(base.py):=20remove=20SECRET=5FKEY=20field=20from=20Set?= =?UTF-8?q?tings=20class=20since=20it=20is=20now=20handled=20by=20AuthSett?= =?UTF-8?q?ings=20class=20=F0=9F=94=92=20refactor(manager.py):=20pass=20CO?= =?UTF-8?q?NFIG=5FDIR=20to=20AuthSettings=20constructor=20when=20creating?= =?UTF-8?q?=20an=20instance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/services/settings/auth.py | 42 +++++++++++++++++- .../langflow/services/settings/base.py | 44 +------------------ .../langflow/services/settings/manager.py | 2 +- 3 files changed, 42 insertions(+), 46 deletions(-) diff --git a/src/backend/langflow/services/settings/auth.py b/src/backend/langflow/services/settings/auth.py index ce1bfe108..7550d3ddd 100644 --- a/src/backend/langflow/services/settings/auth.py +++ b/src/backend/langflow/services/settings/auth.py @@ -1,13 +1,21 @@ +from pathlib import Path from typing import Optional import secrets +from langflow.services.settings.utils import read_secret_from_file, write_secret_to_file -from pydantic import BaseSettings +from pydantic import BaseSettings, Field, validator from passlib.context import CryptContext +from langflow.utils.logger import logger class AuthSettings(BaseSettings): # Login settings - SECRET_KEY: str = secrets.token_hex(32) + CONFIG_DIR: str + SECRET_KEY: Optional[str] = Field( + None, + description="Secret key for JWT. If not provided, a random one will be generated.", + env="LANGFLOW_SECRET_KEY", + ) ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 REFRESH_TOKEN_EXPIRE_MINUTES: int = 70 @@ -31,3 +39,33 @@ class AuthSettings(BaseSettings): validate_assignment = True extra = "ignore" env_prefix = "LANGFLOW_" + + @validator("SECRET_KEY", pre=True) + def get_secret_key(cls, value, values): + config_dir = values.get("CONFIG_DIR") + + if not config_dir: + logger.debug("No CONFIG_DIR provided, not saving secret key") + return value or secrets.token_urlsafe(32) + + secret_key_path = Path(config_dir) / "secret_key" + + if value: + logger.debug("Secret key provided") + write_secret_to_file(secret_key_path, value) + else: + logger.debug("No secret key provided, generating a random one") + + if secret_key_path.exists(): + value = read_secret_from_file(secret_key_path) + logger.debug("Loaded secret key") + if not value: + value = secrets.token_urlsafe(32) + write_secret_to_file(secret_key_path, value) + logger.debug("Saved secret key") + else: + value = secrets.token_urlsafe(32) + write_secret_to_file(secret_key_path, value) + logger.debug("Saved secret key") + + return value diff --git a/src/backend/langflow/services/settings/base.py b/src/backend/langflow/services/settings/base.py index 4df77f8b2..00cd2085f 100644 --- a/src/backend/langflow/services/settings/base.py +++ b/src/backend/langflow/services/settings/base.py @@ -1,7 +1,5 @@ import contextlib import json -import secrets -from langflow.services.settings.utils import read_secret_from_file, write_secret_to_file import orjson import os from shutil import copy2 @@ -9,7 +7,7 @@ from typing import Optional, List from pathlib import Path import yaml -from pydantic import BaseSettings, Field, root_validator, validator +from pydantic import BaseSettings, root_validator, validator from langflow.utils.logger import logger # BASE_COMPONENTS_PATH = str(Path(__file__).parent / "components") @@ -43,46 +41,6 @@ class Settings(BaseSettings): REMOVE_API_KEYS: bool = False COMPONENTS_PATH: List[str] = [] - # Login settings - SECRET_KEY: Optional[str] = Field(None, env="LANGFLOW_SECRET_KEY") - - ALGORITHM: str = "HS256" - ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 - REFRESH_TOKEN_EXPIRE_MINUTES: int = 70 - # If AUTO_LOGIN = True - # > The application does not request login and logs in automatically as a super user. - AUTO_LOGIN: bool = True - - @validator("SECRET_KEY", pre=True) - def get_secret_key(cls, value, values): - config_dir = values.get("CONFIG_DIR") - - if not config_dir: - logger.debug("No CONFIG_DIR provided, not saving secret key") - return value or secrets.token_urlsafe(32) - - secret_key_path = Path(config_dir) / "secret_key" - - if value: - logger.debug("Secret key provided") - write_secret_to_file(secret_key_path, value) - else: - logger.debug("No secret key provided, generating a random one") - - if secret_key_path.exists(): - value = read_secret_from_file(secret_key_path) - logger.debug("Loaded secret key") - if not value: - value = secrets.token_urlsafe(32) - write_secret_to_file(secret_key_path, value) - logger.debug("Saved secret key") - else: - value = secrets.token_urlsafe(32) - write_secret_to_file(secret_key_path, value) - logger.debug("Saved secret key") - - return value - @validator("CONFIG_DIR", pre=True, allow_reuse=True) def set_langflow_dir(cls, value): if not value: diff --git a/src/backend/langflow/services/settings/manager.py b/src/backend/langflow/services/settings/manager.py index 1a6c0feeb..67e06108e 100644 --- a/src/backend/langflow/services/settings/manager.py +++ b/src/backend/langflow/services/settings/manager.py @@ -35,5 +35,5 @@ class SettingsManager(Service): ) settings = Settings(**settings_dict) - auth_settings = AuthSettings() + auth_settings = AuthSettings(CONFIG_DIR=settings.CONFIG_DIR) return cls(settings, auth_settings) From c06cfce385d4df1495079e1d7f4232678468f4a6 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa Date: Wed, 30 Aug 2023 19:02:52 -0300 Subject: [PATCH 29/71] =?UTF-8?q?=F0=9F=90=9B=20fix(api.tsx):=20handle=20n?= =?UTF-8?q?ull=20values=20when=20calling=20login=20function=20to=20prevent?= =?UTF-8?q?=20potential=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/controllers/API/api.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx index 59fba4393..4c444ff37 100644 --- a/src/frontend/src/controllers/API/api.tsx +++ b/src/frontend/src/controllers/API/api.tsx @@ -33,7 +33,7 @@ function ApiInterceptor() { } const res = await renewAccessToken(refreshToken); - login(res.data.access_token, res.data.refresh_token); + login(res?.data?.access_token, res?.data?.refresh_token); try { if (error?.config?.headers) { delete error.config.headers["Authorization"]; From 19dd994c1286cb5cf5e7ba022924ff2e53080310 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Tue, 29 Aug 2023 18:05:06 -0300 Subject: [PATCH 30/71] chore(frontend): update dependencies in package.json - Update "@emotion/react" to version "^11.11.1" - Update "@emotion/styled" to version "^11.11.0" - Update "@headlessui/react" to version "^1.7.17" - Update "@heroicons/react" to version "^2.0.18" - Update "@mui/material" to version "^5.14.7" - Update "@tabler/icons-react" to version "^2.32.0" - Update "@tailwindcss/forms" to version "^0.5.6" - Update "ace-builds" to version "^1.24.1" - Update "axios" to version "^1.5.0" - Update "class-variance-authority" to version "^0.6.1" - Update "dompurify" to version "^3.0.5" - Update "esbuild" to version "^0.17.19" - Update "react-error-boundary" to version "^4.0.11" - Update "react-icons" to version "^4.10.1" - Update "react-router-dom" to version "^6.15.0" - Update "react-tabs" to version "^6.0.2" - Update "react-tooltip" to version "^5.21.1" - Update "rehype-mathjax" to version "^4.0.3" - Update "shadcn-ui" to version "^0.2.3" - Update "tailwind-merge" to version "^1.14.0" - Update "tailwindcss-animate" to version "^1.0.7" chore(frontend): update devDependencies in package.json - Update "@swc/cli" to version "^0.1.62" - Update "@swc/core" to version "^1.3.80" - Update "@tailwindcss/typography" to version "^0.5.9" - Update "@testing-library/jest-dom" to version "^5.17.0" - Update "@testing-library/react" to version "^13.4.0" - Update "@testing-library/user-event" to version "^13.5.0" - Update "@types/lodash" to version "^4.14.197" - Update "@types/node" to version "^16.18.46" - Update "@types/react --- src/frontend/package-lock.json | 72 +++++++++++++++++----------------- src/frontend/package.json | 72 +++++++++++++++++----------------- 2 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index b8af76667..ea796cc6d 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -8,11 +8,11 @@ "name": "langflow", "version": "0.1.2", "dependencies": { - "@emotion/react": "^11.10.5", - "@emotion/styled": "^11.10.5", - "@headlessui/react": "^1.7.10", - "@heroicons/react": "^2.0.15", - "@mui/material": "^5.11.9", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@headlessui/react": "^1.7.17", + "@heroicons/react": "^2.0.18", + "@mui/material": "^5.14.7", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.4", @@ -29,20 +29,20 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.6", - "@tabler/icons-react": "^2.18.0", - "@tailwindcss/forms": "^0.5.3", + "@tabler/icons-react": "^2.32.0", + "@tailwindcss/forms": "^0.5.6", "@tailwindcss/line-clamp": "^0.4.4", "@types/axios": "^0.14.0", "accordion": "^3.0.2", - "ace-builds": "^1.16.0", + "ace-builds": "^1.24.1", "add": "^2.0.6", "ansi-to-html": "^0.7.2", - "axios": "^1.3.2", + "axios": "^1.5.0", "base64-js": "^1.5.1", - "class-variance-authority": "^0.6.0", + "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", - "dompurify": "^3.0.4", - "esbuild": "^0.17.18", + "dompurify": "^3.0.5", + "esbuild": "^0.17.19", "lodash": "^4.17.21", "lucide-react": "^0.233.0", "moment": "^2.29.4", @@ -50,51 +50,51 @@ "react-ace": "^10.1.0", "react-cookie": "^4.1.1", "react-dom": "^18.2.0", - "react-error-boundary": "^4.0.2", - "react-icons": "^4.8.0", + "react-error-boundary": "^4.0.11", + "react-icons": "^4.10.1", "react-laag": "^2.0.5", "react-markdown": "^8.0.7", - "react-router-dom": "^6.8.1", + "react-router-dom": "^6.15.0", "react-syntax-highlighter": "^15.5.0", - "react-tabs": "^6.0.0", - "react-tooltip": "^5.13.1", + "react-tabs": "^6.0.2", + "react-tooltip": "^5.21.1", "reactflow": "^11.8.3", - "rehype-mathjax": "^4.0.2", + "rehype-mathjax": "^4.0.3", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", - "shadcn-ui": "^0.2.2", + "shadcn-ui": "^0.2.3", "short-unique-id": "^4.4.4", "switch": "^0.0.0", "table": "^6.8.1", - "tailwind-merge": "^1.13.0", - "tailwindcss-animate": "^1.0.5", + "tailwind-merge": "^1.14.0", + "tailwindcss-animate": "^1.0.7", "uuid": "^9.0.0", "vite-plugin-svgr": "^3.2.0", "web-vitals": "^2.1.4" }, "devDependencies": { "@swc/cli": "^0.1.62", - "@swc/core": "^1.3.62", + "@swc/core": "^1.3.80", "@tailwindcss/typography": "^0.5.9", - "@testing-library/jest-dom": "^5.16.5", + "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.5.2", - "@types/lodash": "^4.14.194", - "@types/node": "^16.18.12", - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "@types/uuid": "^9.0.1", - "@vitejs/plugin-react-swc": "^3.0.0", - "autoprefixer": "^10.4.14", - "daisyui": "^3.1.1", - "postcss": "^8.4.23", + "@types/lodash": "^4.14.197", + "@types/node": "^16.18.46", + "@types/react": "^18.2.21", + "@types/react-dom": "^18.2.7", + "@types/uuid": "^9.0.2", + "@vitejs/plugin-react-swc": "^3.3.2", + "autoprefixer": "^10.4.15", + "daisyui": "^3.6.3", + "postcss": "^8.4.29", "prettier": "^2.8.8", - "prettier-plugin-organize-imports": "^3.2.2", + "prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-tailwindcss": "^0.3.0", - "tailwindcss": "^3.3.2", - "typescript": "^5.0.2", - "vite": "^4.3.9" + "tailwindcss": "^3.3.3", + "typescript": "^5.2.2", + "vite": "^4.4.9" } }, "node_modules/@adobe/css-tools": { diff --git a/src/frontend/package.json b/src/frontend/package.json index bd6e031df..8d7d25d88 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -3,11 +3,11 @@ "version": "0.1.2", "private": true, "dependencies": { - "@emotion/react": "^11.10.5", - "@emotion/styled": "^11.10.5", - "@headlessui/react": "^1.7.10", - "@heroicons/react": "^2.0.15", - "@mui/material": "^5.11.9", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@headlessui/react": "^1.7.17", + "@heroicons/react": "^2.0.18", + "@mui/material": "^5.14.7", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-dialog": "^1.0.4", @@ -24,20 +24,20 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-tooltip": "^1.0.6", - "@tabler/icons-react": "^2.18.0", - "@tailwindcss/forms": "^0.5.3", + "@tabler/icons-react": "^2.32.0", + "@tailwindcss/forms": "^0.5.6", "@tailwindcss/line-clamp": "^0.4.4", "@types/axios": "^0.14.0", "accordion": "^3.0.2", - "ace-builds": "^1.16.0", + "ace-builds": "^1.24.1", "add": "^2.0.6", "ansi-to-html": "^0.7.2", - "axios": "^1.3.2", + "axios": "^1.5.0", "base64-js": "^1.5.1", - "class-variance-authority": "^0.6.0", + "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", - "dompurify": "^3.0.4", - "esbuild": "^0.17.18", + "dompurify": "^3.0.5", + "esbuild": "^0.17.19", "lodash": "^4.17.21", "lucide-react": "^0.233.0", "moment": "^2.29.4", @@ -45,24 +45,24 @@ "react-ace": "^10.1.0", "react-cookie": "^4.1.1", "react-dom": "^18.2.0", - "react-error-boundary": "^4.0.2", - "react-icons": "^4.8.0", + "react-error-boundary": "^4.0.11", + "react-icons": "^4.10.1", "react-laag": "^2.0.5", "react-markdown": "^8.0.7", - "react-router-dom": "^6.8.1", + "react-router-dom": "^6.15.0", "react-syntax-highlighter": "^15.5.0", - "react-tabs": "^6.0.0", - "react-tooltip": "^5.13.1", + "react-tabs": "^6.0.2", + "react-tooltip": "^5.21.1", "reactflow": "^11.8.3", - "rehype-mathjax": "^4.0.2", + "rehype-mathjax": "^4.0.3", "remark-gfm": "^3.0.1", "remark-math": "^5.1.1", - "shadcn-ui": "^0.2.2", + "shadcn-ui": "^0.2.3", "short-unique-id": "^4.4.4", "switch": "^0.0.0", "table": "^6.8.1", - "tailwind-merge": "^1.13.0", - "tailwindcss-animate": "^1.0.5", + "tailwind-merge": "^1.14.0", + "tailwindcss-animate": "^1.0.7", "uuid": "^9.0.0", "vite-plugin-svgr": "^3.2.0", "web-vitals": "^2.1.4" @@ -96,26 +96,26 @@ "proxy": "http://127.0.0.1:7860", "devDependencies": { "@swc/cli": "^0.1.62", - "@swc/core": "^1.3.62", + "@swc/core": "^1.3.80", "@tailwindcss/typography": "^0.5.9", - "@testing-library/jest-dom": "^5.16.5", + "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.5.2", - "@types/lodash": "^4.14.194", - "@types/node": "^16.18.12", - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "@types/uuid": "^9.0.1", - "@vitejs/plugin-react-swc": "^3.0.0", - "autoprefixer": "^10.4.14", - "daisyui": "^3.1.1", - "postcss": "^8.4.23", + "@types/lodash": "^4.14.197", + "@types/node": "^16.18.46", + "@types/react": "^18.2.21", + "@types/react-dom": "^18.2.7", + "@types/uuid": "^9.0.2", + "@vitejs/plugin-react-swc": "^3.3.2", + "autoprefixer": "^10.4.15", + "daisyui": "^3.6.3", + "postcss": "^8.4.29", "prettier": "^2.8.8", - "prettier-plugin-organize-imports": "^3.2.2", + "prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-tailwindcss": "^0.3.0", - "tailwindcss": "^3.3.2", - "typescript": "^5.0.2", - "vite": "^4.3.9" + "tailwindcss": "^3.3.3", + "typescript": "^5.2.2", + "vite": "^4.4.9" } } From ee27839009923d7bb58aa1c79a67911204859e04 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Wed, 30 Aug 2023 22:56:43 -0300 Subject: [PATCH 31/71] Added skeleton when loading all flows --- .../skeletonCardComponent/index.tsx | 16 ++++ src/frontend/src/components/ui/skeleton.tsx | 15 ++++ src/frontend/src/contexts/tabsContext.tsx | 11 ++- src/frontend/src/pages/MainPage/index.tsx | 75 ++++++++++++------- src/frontend/src/style/applies.css | 12 +++ src/frontend/src/types/tabs/index.ts | 1 + 6 files changed, 101 insertions(+), 29 deletions(-) create mode 100644 src/frontend/src/components/skeletonCardComponent/index.tsx create mode 100644 src/frontend/src/components/ui/skeleton.tsx diff --git a/src/frontend/src/components/skeletonCardComponent/index.tsx b/src/frontend/src/components/skeletonCardComponent/index.tsx new file mode 100644 index 000000000..a9857e4f4 --- /dev/null +++ b/src/frontend/src/components/skeletonCardComponent/index.tsx @@ -0,0 +1,16 @@ +import { Skeleton } from "../ui/skeleton"; + +export const SkeletonCardComponent = (): JSX.Element => { + return ( +
+
+ + +
+
+ + +
+
+ ); +}; diff --git a/src/frontend/src/components/ui/skeleton.tsx b/src/frontend/src/components/ui/skeleton.tsx new file mode 100644 index 000000000..6556585a4 --- /dev/null +++ b/src/frontend/src/components/ui/skeleton.tsx @@ -0,0 +1,15 @@ +import { cn } from "../../utils/utils" + +function Skeleton({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ) +} + +export { Skeleton } diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index 114c1ff93..97ad50329 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -39,6 +39,7 @@ const TabsContextInitialValue: TabsContextType = { save: () => {}, tabId: "", setTabId: (index: string) => {}, + isLoading: true, flows: [], removeFlow: (id: string) => {}, addFlow: async (flowData?: any) => "", @@ -76,6 +77,8 @@ export function TabsProvider({ children }: { children: ReactNode }) { const [tabId, setTabId] = useState(""); + const [isLoading, setIsLoading] = useState(true); + const [flows, setFlows] = useState>([]); const [id, setId] = useState(uid()); const { templates, reactFlowInstance } = useContext(typesContext); @@ -87,10 +90,10 @@ export function TabsProvider({ children }: { children: ReactNode }) { const [getTweak, setTweak] = useState([]); useEffect(() => { - if(!isAuthenticated){ + if (!isAuthenticated) { hardReset(); } - }, [isAuthenticated]) + }, [isAuthenticated]); const newNodeId = useRef(uid()); function incrementNodeId() { @@ -122,11 +125,13 @@ export function TabsProvider({ children }: { children: ReactNode }) { } function refreshFlows() { + setIsLoading(true); getTabsDataFromDB().then((DbData) => { if (DbData && Object.keys(templates).length > 0) { try { processDBData(DbData); updateStateWithDbData(DbData); + setIsLoading(false); } catch (e) {} } }); @@ -235,6 +240,7 @@ export function TabsProvider({ children }: { children: ReactNode }) { setTabId(""); setFlows([]); + setIsLoading(true); setId(uid()); } @@ -647,6 +653,7 @@ export function TabsProvider({ children }: { children: ReactNode }) { paste, getTweak, setTweak, + isLoading, }} > {children} diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index 67412401a..442a43e2f 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -3,12 +3,20 @@ import { Link, useNavigate } from "react-router-dom"; import { CardComponent } from "../../components/cardComponent"; import IconComponent from "../../components/genericIconComponent"; import Header from "../../components/headerComponent"; +import { SkeletonCardComponent } from "../../components/skeletonCardComponent"; import { Button } from "../../components/ui/button"; import { USER_PROJECTS_HEADER } from "../../constants/constants"; import { TabsContext } from "../../contexts/tabsContext"; export default function HomePage(): JSX.Element { - const { flows, setTabId, downloadFlows, uploadFlows, addFlow, removeFlow } = - useContext(TabsContext); + const { + flows, + setTabId, + downloadFlows, + uploadFlows, + addFlow, + removeFlow, + isLoading, + } = useContext(TabsContext); // Set a null id useEffect(() => { @@ -16,6 +24,10 @@ export default function HomePage(): JSX.Element { }, []); const navigate = useNavigate(); + useEffect(() => { + console.log(isLoading); + }, [isLoading]); + // Personal flows display return ( <> @@ -62,31 +74,40 @@ export default function HomePage(): JSX.Element { Manage your personal projects. Download or upload your collection.
- {flows.map((flow, idx) => ( - - - - } - onDelete={() => { - removeFlow(flow.id); - }} - /> - ))} + {isLoading && flows.length == 0 ? ( + <> + + + + + + ) : ( + flows.map((flow, idx) => ( + + + + } + onDelete={() => { + removeFlow(flow.id); + }} + /> + )) + )}
diff --git a/src/frontend/src/style/applies.css b/src/frontend/src/style/applies.css index 4f6f9b3a5..685d81b05 100644 --- a/src/frontend/src/style/applies.css +++ b/src/frontend/src/style/applies.css @@ -126,6 +126,18 @@ @apply form-input block w-full truncate rounded-md border-border bg-background px-3 text-left shadow-sm placeholder:text-muted-foreground focus:border-ring focus:placeholder-transparent focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm; } + .skeleton-card { + @apply bg-background h-48 p-4 border rounded-lg flex flex-col gap-6; + } + + .skeleton-card-wrapper { + @apply flex items-center space-x-4; + } + + .skeleton-card-text { + @apply flex flex-col gap-3; + } + /* The same as primary-input but no-truncate */ .textarea-primary { @apply form-input block w-full rounded-md border-border bg-background px-3 text-left shadow-sm placeholder:text-muted-foreground focus:border-ring focus:placeholder-transparent focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 sm:text-sm; diff --git a/src/frontend/src/types/tabs/index.ts b/src/frontend/src/types/tabs/index.ts index a87cdb35e..036f82717 100644 --- a/src/frontend/src/types/tabs/index.ts +++ b/src/frontend/src/types/tabs/index.ts @@ -5,6 +5,7 @@ export type TabsContextType = { saveFlow: (flow: FlowType) => Promise; save: () => void; tabId: string; + isLoading: boolean; setTabId: (index: string) => void; flows: Array; removeFlow: (id: string) => void; From 03599541c24db41a8f89ee4c4abb357b30082092 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Thu, 31 Aug 2023 08:20:23 -0300 Subject: [PATCH 32/71] Added user dropdown instead of buttons --- .../src/components/headerComponent/index.tsx | 79 +++++++++++-------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index c74cdaa76..2a7219fed 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -7,8 +7,17 @@ import { alertContext } from "../../contexts/alertContext"; import { AuthContext } from "../../contexts/authContext"; import { darkContext } from "../../contexts/darkContext"; import { TabsContext } from "../../contexts/tabsContext"; +import { gradients } from "../../utils/styleUtils"; import IconComponent from "../genericIconComponent"; import { Button } from "../ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "../ui/dropdown-menu"; import { Separator } from "../ui/separator"; import MenuBar from "./components/menuBar"; @@ -17,7 +26,7 @@ export default function Header(): JSX.Element { const { dark, setDark } = useContext(darkContext); const { notificationCenter } = useContext(alertContext); const location = useLocation(); - const { logout, autoLogin, isAdmin } = useContext(AuthContext); + const { logout, autoLogin, isAdmin, userData } = useContext(AuthContext); const { stars } = useContext(darkContext); const navigate = useNavigate(); @@ -31,40 +40,6 @@ export default function Header(): JSX.Element { {flows.findIndex((f) => tabId === f.id) !== -1 && tabId !== "" && ( )} - {!autoLogin && location.pathname !== `/flow/${tabId}` && ( - { - logout(); - navigate("/login"); - }} - className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer mx-5" - > - Sign out - - )} - - {location.pathname === "/admin" && ( - { - navigate("/"); - }} - className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer" - > - Home - - )} - - {isAdmin && - !autoLogin && - location.pathname !== "/admin" && - location.pathname !== `/flow/${tabId}` && ( - navigate("/admin")} - > - Admin page - - )}
@@ -156,6 +131,40 @@ export default function Header(): JSX.Element { /> )} + {!autoLogin && ( + <> + + + +
From 08407abe9a9cfd5d21ff347cfe85e744621be03e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 10:20:20 -0300 Subject: [PATCH 33/71] =?UTF-8?q?=F0=9F=94=A7=20chore(main.py):=20add=20te?= =?UTF-8?q?ardown=5Fservices=20function=20to=20be=20called=20on=20app=20sh?= =?UTF-8?q?utdown=20event=20to=20properly=20clean=20up=20resources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/main.py b/src/backend/langflow/main.py index 57f3e34dc..f567e65bb 100644 --- a/src/backend/langflow/main.py +++ b/src/backend/langflow/main.py @@ -10,7 +10,7 @@ from langflow.api import router from langflow.interface.utils import setup_llm_caching from langflow.services.database.utils import initialize_database -from langflow.services.manager import initialize_services +from langflow.services.manager import initialize_services, teardown_services from langflow.utils.logger import configure @@ -40,6 +40,7 @@ def create_app(): app.on_event("startup")(initialize_services) app.on_event("startup")(initialize_database) app.on_event("startup")(setup_llm_caching) + app.on_event("shutdown")(teardown_services) return app From 91ea879e508bbb350a0d4df573668f8cf8c32432 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 10:20:40 -0300 Subject: [PATCH 34/71] =?UTF-8?q?=F0=9F=94=A7=20fix(base.py):=20make=20Ser?= =?UTF-8?q?vice=20class=20inherit=20from=20ABC=20to=20make=20it=20an=20abs?= =?UTF-8?q?tract=20base=20class=20=E2=9C=A8=20feat(manager.py):=20add=20de?= =?UTF-8?q?bug=20log=20messages=20for=20service=20creation=20and=20update?= =?UTF-8?q?=20to=20improve=20debugging=20=E2=9C=A8=20feat(manager.py):=20a?= =?UTF-8?q?dd=20teardown=20method=20to=20ServiceManager=20to=20teardown=20?= =?UTF-8?q?all=20services=20and=20clear=20state=20=E2=9C=A8=20feat(manager?= =?UTF-8?q?.py):=20add=20teardown=5Fservices=20function=20to=20teardown=20?= =?UTF-8?q?all=20services=20and=20clear=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/base.py | 8 +++++++- src/backend/langflow/services/manager.py | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/backend/langflow/services/base.py b/src/backend/langflow/services/base.py index 6bca6c4e2..aaa966047 100644 --- a/src/backend/langflow/services/base.py +++ b/src/backend/langflow/services/base.py @@ -1,2 +1,8 @@ -class Service: +from abc import ABC + + +class Service(ABC): name: str + + def teardown(self): + pass diff --git a/src/backend/langflow/services/manager.py b/src/backend/langflow/services/manager.py index e9895adab..bfe83fce8 100644 --- a/src/backend/langflow/services/manager.py +++ b/src/backend/langflow/services/manager.py @@ -1,5 +1,6 @@ from langflow.services.schema import ServiceType from typing import TYPE_CHECKING, List, Optional +from langflow.utils.logger import logger if TYPE_CHECKING: from langflow.services.factory import ServiceFactory @@ -42,6 +43,7 @@ class ServiceManager: """ Create a new service given its name, handling dependencies. """ + logger.debug(f"Create service {service_name}") self._validate_service_creation(service_name) # Create dependencies first @@ -74,9 +76,21 @@ class ServiceManager: Update a service by its name. """ if service_name in self.services: + logger.debug(f"Update service {service_name}") self.services.pop(service_name, None) self.get(service_name) + def teardown(self): + """ + Teardown all the services. + """ + for service in self.services.values(): + logger.debug(f"Teardown service {service.name}") + service.teardown() + self.services = {} + self.factories = {} + self.dependencies = {} + service_manager = ServiceManager() @@ -134,3 +148,10 @@ def initialize_session_manager(): session_manager_factory.SessionManagerFactory(), dependencies=[ServiceType.CACHE_MANAGER], ) + + +def teardown_services(): + """ + Teardown all the services. + """ + service_manager.teardown() From 29a616bc77813e816590c8fc2004ece4bfc52d7e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 10:20:53 -0300 Subject: [PATCH 35/71] =?UTF-8?q?=F0=9F=90=9B=20fix(utils.py):=20remove=20?= =?UTF-8?q?unnecessary=20code=20and=20simplify=20create=5Fsuper=5Fuser=20f?= =?UTF-8?q?unction=20=E2=9C=A8=20feat(utils.py):=20refactor=20create=5Fuse?= =?UTF-8?q?r=5Flongterm=5Ftoken=20to=20use=20settings=5Fmanager=20for=20us?= =?UTF-8?q?ername=20and=20password?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/auth/utils.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/backend/langflow/services/auth/utils.py b/src/backend/langflow/services/auth/utils.py index 1431ee615..a53a182c0 100644 --- a/src/backend/langflow/services/auth/utils.py +++ b/src/backend/langflow/services/auth/utils.py @@ -154,18 +154,12 @@ def create_super_user( username: Optional[str] = None, password: Optional[str] = None, ) -> User: - settings_manager = get_settings_manager() - - super_user = get_user_by_username( - db, username or settings_manager.auth_settings.FIRST_SUPERUSER - ) + super_user = get_user_by_username(db, username) if not super_user: super_user = User( - username=username or settings_manager.auth_settings.FIRST_SUPERUSER, - password=get_password_hash( - password or settings_manager.auth_settings.FIRST_SUPERUSER_PASSWORD - ), + username=username, + password=get_password_hash(password), is_superuser=True, is_active=True, last_login_at=None, @@ -179,7 +173,10 @@ def create_super_user( def create_user_longterm_token(db: Session = Depends(get_session)) -> dict: - super_user = create_super_user(db) + settings_manager = get_settings_manager() + username = settings_manager.auth_settings.FIRST_SUPERUSER + password = settings_manager.auth_settings.FIRST_SUPERUSER_PASSWORD + super_user = create_super_user(db, username=username, password=password) access_token_expires_longterm = timedelta(days=365) access_token = create_token( From 8d96c32c2b4a42dae66afaa562e6816a50cffefd Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 10:21:03 -0300 Subject: [PATCH 36/71] =?UTF-8?q?=F0=9F=94=A7=20chore(manager.py):=20add?= =?UTF-8?q?=20teardown=20method=20to=20DatabaseManager=20class=20for=20cle?= =?UTF-8?q?aning=20up=20the=20database=20=F0=9F=94=A7=20chore(manager.py):?= =?UTF-8?q?=20remove=20default=20superuser=20if=20auto=5Flogin=20is=20enab?= =?UTF-8?q?led=20during=20teardown=20to=20ensure=20clean=20database=20stat?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../langflow/services/database/manager.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/backend/langflow/services/database/manager.py b/src/backend/langflow/services/database/manager.py index 2b599a0ba..1159cbf7a 100644 --- a/src/backend/langflow/services/database/manager.py +++ b/src/backend/langflow/services/database/manager.py @@ -1,6 +1,7 @@ from pathlib import Path from typing import TYPE_CHECKING from langflow.services.base import Service +from langflow.services.database.models.user.crud import get_user_by_username from langflow.services.database.utils import Result, TableResults from langflow.services.utils import get_settings_manager from sqlalchemy import inspect @@ -159,3 +160,23 @@ class DatabaseManager(Service): ) logger.debug("Database and tables created successfully") + + def teardown(self): + logger.debug("Tearing down database") + try: + settings_manager = get_settings_manager() + # remove the default superuser if auto_login is enabled + # using the FIRST_SUPERUSER to get the user + if settings_manager.auth_settings.AUTO_LOGIN: + logger.debug("Removing default superuser") + username = settings_manager.auth_settings.FIRST_SUPERUSER + with Session(self.engine) as session: + user = get_user_by_username(session, username) + session.delete(user) + session.commit() + logger.debug("Default superuser removed") + + except Exception as exc: + logger.error(f"Error tearing down database: {exc}") + + self.engine.dispose() From d8c7450576b838ccbe21ed23a3e75257db0ed662 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 10:55:04 -0300 Subject: [PATCH 37/71] =?UTF-8?q?=F0=9F=94=A7=20chore(test=5Fuser.py):=20r?= =?UTF-8?q?efactor=20super=5Fuser=20fixture=20to=20use=20auth=20settings?= =?UTF-8?q?=20from=20settings=20manager=20for=20username=20and=20password?= =?UTF-8?q?=20=F0=9F=94=A7=20chore(test=5Fuser.py):=20refactor=20super=5Fu?= =?UTF-8?q?ser=20fixture=20to=20use=20auth=20settings=20from=20settings=20?= =?UTF-8?q?manager=20for=20username=20and=20password=20in=20create=5Fsuper?= =?UTF-8?q?=5Fuser=20function=20call?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_user.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_user.py b/tests/test_user.py index d734e4d61..35b724cc6 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -9,7 +9,13 @@ from langflow.services.database.models.user import UserUpdate @pytest.fixture def super_user(client, session): - return create_super_user(session) + settings_manager = get_settings_manager() + auth_settings = settings_manager.auth_settings + return create_super_user( + session, + username=auth_settings.FIRST_SUPERUSER, + password=auth_settings.FIRST_SUPERUSER_PASSWORD, + ) @pytest.fixture From fc0e8685151a61c1be7ef5e733e895f8275a758c Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Thu, 31 Aug 2023 11:15:12 -0300 Subject: [PATCH 38/71] Fixed UI of Dropdown Button --- .../DropdownButtonComponent/index.tsx | 90 ++++++++++--------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/src/frontend/src/components/DropdownButtonComponent/index.tsx b/src/frontend/src/components/DropdownButtonComponent/index.tsx index b9fffbb00..1ddddb3c1 100644 --- a/src/frontend/src/components/DropdownButtonComponent/index.tsx +++ b/src/frontend/src/components/DropdownButtonComponent/index.tsx @@ -1,8 +1,13 @@ -import { Fragment, useState } from "react"; +import { useState } from "react"; +import { dropdownButtonPropsType } from "../../types/components"; import IconComponent from "../genericIconComponent"; import { Button } from "../ui/button"; -import { dropdownButtonPropsType } from "../../types/components"; -import { Transition } from "@headlessui/react"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "../ui/dropdown-menu"; export default function DropdownButton({ firstButtonName, @@ -12,54 +17,51 @@ export default function DropdownButton({ const [showOptions, setShowOptions] = useState(false); return ( -
-
- -
-
- + + { event.stopPropagation(); + event.preventDefault(); setShowOptions(!showOptions); }} > - {!showOptions ? ( -
- -
{options.map(({ name, onBtnClick }, index) => ( - + ))} -
-
+ +
); } From 269cb9bc53d52f1636e4c248b208bfb73cdcb190 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:16:39 -0300 Subject: [PATCH 39/71] =?UTF-8?q?=F0=9F=90=9B=20fix(=5F=5Fmain=5F=5F.py):?= =?UTF-8?q?=20pass=20the=20session=20as=20a=20keyword=20argument=20'db'=20?= =?UTF-8?q?to=20the=20create=5Fsuper=5Fuser=20function=20for=20clarity=20a?= =?UTF-8?q?nd=20consistency=20=F0=9F=90=9B=20fix(test=5Fuser.py):=20pass?= =?UTF-8?q?=20the=20session=20as=20a=20keyword=20argument=20'db'=20to=20th?= =?UTF-8?q?e=20create=5Fsuper=5Fuser=20function=20for=20clarity=20and=20co?= =?UTF-8?q?nsistency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/__main__.py | 2 +- tests/test_user.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/__main__.py b/src/backend/langflow/__main__.py index b5ec034de..a08ae9fb0 100644 --- a/src/backend/langflow/__main__.py +++ b/src/backend/langflow/__main__.py @@ -356,7 +356,7 @@ def superuser( with session_getter(db_manager) as session: from langflow.services.auth.utils import create_super_user - if create_super_user(session, username, password): + if create_super_user(db=session, username=username, password=password): # Verify that the superuser was created from langflow.services.database.models.user.user import User diff --git a/tests/test_user.py b/tests/test_user.py index 35b724cc6..bc617e127 100644 --- a/tests/test_user.py +++ b/tests/test_user.py @@ -12,7 +12,7 @@ def super_user(client, session): settings_manager = get_settings_manager() auth_settings = settings_manager.auth_settings return create_super_user( - session, + db=session, username=auth_settings.FIRST_SUPERUSER, password=auth_settings.FIRST_SUPERUSER_PASSWORD, ) From 8429f3fe7241f6b5b814b9df00068d785e7be715 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:16:52 -0300 Subject: [PATCH 40/71] =?UTF-8?q?=F0=9F=90=9B=20fix(chat.py):=20fix=20typo?= =?UTF-8?q?=20in=20variable=20name=20'messsage'=20to=20'message'=20for=20b?= =?UTF-8?q?etter=20readability=20=F0=9F=94=A7=20chore(chat.py):=20refactor?= =?UTF-8?q?=20error=20handling=20in=20chat=20websocket=20to=20improve=20co?= =?UTF-8?q?de=20clarity=20and=20maintainability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index e4fc71343..9d322b03c 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -61,14 +61,13 @@ async def chat( await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) except Exception as exc: logger.error(f"Error in chat websocket: {exc}") - if isinstance(exc, HTTPException): - exc = exc.detail + messsage = exc.detail if isinstance(exc, HTTPException) else str(exc) if "Could not validate credentials" in str(exc): await websocket.close( code=status.WS_1008_POLICY_VIOLATION, reason="Unauthorized" ) else: - await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc)) + await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=messsage) @router.post("/build/init/{flow_id}", response_model=InitResponse, status_code=201) From 9eca124b1700eaeb8742b1f60c7170543fcb03f5 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:17:16 -0300 Subject: [PATCH 41/71] =?UTF-8?q?=F0=9F=90=9B=20fix(utils.py):=20raise=20H?= =?UTF-8?q?TTPException=20with=20status=20code=20400=20and=20detail=20mess?= =?UTF-8?q?age=20when=20FIRST=5FSUPERUSER=20credentials=20are=20missing=20?= =?UTF-8?q?in=20api=5Fkey=5Fsecurity=20function=20=F0=9F=90=9B=20fix(utils?= =?UTF-8?q?.py):=20raise=20credentials=5Fexception=20when=20SECRET=5FKEY?= =?UTF-8?q?=20is=20None=20in=20get=5Fcurrent=5Fuser=20function=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(utils.py):=20raise=20HTTPException=20with=20?= =?UTF-8?q?status=20code=20400=20and=20detail=20message=20when=20FIRST=5FS?= =?UTF-8?q?UPERUSER=20credentials=20are=20missing=20in=20create=5Fuser=5Fl?= =?UTF-8?q?ongterm=5Ftoken=20function=20=F0=9F=90=9B=20fix(auth.py):=20set?= =?UTF-8?q?=20SECRET=5FKEY=20default=20value=20to=20empty=20string=20and?= =?UTF-8?q?=20disallow=20mutation=20in=20AuthSettings=20class=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(auth.py):=20set=20FIRST=5FSUPERUSER=20and=20?= =?UTF-8?q?FIRST=5FSUPERUSER=5FPASSWORD=20as=20optional=20fields=20with=20?= =?UTF-8?q?default=20values=20and=20disallow=20mutation=20in=20AuthSetting?= =?UTF-8?q?s=20class=20=F0=9F=90=9B=20fix(manager.py):=20raise=20ValueErro?= =?UTF-8?q?r=20when=20CONFIG=5FDIR=20is=20not=20set=20in=20settings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/auth/utils.py | 21 +++++++++++++++---- .../langflow/services/settings/auth.py | 19 +++++++++++++---- .../langflow/services/settings/manager.py | 8 ++++++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/src/backend/langflow/services/auth/utils.py b/src/backend/langflow/services/auth/utils.py index a53a182c0..485968a38 100644 --- a/src/backend/langflow/services/auth/utils.py +++ b/src/backend/langflow/services/auth/utils.py @@ -37,7 +37,12 @@ async def api_key_security( result: Optional[Union[ApiKey, User]] = None if settings_manager.auth_settings.AUTO_LOGIN: # Get the first user - settings_manager.auth_settings.FIRST_SUPERUSER + if not settings_manager.auth_settings.FIRST_SUPERUSER: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Missing first superuser credentials", + ) + result = get_user_by_username( db, settings_manager.auth_settings.FIRST_SUPERUSER ) @@ -80,6 +85,9 @@ async def get_current_user( if isinstance(token, Coroutine): token = await token + if settings_manager.auth_settings.SECRET_KEY is None: + raise credentials_exception + try: payload = jwt.decode( token, @@ -150,9 +158,9 @@ def create_token(data: dict, expires_delta: timedelta): def create_super_user( + username: str, + password: str, db: Session = Depends(get_session), - username: Optional[str] = None, - password: Optional[str] = None, ) -> User: super_user = get_user_by_username(db, username) @@ -176,7 +184,12 @@ def create_user_longterm_token(db: Session = Depends(get_session)) -> dict: settings_manager = get_settings_manager() username = settings_manager.auth_settings.FIRST_SUPERUSER password = settings_manager.auth_settings.FIRST_SUPERUSER_PASSWORD - super_user = create_super_user(db, username=username, password=password) + if not username or not password: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Missing first superuser credentials", + ) + super_user = create_super_user(db=db, username=username, password=password) access_token_expires_longterm = timedelta(days=365) access_token = create_token( diff --git a/src/backend/langflow/services/settings/auth.py b/src/backend/langflow/services/settings/auth.py index 7550d3ddd..c38417502 100644 --- a/src/backend/langflow/services/settings/auth.py +++ b/src/backend/langflow/services/settings/auth.py @@ -11,10 +11,11 @@ from langflow.utils.logger import logger class AuthSettings(BaseSettings): # Login settings CONFIG_DIR: str - SECRET_KEY: Optional[str] = Field( - None, + SECRET_KEY: str = Field( + default="", description="Secret key for JWT. If not provided, a random one will be generated.", env="LANGFLOW_SECRET_KEY", + allow_mutation=False, ) ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 @@ -30,8 +31,18 @@ class AuthSettings(BaseSettings): # If AUTO_LOGIN = True # > The application does not request login and logs in automatically as a super user. AUTO_LOGIN: bool = False - FIRST_SUPERUSER: str = "langflow" - FIRST_SUPERUSER_PASSWORD: str = "langflow" + FIRST_SUPERUSER: Optional[str] = Field( + "langflow", + description="First super user to be created if AUTO_LOGIN is True.", + env="LANGFLOW_FIRST_SUPERUSER", + allow_mutation=False, + ) + FIRST_SUPERUSER_PASSWORD: Optional[str] = Field( + "langflow", + description="First super user password to be created if AUTO_LOGIN is True.", + env="LANGFLOW_FIRST_SUPERUSER_PASSWORD", + allow_mutation=False, + ) pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") diff --git a/src/backend/langflow/services/settings/manager.py b/src/backend/langflow/services/settings/manager.py index 67e06108e..cef212c4e 100644 --- a/src/backend/langflow/services/settings/manager.py +++ b/src/backend/langflow/services/settings/manager.py @@ -35,5 +35,11 @@ class SettingsManager(Service): ) settings = Settings(**settings_dict) - auth_settings = AuthSettings(CONFIG_DIR=settings.CONFIG_DIR) + if not settings.CONFIG_DIR: + raise ValueError("CONFIG_DIR must be set in settings") + auth_settings = AuthSettings( + CONFIG_DIR=settings.CONFIG_DIR, + FIRST_SUPERUSER=None, + FIRST_SUPERUSER_PASSWORD=None, + ) return cls(settings, auth_settings) From 942c48955285aa92191900fb33a1ed79300e8420 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:17:28 -0300 Subject: [PATCH 42/71] =?UTF-8?q?=F0=9F=90=9B=20fix(utils.py):=20change=20?= =?UTF-8?q?file=20mode=20from=20"rb"=20to=20"r"=20when=20reading=20secret?= =?UTF-8?q?=20from=20file=20to=20fix=20incorrect=20file=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/settings/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/services/settings/utils.py b/src/backend/langflow/services/settings/utils.py index 5eb4cd787..bb411a299 100644 --- a/src/backend/langflow/services/settings/utils.py +++ b/src/backend/langflow/services/settings/utils.py @@ -43,5 +43,5 @@ def write_secret_to_file(path: Path, value: str) -> None: def read_secret_from_file(path: Path) -> str: - with path.open("rb") as f: + with path.open("r") as f: return f.read() From 4010f5669e42b5c2a76c60b766e712446f41ab5f Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:17:38 -0300 Subject: [PATCH 43/71] =?UTF-8?q?=F0=9F=94=A7=20chore(pyproject.toml):=20a?= =?UTF-8?q?dd=20types-pywin32=20as=20a=20dependency=20to=20support=20Windo?= =?UTF-8?q?ws-specific=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 13 ++++++++++++- pyproject.toml | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 675118488..cdb1ffd1a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -7041,6 +7041,17 @@ files = [ {file = "types_pytz-2023.3.0.1-py3-none-any.whl", hash = "sha256:65152e872137926bb67a8fe6cc9cfd794365df86650c5d5fdc7b167b0f38892e"}, ] +[[package]] +name = "types-pywin32" +version = "306.0.0.4" +description = "Typing stubs for pywin32" +optional = false +python-versions = "*" +files = [ + {file = "types-pywin32-306.0.0.4.tar.gz", hash = "sha256:ae4bbec80d535053236d4bebedf55f58dee89cf5883d277f0fa89e857f3ff337"}, + {file = "types_pywin32-306.0.0.4-py3-none-any.whl", hash = "sha256:f76a343ed6933008af85e158063963f923e54f2f461e697b2929b4178c7b77a1"}, +] + [[package]] name = "types-pyyaml" version = "6.0.12.11" @@ -7773,4 +7784,4 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.11" -content-hash = "c877b4d713eef71815d858d30976ab21c42e5eadcc2df8159e940e03323681ee" +content-hash = "a3a506d483c2db7169a9790090095d1764aa5be223d135c6fc3fc2768dfef36c" diff --git a/pyproject.toml b/pyproject.toml index f852c2a7c..796145886 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -103,6 +103,7 @@ types-python-jose = "^3.3.4.8" types-passlib = "^1.7.7.13" pytest-mock = "^3.11.1" pytest-xdist = "^3.3.1" +types-pywin32 = "^306.0.0.4" [tool.poetry.extras] From c7b500dd5c8a4c753bd8eed8ca6411f48b316f4c Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:27:45 -0300 Subject: [PATCH 44/71] =?UTF-8?q?=F0=9F=94=A7=20fix(base.py):=20fix=20comm?= =?UTF-8?q?ent=20indentation=20for=20better=20readability=20=F0=9F=94=A7?= =?UTF-8?q?=20fix(users.py):=20fix=20code=20formatting=20and=20indentation?= =?UTF-8?q?=20for=20better=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/base.py | 4 ++-- src/backend/langflow/api/v1/users.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/backend/langflow/api/v1/base.py b/src/backend/langflow/api/v1/base.py index 39c8b0b9f..acffc1bc3 100644 --- a/src/backend/langflow/api/v1/base.py +++ b/src/backend/langflow/api/v1/base.py @@ -21,7 +21,7 @@ class FrontendNodeRequest(FrontendNode): class ValidatePromptRequest(BaseModel): name: str template: str - #optional for tweak call + # optional for tweak call frontend_node: Optional[FrontendNodeRequest] @@ -41,7 +41,7 @@ class CodeValidationResponse(BaseModel): class PromptValidationResponse(BaseModel): input_variables: list - #object return for tweak call + # object return for tweak call frontend_node: FrontendNodeRequest | object diff --git a/src/backend/langflow/api/v1/users.py b/src/backend/langflow/api/v1/users.py index 7365e7cc1..5094409cb 100644 --- a/src/backend/langflow/api/v1/users.py +++ b/src/backend/langflow/api/v1/users.py @@ -43,7 +43,9 @@ def add_user( db.refresh(new_user) except IntegrityError as e: db.rollback() - raise HTTPException(status_code=400, detail="This username is unavailable.") from e + raise HTTPException( + status_code=400, detail="This username is unavailable." + ) from e return new_user From 8fedf9562fcda03e6512099bbcfd40e60d4346ad Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Thu, 31 Aug 2023 11:38:40 -0300 Subject: [PATCH 45/71] Fixed usability issues on import json method --- src/frontend/src/contexts/tabsContext.tsx | 47 +++++++++++------------ src/frontend/src/pages/MainPage/index.tsx | 4 +- src/frontend/src/types/tabs/index.ts | 2 +- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index 97ad50329..339ad67b5 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -48,7 +48,7 @@ const TabsContextInitialValue: TabsContextType = { downloadFlow: (flow: FlowType) => {}, downloadFlows: () => {}, uploadFlows: () => {}, - uploadFlow: () => {}, + uploadFlow: async () => "", isBuilt: false, setIsBuilt: (state: boolean) => {}, hardReset: () => {}, @@ -298,39 +298,38 @@ export function TabsProvider({ children }: { children: ReactNode }) { * If the file type is application/json, the file is read and parsed into a JSON object. * The resulting JSON object is passed to the addFlow function. */ - function uploadFlow(newProject?: boolean, file?: File) { + async function uploadFlow( + newProject?: boolean, + file?: File + ): Promise { + let id; if (file) { - file.text().then((text) => { - // parse the text into a JSON object - let flow: FlowType = JSON.parse(text); + let text = await file.text(); + // parse the text into a JSON object + let flow: FlowType = JSON.parse(text); - addFlow(flow, newProject); - }); + id = await addFlow(flow, newProject); } else { // create a file input const input = document.createElement("input"); input.type = "file"; input.accept = ".json"; // add a change event listener to the file input - input.onchange = (e: Event) => { - // check if the file type is application/json - if ( - (e.target as HTMLInputElement).files![0].type === "application/json" - ) { - // get the file from the file input - const currentfile = (e.target as HTMLInputElement).files![0]; - // read the file as text - currentfile.text().then((text) => { - // parse the text into a JSON object + id = await new Promise(resolve => { + input.onchange = async (e: Event) => { + if ((e.target as HTMLInputElement).files![0].type === "application/json") { + const currentfile = (e.target as HTMLInputElement).files![0]; + let text = await currentfile.text(); let flow: FlowType = JSON.parse(text); - - addFlow(flow, newProject); - }); - } - }; - // trigger the file input click event to open the file dialog - input.click(); + const flowId = await addFlow(flow, newProject); + resolve(flowId); + } + }; + // trigger the file input click event to open the file dialog + input.click(); + }); } + return id; } function uploadFlows() { diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index f6f111185..364519ea8 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -18,7 +18,9 @@ export default function HomePage(): JSX.Element { removeFlow, uploadFlow, isLoading, } = useContext(TabsContext); - const dropdownOptions = [{name: "Import from JSON", onBtnClick: () => uploadFlow(true)}] + const dropdownOptions = [{name: "Import from JSON", onBtnClick: () => uploadFlow(true).then((id) => { + navigate("/flow/" + id); + })}] // Set a null id useEffect(() => { diff --git a/src/frontend/src/types/tabs/index.ts b/src/frontend/src/types/tabs/index.ts index 036f82717..4c5b99dd7 100644 --- a/src/frontend/src/types/tabs/index.ts +++ b/src/frontend/src/types/tabs/index.ts @@ -24,7 +24,7 @@ export type TabsContextType = { uploadFlows: () => void; isBuilt: boolean; setIsBuilt: (state: boolean) => void; - uploadFlow: (newFlow?: boolean, file?: File) => void; + uploadFlow: (newFlow?: boolean, file?: File) => Promise; hardReset: () => void; getNodeId: (nodeType: string) => string; tabsState: TabsState; From 156d8bb089318c0622f25c9bedbb6899b00cc377 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:43:41 -0300 Subject: [PATCH 46/71] =?UTF-8?q?=F0=9F=94=A7=20chore(auth.py):=20remove?= =?UTF-8?q?=20unnecessary=20comments=20and=20fields=20in=20AuthSettings=20?= =?UTF-8?q?class=20=F0=9F=94=A7=20chore(manager.py):=20remove=20unnecessar?= =?UTF-8?q?y=20arguments=20in=20AuthSettings=20instantiation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/settings/auth.py | 14 ++------------ src/backend/langflow/services/settings/manager.py | 3 +-- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/backend/langflow/services/settings/auth.py b/src/backend/langflow/services/settings/auth.py index c38417502..582aecb90 100644 --- a/src/backend/langflow/services/settings/auth.py +++ b/src/backend/langflow/services/settings/auth.py @@ -31,18 +31,8 @@ class AuthSettings(BaseSettings): # If AUTO_LOGIN = True # > The application does not request login and logs in automatically as a super user. AUTO_LOGIN: bool = False - FIRST_SUPERUSER: Optional[str] = Field( - "langflow", - description="First super user to be created if AUTO_LOGIN is True.", - env="LANGFLOW_FIRST_SUPERUSER", - allow_mutation=False, - ) - FIRST_SUPERUSER_PASSWORD: Optional[str] = Field( - "langflow", - description="First super user password to be created if AUTO_LOGIN is True.", - env="LANGFLOW_FIRST_SUPERUSER_PASSWORD", - allow_mutation=False, - ) + FIRST_SUPERUSER: str = "langflow" + FIRST_SUPERUSER_PASSWORD: str = "langflow" pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") diff --git a/src/backend/langflow/services/settings/manager.py b/src/backend/langflow/services/settings/manager.py index cef212c4e..b0af8b7f1 100644 --- a/src/backend/langflow/services/settings/manager.py +++ b/src/backend/langflow/services/settings/manager.py @@ -37,9 +37,8 @@ class SettingsManager(Service): settings = Settings(**settings_dict) if not settings.CONFIG_DIR: raise ValueError("CONFIG_DIR must be set in settings") + auth_settings = AuthSettings( CONFIG_DIR=settings.CONFIG_DIR, - FIRST_SUPERUSER=None, - FIRST_SUPERUSER_PASSWORD=None, ) return cls(settings, auth_settings) From d9323cb9a7b864703d306020ba5ce310cea58c49 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Thu, 31 Aug 2023 11:44:50 -0300 Subject: [PATCH 47/71] pre-commit make init fix --- .githooks/pre-commit | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .githooks/pre-commit diff --git a/.githooks/pre-commit b/.githooks/pre-commit old mode 100644 new mode 100755 From 06e5e7dc4cf57dfb20026665602da3c6ea2b9e50 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Thu, 31 Aug 2023 11:48:36 -0300 Subject: [PATCH 48/71] Formatting issues --- src/backend/langflow/api/v1/base.py | 4 +- .../components/codeTabsComponent/index.tsx | 3 +- src/frontend/src/components/ui/skeleton.tsx | 6 +- src/frontend/src/contexts/alertContext.tsx | 2 +- src/frontend/src/modals/formModal/index.tsx | 185 +++++++++--------- .../src/modals/genericModal/index.tsx | 6 +- .../extraSidebarComponent/index.tsx | 7 +- src/frontend/src/pages/loginPage/index.tsx | 4 +- 8 files changed, 111 insertions(+), 106 deletions(-) diff --git a/src/backend/langflow/api/v1/base.py b/src/backend/langflow/api/v1/base.py index 39c8b0b9f..acffc1bc3 100644 --- a/src/backend/langflow/api/v1/base.py +++ b/src/backend/langflow/api/v1/base.py @@ -21,7 +21,7 @@ class FrontendNodeRequest(FrontendNode): class ValidatePromptRequest(BaseModel): name: str template: str - #optional for tweak call + # optional for tweak call frontend_node: Optional[FrontendNodeRequest] @@ -41,7 +41,7 @@ class CodeValidationResponse(BaseModel): class PromptValidationResponse(BaseModel): input_variables: list - #object return for tweak call + # object return for tweak call frontend_node: FrontendNodeRequest | object diff --git a/src/frontend/src/components/codeTabsComponent/index.tsx b/src/frontend/src/components/codeTabsComponent/index.tsx index 2fa6563a6..d807326f0 100644 --- a/src/frontend/src/components/codeTabsComponent/index.tsx +++ b/src/frontend/src/components/codeTabsComponent/index.tsx @@ -28,7 +28,6 @@ import { TabsList, TabsTrigger, } from "../../components/ui/tabs"; -import { alertContext } from "../../contexts/alertContext"; import { darkContext } from "../../contexts/darkContext"; import { typesContext } from "../../contexts/typesContext"; import { codeTabsPropsType } from "../../types/components"; @@ -57,7 +56,7 @@ export default function CodeTabsComponent({ }, [flow]); useEffect(() => { - if(tweaks){ + if (tweaks) { unselectAllNodes({ data, updateNodes: (nodes) => { diff --git a/src/frontend/src/components/ui/skeleton.tsx b/src/frontend/src/components/ui/skeleton.tsx index 6556585a4..f7a1573f2 100644 --- a/src/frontend/src/components/ui/skeleton.tsx +++ b/src/frontend/src/components/ui/skeleton.tsx @@ -1,4 +1,4 @@ -import { cn } from "../../utils/utils" +import { cn } from "../../utils/utils"; function Skeleton({ className, @@ -9,7 +9,7 @@ function Skeleton({ className={cn("animate-pulse rounded-md bg-border", className)} {...props} /> - ) + ); } -export { Skeleton } +export { Skeleton }; diff --git a/src/frontend/src/contexts/alertContext.tsx b/src/frontend/src/contexts/alertContext.tsx index ba46dddac..0b183a297 100644 --- a/src/frontend/src/contexts/alertContext.tsx +++ b/src/frontend/src/contexts/alertContext.tsx @@ -25,7 +25,7 @@ const initialValue: alertContextType = { notificationList: [], pushNotificationList: () => {}, clearNotificationList: () => {}, - removeFromNotificationList: () => {} + removeFromNotificationList: () => {}, }; export const alertContext = createContext(initialValue); diff --git a/src/frontend/src/modals/formModal/index.tsx b/src/frontend/src/modals/formModal/index.tsx index 0a9bf7483..2982b8738 100644 --- a/src/frontend/src/modals/formModal/index.tsx +++ b/src/frontend/src/modals/formModal/index.tsx @@ -8,7 +8,7 @@ import { classNames } from "../../utils/utils"; import ChatInput from "./chatInput"; import ChatMessage from "./chatMessage"; -import _, { set } from "lodash"; +import _ from "lodash"; import AccordionComponent from "../../components/AccordionComponent"; import IconComponent from "../../components/genericIconComponent"; import ToggleShadComponent from "../../components/toggleShadComponent"; @@ -25,9 +25,9 @@ import { Textarea } from "../../components/ui/textarea"; import { CHAT_FORM_DIALOG_SUBTITLE } from "../../constants/constants"; import { AuthContext } from "../../contexts/authContext"; import { TabsContext } from "../../contexts/tabsContext"; +import { getBuildStatus } from "../../controllers/API"; import { TabsState } from "../../types/tabs"; import { validateNodes } from "../../utils/reactflowUtils"; -import { getBuildStatus } from "../../controllers/API"; export default function FormModal({ flow, @@ -156,19 +156,21 @@ export default function FormModal({ function handleOnClose(event: CloseEvent): void { if (isOpen.current) { - getBuildStatus(flow.id).then((response) => { - if (response.data.built) { - connectWS(); - } - else { + getBuildStatus(flow.id) + .then((response) => { + if (response.data.built) { + connectWS(); + } else { + setErrorData({ + title: "Please build the flow again before using the chat.", + }); + } + }) + .catch((error) => { setErrorData({ - title: "Please build the flow again before using the chat." - }) - } - }).catch((error) => { - setErrorData({title:error.data?.detail?error.data.detail:error.message}) - - }); + title: error.data?.detail ? error.data.detail : error.message, + }); + }); setErrorData({ title: event.reason }); setTimeout(() => { setLockChat(false); @@ -186,8 +188,9 @@ export default function FormModal({ const host = isDevelopment ? "localhost:7860" : window.location.host; const chatEndpoint = `/api/v1/chat/${chatId}`; - return `${isDevelopment ? "ws" : webSocketProtocol - }://${host}${chatEndpoint}?token=${encodeURIComponent(accessToken!)}`; + return `${ + isDevelopment ? "ws" : webSocketProtocol + }://${host}${chatEndpoint}?token=${encodeURIComponent(accessToken!)}`; } function handleWsMessage(data: any) { @@ -209,20 +212,20 @@ export default function FormModal({ newChatHistory.push( chatItem.files ? { - isSend: !chatItem.is_bot, - message: chatItem.message, - template: chatItem.template, - thought: chatItem.intermediate_steps, - files: chatItem.files, - chatKey: chatItem.chatKey, - } + isSend: !chatItem.is_bot, + message: chatItem.message, + template: chatItem.template, + thought: chatItem.intermediate_steps, + files: chatItem.files, + chatKey: chatItem.chatKey, + } : { - isSend: !chatItem.is_bot, - message: chatItem.message, - template: chatItem.template, - thought: chatItem.intermediate_steps, - chatKey: chatItem.chatKey, - } + isSend: !chatItem.is_bot, + message: chatItem.message, + template: chatItem.template, + thought: chatItem.intermediate_steps, + chatKey: chatItem.chatKey, + } ); } } @@ -442,73 +445,73 @@ export default function FormModal({ {tabsState[id.current]?.formKeysData?.input_keys ? Object.keys( - tabsState[id.current].formKeysData.input_keys! - ).map((key, index) => ( -
- - - {key} - + tabsState[id.current].formKeysData.input_keys! + ).map((key, index) => ( +
+ + + {key} + -
{ - event.stopPropagation(); - }} - > - - handleOnCheckedChange(value, key) - } - size="small" - disabled={tabsState[ - id.current - ].formKeysData.handle_keys!.some( - (t) => t === key - )} - /> +
{ + event.stopPropagation(); + }} + > + + handleOnCheckedChange(value, key) + } + size="small" + disabled={tabsState[ + id.current + ].formKeysData.handle_keys!.some( + (t) => t === key + )} + /> +
-
- } - key={index} - keyValue={key} - > -
- {tabsState[id.current].formKeysData.handle_keys!.some( - (t) => t === key - ) && ( + } + key={index} + keyValue={key} + > +
+ {tabsState[id.current].formKeysData.handle_keys!.some( + (t) => t === key + ) && (
Source: Component
)} - -
- -
- )) + +
+ + + )) : null} {tabsState[id.current].formKeysData.memory_keys!.map( (key, index) => ( @@ -522,7 +525,7 @@ export default function FormModal({
{ }} + setEnabled={() => {}} size="small" disabled={true} /> diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx index e0875eba3..b29c5acf8 100644 --- a/src/frontend/src/modals/genericModal/index.tsx +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -136,7 +136,11 @@ export default function GenericModal({ setSuccessData({ title: "Prompt is ready", }); - if(JSON.stringify(apiReturn.data?.frontend_node)!==JSON.stringify({})) setNodeClass!(apiReturn.data?.frontend_node); + if ( + JSON.stringify(apiReturn.data?.frontend_node) !== + JSON.stringify({}) + ) + setNodeClass!(apiReturn.data?.frontend_node); setModalOpen(closeModal); setValue(inputValue); } diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index c8dd34628..8ea74390a 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -21,8 +21,7 @@ export default function ExtraSidebar(): JSX.Element { const { data, templates } = useContext(typesContext); const { flows, tabId, uploadFlow, tabsState, saveFlow, isBuilt } = useContext(TabsContext); - const { setSuccessData, setErrorData } = - useContext(alertContext); + const { setSuccessData, setErrorData } = useContext(alertContext); const [dataFilter, setFilterData] = useState(data); const [search, setSearch] = useState(""); const isPending = tabsState[tabId]?.isPending; @@ -101,9 +100,7 @@ export default function ExtraSidebar(): JSX.Element {
{flow && flow.data && ( -
+
- +
From 594dfb13c1f5a116268137763ef7cdd78a6972fa Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 31 Aug 2023 11:49:51 -0300 Subject: [PATCH 49/71] =?UTF-8?q?=F0=9F=94=80=20chore(manager.py):=20ignor?= =?UTF-8?q?e=20type=20error=20for=20session=5Fmanager=5Ffactory=20import?= =?UTF-8?q?=20to=20prevent=20linting=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/services/manager.py b/src/backend/langflow/services/manager.py index bfe83fce8..ca9eb4e70 100644 --- a/src/backend/langflow/services/manager.py +++ b/src/backend/langflow/services/manager.py @@ -135,7 +135,7 @@ def initialize_session_manager(): """ Initialize the session manager. """ - from langflow.services.session import factory as session_manager_factory + from langflow.services.session import factory as session_manager_factory # type: ignore from langflow.services.cache import factory as cache_factory initialize_settings_manager() From d16456d795ca79bce00b992989b0e49ab98591b5 Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa Date: Thu, 31 Aug 2023 16:07:48 -0300 Subject: [PATCH 50/71] =?UTF-8?q?=F0=9F=8E=A8=20style(headerComponent):=20?= =?UTF-8?q?add=20cursor-pointer=20class=20to=20admin=20page=20and=20logout?= =?UTF-8?q?=20menu=20items=20for=20better=20user=20experience?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/components/headerComponent/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index 2a7219fed..4388fb081 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -149,11 +149,15 @@ export default function Header(): JSX.Element { My Account {isAdmin && ( - navigate("/admin")}> + navigate("/admin")} + > Admin Page )} { logout(); navigate("/login"); From 6d6ab9a8740bc632347c5f3b40291bdb549a9a54 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 2 Sep 2023 21:36:49 +0000 Subject: [PATCH 51/71] added missing backslashes to api key request definition --- src/frontend/src/controllers/API/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 780d784e5..d9ea890c8 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -468,7 +468,7 @@ export async function updateUser(user_id: string, user: Users) { export async function getApiKey() { try { - const res = await api.get(`${BASE_URL_API}api_key`); + const res = await api.get(`${BASE_URL_API}api_key/`); if (res.status === 200) { return res.data; } @@ -480,7 +480,7 @@ export async function getApiKey() { export async function createApiKey(name: string) { try { - const res = await api.post(`${BASE_URL_API}api_key`, { name }); + const res = await api.post(`${BASE_URL_API}api_key/`, { name }); if (res.status === 200) { return res.data; } From 2bbbf44b39374546bf01fe7973d99455fc8ee211 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 06:41:34 -0300 Subject: [PATCH 52/71] =?UTF-8?q?=F0=9F=90=9B=20fix(endpoints.py):=20chang?= =?UTF-8?q?e=20get=5Fall=20function=20signature=20to=20include=20settings?= =?UTF-8?q?=5Fmanager=20as=20a=20dependency=20to=20improve=20code=20readab?= =?UTF-8?q?ility=20=F0=9F=90=9B=20fix(flows.py):=20change=20update=5Fflow?= =?UTF-8?q?=20function=20signature=20to=20include=20settings=5Fmanager=20a?= =?UTF-8?q?s=20a=20dependency=20to=20improve=20code=20readability=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(login.py):=20change=20auto=5Flogin=20functio?= =?UTF-8?q?n=20signature=20to=20include=20settings=5Fmanager=20as=20a=20de?= =?UTF-8?q?pendency=20to=20improve=20code=20readability=20=F0=9F=90=9B=20f?= =?UTF-8?q?ix(users.py):=20change=20add=5Fuser=20function=20signature=20to?= =?UTF-8?q?=20include=20session=20as=20a=20dependency=20to=20improve=20cod?= =?UTF-8?q?e=20readability=20=F0=9F=90=9B=20fix(users.py):=20change=20read?= =?UTF-8?q?=5Fall=5Fusers=20function=20signature=20to=20include=20session?= =?UTF-8?q?=20as=20a=20dependency=20to=20improve=20code=20readability=20?= =?UTF-8?q?=F0=9F=90=9B=20fix(users.py):=20change=20patch=5Fuser=20functio?= =?UTF-8?q?n=20signature=20to=20include=20session=20as=20a=20dependency=20?= =?UTF-8?q?to=20improve=20code=20readability=20=F0=9F=90=9B=20fix(users.py?= =?UTF-8?q?):=20change=20delete=5Fuser=20function=20signature=20to=20inclu?= =?UTF-8?q?de=20session=20as=20a=20dependency=20to=20improve=20code=20read?= =?UTF-8?q?ability=20=F0=9F=90=9B=20fix(users.py):=20change=20add=5Fsuper?= =?UTF-8?q?=5Fuser=5Ffor=5Ftesting=5Fpurposes=5Fdelete=5Fme=5Fbefore=5Fmer?= =?UTF-8?q?ge=5Finto=5Fdev=20function=20signature=20to=20include=20session?= =?UTF-8?q?=20as=20a=20dependency=20to=20improve=20code=20readability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/endpoints.py | 7 +++-- src/backend/langflow/api/v1/flows.py | 2 +- src/backend/langflow/api/v1/login.py | 6 ++-- src/backend/langflow/api/v1/users.py | 38 ++++++++++++------------ 4 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/backend/langflow/api/v1/endpoints.py b/src/backend/langflow/api/v1/endpoints.py index 813aaf415..05477a859 100644 --- a/src/backend/langflow/api/v1/endpoints.py +++ b/src/backend/langflow/api/v1/endpoints.py @@ -34,14 +34,15 @@ from sqlmodel import Session router = APIRouter(tags=["Base"]) -@router.get("/all") -def get_all(current_user: User = Depends(get_current_active_user)): +@router.get("/all", dependencies=[Depends(get_current_active_user)]) +def get_all( + settings_manager=Depends(get_settings_manager), +): logger.debug("Building langchain types dict") native_components = build_langchain_types_dict() # custom_components is a list of dicts # need to merge all the keys into one dict custom_components_from_file: dict[str, Any] = {} - settings_manager = get_settings_manager() if settings_manager.settings.COMPONENTS_PATH: logger.info( f"Building custom components from {settings_manager.settings.COMPONENTS_PATH}" diff --git a/src/backend/langflow/api/v1/flows.py b/src/backend/langflow/api/v1/flows.py index b215b9f95..be65048d4 100644 --- a/src/backend/langflow/api/v1/flows.py +++ b/src/backend/langflow/api/v1/flows.py @@ -83,6 +83,7 @@ def update_flow( flow_id: UUID, flow: FlowUpdate, current_user: User = Depends(get_current_active_user), + settings_manager=Depends(get_settings_manager), ): """Update a flow.""" @@ -90,7 +91,6 @@ def update_flow( if not db_flow: raise HTTPException(status_code=404, detail="Flow not found") flow_data = flow.dict(exclude_unset=True) - settings_manager = get_settings_manager() if settings_manager.settings.REMOVE_API_KEYS: flow_data = remove_api_keys(flow_data) for key, value in flow_data.items(): diff --git a/src/backend/langflow/api/v1/login.py b/src/backend/langflow/api/v1/login.py index afe67a916..4241b8d47 100644 --- a/src/backend/langflow/api/v1/login.py +++ b/src/backend/langflow/api/v1/login.py @@ -34,9 +34,9 @@ async def login_to_get_access_token( @router.get("/auto_login") -async def auto_login(db: Session = Depends(get_session)): - settings_manager = get_settings_manager() - +async def auto_login( + db: Session = Depends(get_session), settings_manager=Depends(get_settings_manager) +): if settings_manager.auth_settings.AUTO_LOGIN: return create_user_longterm_token(db) diff --git a/src/backend/langflow/api/v1/users.py b/src/backend/langflow/api/v1/users.py index 5094409cb..517dd7f69 100644 --- a/src/backend/langflow/api/v1/users.py +++ b/src/backend/langflow/api/v1/users.py @@ -29,7 +29,7 @@ router = APIRouter(tags=["Users"]) @router.post("/user", response_model=UserRead, status_code=201) def add_user( user: UserCreate, - db: Session = Depends(get_session), + session: Session = Depends(get_session), ) -> User: """ Add a new user to the database. @@ -38,11 +38,11 @@ def add_user( try: new_user.password = get_password_hash(user.password) - db.add(new_user) - db.commit() - db.refresh(new_user) + session.add(new_user) + session.commit() + session.refresh(new_user) except IntegrityError as e: - db.rollback() + session.rollback() raise HTTPException( status_code=400, detail="This username is unavailable." ) from e @@ -65,16 +65,16 @@ def read_all_users( skip: int = 0, limit: int = 10, current_user: Session = Depends(get_current_active_superuser), - db: Session = Depends(get_session), + session: Session = Depends(get_session), ) -> UsersResponse: """ Retrieve a list of users from the database with pagination. """ query = select(User).offset(skip).limit(limit) - users = db.execute(query).fetchall() + users = session.execute(query).fetchall() count_query = select(func.count()).select_from(User) # type: ignore - total_count = db.execute(count_query).scalar() + total_count = session.execute(count_query).scalar() return UsersResponse( total_count=total_count, # type: ignore @@ -87,19 +87,19 @@ def patch_user( user_id: UUID, user: UserUpdate, _: Session = Depends(get_current_active_user), - db: Session = Depends(get_session), + session: Session = Depends(get_session), ) -> User: """ Update an existing user's data. """ - return update_user(user_id, user, db) + return update_user(user_id, user, session) @router.delete("/user/{user_id}") def delete_user( user_id: UUID, current_user: User = Depends(get_current_active_superuser), - db: Session = Depends(get_session), + session: Session = Depends(get_session), ) -> dict: """ Delete a user from the database. @@ -113,12 +113,12 @@ def delete_user( status_code=403, detail="You don't have the permission to delete this user" ) - user_db = db.query(User).filter(User.id == user_id).first() + user_db = session.query(User).filter(User.id == user_id).first() if not user_db: raise HTTPException(status_code=404, detail="User not found") - db.delete(user_db) - db.commit() + session.delete(user_db) + session.commit() return {"detail": "User deleted"} @@ -126,7 +126,7 @@ def delete_user( # TODO: REMOVE - Just for testing purposes @router.post("/super_user", response_model=User) def add_super_user_for_testing_purposes_delete_me_before_merge_into_dev( - db: Session = Depends(get_session), + session: Session = Depends(get_session), ) -> User: """ Add a superuser for testing purposes. @@ -141,11 +141,11 @@ def add_super_user_for_testing_purposes_delete_me_before_merge_into_dev( ) try: - db.add(new_user) - db.commit() - db.refresh(new_user) + session.add(new_user) + session.commit() + session.refresh(new_user) except IntegrityError as e: - db.rollback() + session.rollback() raise HTTPException(status_code=400, detail="User exists") from e return new_user From 84a0d3acb39c14f8e0f51a2cd8f2dac11904fc89 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 06:42:01 -0300 Subject: [PATCH 53/71] =?UTF-8?q?=F0=9F=94=A7=20fix(chat.py):=20remove=20u?= =?UTF-8?q?nused=20imports=20and=20type=20hints=20to=20improve=20code=20re?= =?UTF-8?q?adability=20=E2=9C=A8=20feat(chat.py):=20add=20dependency=20inj?= =?UTF-8?q?ection=20for=20ChatManager=20in=20chat=20and=20init=5Fbuild=20r?= =?UTF-8?q?outes=20to=20improve=20modularity=20and=20testability=20?= =?UTF-8?q?=F0=9F=94=A7=20fix(chat.py):=20remove=20duplicate=20instantiati?= =?UTF-8?q?on=20of=20ChatManager=20in=20chat=20and=20init=5Fbuild=20routes?= =?UTF-8?q?=20to=20improve=20efficiency=20=F0=9F=94=A7=20fix(chat.py):=20r?= =?UTF-8?q?emove=20duplicate=20instantiation=20of=20ChatManager=20in=20str?= =?UTF-8?q?eam=5Fbuild=20route=20to=20improve=20efficiency=20=F0=9F=94=A7?= =?UTF-8?q?=20fix(utils.py):=20add=20missing=20import=20for=20ChatManager?= =?UTF-8?q?=20in=20get=5Fchat=5Fmanager=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/chat.py | 20 ++++++++++---------- src/backend/langflow/services/utils.py | 8 +++++++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 9d322b03c..2c276c75d 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -11,17 +11,14 @@ from fastapi.responses import StreamingResponse from langflow.api.utils import build_input_keys_response from langflow.api.v1.schemas import BuildStatus, BuiltResponse, InitResponse, StreamData -from langflow.services import service_manager, ServiceType from langflow.graph.graph.base import Graph from langflow.services.auth.utils import get_current_active_user, get_current_user -from langflow.services.utils import get_session +from langflow.services.utils import get_chat_manager, get_session from langflow.utils.logger import logger from cachetools import LRUCache from sqlmodel import Session -from typing import TYPE_CHECKING +from langflow.services.chat.manager import ChatManager -if TYPE_CHECKING: - from langflow.services.chat.manager import ChatManager router = APIRouter(tags=["Chat"]) @@ -34,6 +31,7 @@ async def chat( websocket: WebSocket, token: str = Query(...), db: Session = Depends(get_session), + chat_manager: "ChatManager" = Depends(get_chat_manager), ): """Websocket endpoint for chat.""" try: @@ -48,7 +46,6 @@ async def chat( code=status.WS_1008_POLICY_VIOLATION, reason="Unauthorized" ) - chat_manager: "ChatManager" = service_manager.get(ServiceType.CHAT_MANAGER) if client_id in chat_manager.in_memory_cache: await chat_manager.handle_websocket(client_id, websocket) else: @@ -72,7 +69,10 @@ async def chat( @router.post("/build/init/{flow_id}", response_model=InitResponse, status_code=201) async def init_build( - graph_data: dict, flow_id: str, current_user=Depends(get_current_active_user) + graph_data: dict, + flow_id: str, + current_user=Depends(get_current_active_user), + chat_manager: "ChatManager" = Depends(get_chat_manager), ): """Initialize the build by storing graph data and returning a unique session ID.""" @@ -87,7 +87,6 @@ async def init_build( return InitResponse(flowId=flow_id) # Delete from cache if already exists - chat_manager = service_manager.get(ServiceType.CHAT_MANAGER) if flow_id in chat_manager.in_memory_cache: with chat_manager.in_memory_cache._lock: chat_manager.in_memory_cache.delete(flow_id) @@ -123,7 +122,9 @@ async def build_status(flow_id: str): @router.get("/build/stream/{flow_id}", response_class=StreamingResponse) -async def stream_build(flow_id: str): +async def stream_build( + flow_id: str, chat_manager: "ChatManager" = Depends(get_chat_manager) +): """Stream the build process based on stored flow data.""" async def event_stream(flow_id): @@ -202,7 +203,6 @@ async def stream_build(flow_id: str): "handle_keys": [], } yield str(StreamData(event="message", data=input_keys_response)) - chat_manager = service_manager.get(ServiceType.CHAT_MANAGER) chat_manager.set_cache(flow_id, langchain_object) # We need to reset the chat history chat_manager.chat_history.empty_history(flow_id) diff --git a/src/backend/langflow/services/utils.py b/src/backend/langflow/services/utils.py index 6860f8928..708377d14 100644 --- a/src/backend/langflow/services/utils.py +++ b/src/backend/langflow/services/utils.py @@ -5,6 +5,8 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: from langflow.services.database.manager import DatabaseManager from langflow.services.settings.manager import SettingsManager + from langflow.services.chat.manager import ChatManager + from sqlmodel import Session def get_settings_manager() -> "SettingsManager": @@ -15,6 +17,10 @@ def get_db_manager() -> "DatabaseManager": return service_manager.get(ServiceType.DATABASE_MANAGER) -def get_session(): +def get_session() -> "Session": db_manager = service_manager.get(ServiceType.DATABASE_MANAGER) yield from db_manager.get_session() + + +def get_chat_manager() -> "ChatManager": + return service_manager.get(ServiceType.CHAT_MANAGER) From 37ebbf4e65bfae98f54515c888df106c1b107bfd Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 06:42:41 -0300 Subject: [PATCH 54/71] Formatting --- .../DropdownButtonComponent/index.tsx | 4 +--- src/frontend/src/contexts/tabsContext.tsx | 6 ++++-- src/frontend/src/pages/MainPage/index.tsx | 19 +++++++++++++------ src/frontend/src/types/components/index.ts | 2 +- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/frontend/src/components/DropdownButtonComponent/index.tsx b/src/frontend/src/components/DropdownButtonComponent/index.tsx index 1ddddb3c1..784a08528 100644 --- a/src/frontend/src/components/DropdownButtonComponent/index.tsx +++ b/src/frontend/src/components/DropdownButtonComponent/index.tsx @@ -39,9 +39,7 @@ export default function DropdownButton({ }} > {!showOptions ? ( - + ) : ( )} diff --git a/src/frontend/src/contexts/tabsContext.tsx b/src/frontend/src/contexts/tabsContext.tsx index 339ad67b5..49de70974 100644 --- a/src/frontend/src/contexts/tabsContext.tsx +++ b/src/frontend/src/contexts/tabsContext.tsx @@ -315,9 +315,11 @@ export function TabsProvider({ children }: { children: ReactNode }) { input.type = "file"; input.accept = ".json"; // add a change event listener to the file input - id = await new Promise(resolve => { + id = await new Promise((resolve) => { input.onchange = async (e: Event) => { - if ((e.target as HTMLInputElement).files![0].type === "application/json") { + if ( + (e.target as HTMLInputElement).files![0].type === "application/json" + ) { const currentfile = (e.target as HTMLInputElement).files![0]; let text = await currentfile.text(); let flow: FlowType = JSON.parse(text); diff --git a/src/frontend/src/pages/MainPage/index.tsx b/src/frontend/src/pages/MainPage/index.tsx index 364519ea8..9582d4c57 100644 --- a/src/frontend/src/pages/MainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/index.tsx @@ -1,5 +1,6 @@ import { useContext, useEffect } from "react"; import { Link, useNavigate } from "react-router-dom"; +import DropdownButton from "../../components/DropdownButtonComponent"; import { CardComponent } from "../../components/cardComponent"; import IconComponent from "../../components/genericIconComponent"; import Header from "../../components/headerComponent"; @@ -7,7 +8,6 @@ import { SkeletonCardComponent } from "../../components/skeletonCardComponent"; import { Button } from "../../components/ui/button"; import { USER_PROJECTS_HEADER } from "../../constants/constants"; import { TabsContext } from "../../contexts/tabsContext"; -import DropdownButton from "../../components/DropdownButtonComponent"; export default function HomePage(): JSX.Element { const { flows, @@ -15,12 +15,19 @@ export default function HomePage(): JSX.Element { downloadFlows, uploadFlows, addFlow, - removeFlow, uploadFlow, + removeFlow, + uploadFlow, isLoading, } = useContext(TabsContext); - const dropdownOptions = [{name: "Import from JSON", onBtnClick: () => uploadFlow(true).then((id) => { - navigate("/flow/" + id); - })}] + const dropdownOptions = [ + { + name: "Import from JSON", + onBtnClick: () => + uploadFlow(true).then((id) => { + navigate("/flow/" + id); + }), + }, + ]; // Set a null id useEffect(() => { @@ -73,7 +80,7 @@ export default function HomePage(): JSX.Element {
- Manage your personal projects. Download or upload your collection. + Manage your personal projects. Download or upload your collection.
{isLoading && flows.length == 0 ? ( diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index b61ddf07d..4b72ef36a 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -548,5 +548,5 @@ export type fetchErrorComponentType = { export type dropdownButtonPropsType = { firstButtonName: string; onFirstBtnClick: () => void; - options: Array<{ name: string; onBtnClick: () => void; }>; + options: Array<{ name: string; onBtnClick: () => void }>; }; From 43864904efd4051a91ee9e9160e9d97f7ba40a6e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 07:00:38 -0300 Subject: [PATCH 55/71] =?UTF-8?q?=F0=9F=94=A7=20chore(Makefile):=20update?= =?UTF-8?q?=20mypy=20command=20to=20only=20check=20files=20in=20src/backen?= =?UTF-8?q?d/langflow=20directory=20to=20improve=20performance=20and=20red?= =?UTF-8?q?uce=20noise=20in=20the=20output?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 59dd4a82d..59f326853 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ format: cd src/frontend && npm run format lint: - poetry run mypy --exclude .venv . + poetry run mypy src/backend/langflow poetry run black . --check poetry run ruff . --fix From 833fb4ad8fdefba08477c7d520293697c129265e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 07:01:05 -0300 Subject: [PATCH 56/71] =?UTF-8?q?=F0=9F=94=80=20chore(utils.py):=20add=20t?= =?UTF-8?q?ype=20hint=20for=20get=5Fsession()=20function=20to=20indicate?= =?UTF-8?q?=20it=20returns=20a=20generator=20instead=20of=20a=20Session=20?= =?UTF-8?q?object?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/services/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/services/utils.py b/src/backend/langflow/services/utils.py index 708377d14..8b32aef02 100644 --- a/src/backend/langflow/services/utils.py +++ b/src/backend/langflow/services/utils.py @@ -1,5 +1,5 @@ from langflow.services import ServiceType, service_manager -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Generator if TYPE_CHECKING: @@ -17,7 +17,7 @@ def get_db_manager() -> "DatabaseManager": return service_manager.get(ServiceType.DATABASE_MANAGER) -def get_session() -> "Session": +def get_session() -> Generator["Session", None, None]: db_manager = service_manager.get(ServiceType.DATABASE_MANAGER) yield from db_manager.get_session() From 53c5a3ccdeef6baca22ae2136111f79091bcce88 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 07:05:10 -0300 Subject: [PATCH 57/71] =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20make=20fro?= =?UTF-8?q?ntend=5Fnode=20field=20in=20PromptValidationResponse=20optional?= =?UTF-8?q?=20to=20handle=20cases=20where=20it=20is=20not=20provided?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/langflow/api/v1/base.py b/src/backend/langflow/api/v1/base.py index acffc1bc3..b1071bea2 100644 --- a/src/backend/langflow/api/v1/base.py +++ b/src/backend/langflow/api/v1/base.py @@ -42,7 +42,7 @@ class CodeValidationResponse(BaseModel): class PromptValidationResponse(BaseModel): input_variables: list # object return for tweak call - frontend_node: FrontendNodeRequest | object + frontend_node: Optional[FrontendNodeRequest] = None INVALID_CHARACTERS = { From b1c24054c6fbaf51b57d6a36247da15b6940181f Mon Sep 17 00:00:00 2001 From: root Date: Mon, 4 Sep 2023 11:41:34 +0000 Subject: [PATCH 58/71] added indent to index dropping on non-existing table --- .../langflow/alembic/versions/260dbcc8b680_adds_tables.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/langflow/alembic/versions/260dbcc8b680_adds_tables.py b/src/backend/langflow/alembic/versions/260dbcc8b680_adds_tables.py index 221e66933..53e049a05 100644 --- a/src/backend/langflow/alembic/versions/260dbcc8b680_adds_tables.py +++ b/src/backend/langflow/alembic/versions/260dbcc8b680_adds_tables.py @@ -30,10 +30,10 @@ def upgrade() -> None: # and other related indices if "flowstyle" in existing_tables: op.drop_table("flowstyle") - if "ix_flowstyle_flow_id" in [ - index["name"] for index in inspector.get_indexes("flowstyle") - ]: - op.drop_index("ix_flowstyle_flow_id", table_name="flowstyle") + if "ix_flowstyle_flow_id" in [ + index["name"] for index in inspector.get_indexes("flowstyle") + ]: + op.drop_index("ix_flowstyle_flow_id", table_name="flowstyle") existing_indices_flow = [] existing_fks_flow = [] From 2ab3fcb28a3fbabd3507deab7b03ae288d5555a1 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 10:04:21 -0300 Subject: [PATCH 59/71] =?UTF-8?q?=F0=9F=90=9B=20fix(base.py):=20set=20defa?= =?UTF-8?q?ult=20value=20of=20frontend=5Fnode=20to=20None=20in=20ValidateP?= =?UTF-8?q?romptRequest=20class=20to=20avoid=20potential=20NoneType=20erro?= =?UTF-8?q?rs=20=F0=9F=90=9B=20fix(validate.py):=20set=20frontend=5Fnode?= =?UTF-8?q?=20to=20None=20instead=20of=20an=20empty=20dictionary=20in=20po?= =?UTF-8?q?st=5Fvalidate=5Fprompt=20function=20to=20align=20with=20the=20d?= =?UTF-8?q?efault=20value=20in=20ValidatePromptRequest=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/api/v1/base.py | 2 +- src/backend/langflow/api/v1/validate.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/api/v1/base.py b/src/backend/langflow/api/v1/base.py index b1071bea2..f2c2f3f59 100644 --- a/src/backend/langflow/api/v1/base.py +++ b/src/backend/langflow/api/v1/base.py @@ -22,7 +22,7 @@ class ValidatePromptRequest(BaseModel): name: str template: str # optional for tweak call - frontend_node: Optional[FrontendNodeRequest] + frontend_node: Optional[FrontendNodeRequest] = None # Build ValidationResponse class for {"imports": {"errors": []}, "function": {"errors": []}} diff --git a/src/backend/langflow/api/v1/validate.py b/src/backend/langflow/api/v1/validate.py index da76d25bc..64ef60549 100644 --- a/src/backend/langflow/api/v1/validate.py +++ b/src/backend/langflow/api/v1/validate.py @@ -35,7 +35,7 @@ def post_validate_prompt(prompt_request: ValidatePromptRequest): if prompt_request.frontend_node is None: return PromptValidationResponse( input_variables=input_variables, - frontend_node={}, + frontend_node=None, ) old_custom_fields = get_old_custom_fields(prompt_request) From 5f98f0bbd9997c803bf255c9a885ca8a4a0ce376 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 11:34:38 -0300 Subject: [PATCH 60/71] =?UTF-8?q?=F0=9F=93=A6=20chore(pyproject.toml):=20a?= =?UTF-8?q?dd=20loguru=20package=20as=20a=20dependency=20for=20improved=20?= =?UTF-8?q?logging=20capabilities?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- poetry.lock | 10 +++++----- pyproject.toml | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index cdb1ffd1a..c2a290db4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3047,13 +3047,13 @@ server = ["fastapi (>=0.100.0)", "pydantic-settings (>=2.0.1)", "sse-starlette ( [[package]] name = "loguru" -version = "0.7.0" +version = "0.7.1" description = "Python logging made (stupidly) simple" optional = false python-versions = ">=3.5" files = [ - {file = "loguru-0.7.0-py3-none-any.whl", hash = "sha256:b93aa30099fa6860d4727f1b81f8718e965bb96253fa190fab2077aaad6d15d3"}, - {file = "loguru-0.7.0.tar.gz", hash = "sha256:1612053ced6ae84d7959dd7d5e431a0532642237ec21f7fd83ac73fe539e03e1"}, + {file = "loguru-0.7.1-py3-none-any.whl", hash = "sha256:046bf970cb3cad77a28d607cbf042ac25a407db987a1e801c7f7e692469982f9"}, + {file = "loguru-0.7.1.tar.gz", hash = "sha256:7ba2a7d81b79a412b0ded69bd921e012335e80fd39937a633570f273a343579e"}, ] [package.dependencies] @@ -3061,7 +3061,7 @@ colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""} win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] -dev = ["Sphinx (==5.3.0)", "colorama (==0.4.5)", "colorama (==0.4.6)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v0.990)", "pre-commit (==3.2.1)", "pytest (==6.1.2)", "pytest (==7.2.1)", "pytest-cov (==2.12.1)", "pytest-cov (==4.0.0)", "pytest-mypy-plugins (==1.10.1)", "pytest-mypy-plugins (==1.9.3)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.2.0)", "tox (==3.27.1)", "tox (==4.4.6)"] +dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "pre-commit (==3.3.1)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] [[package]] name = "lxml" @@ -7784,4 +7784,4 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.11" -content-hash = "a3a506d483c2db7169a9790090095d1764aa5be223d135c6fc3fc2768dfef36c" +content-hash = "6523f2e35458c6d0b8d281e20dd2233180128805ea07199c073224b0d6f75ee7" diff --git a/pyproject.toml b/pyproject.toml index 796145886..077a0cb39 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,6 +84,7 @@ python-jose = "^3.3.0" metaphor-python = "^0.1.11" markupsafe = "^2.1.3" pywin32 = { version = "^306", markers = "sys_platform == 'win32'" } +loguru = "^0.7.1" [tool.poetry.group.dev.dependencies] black = "^23.1.0" From 87eb8b1a95f6af27daf7d8212fb1e586605ce0e9 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 11:35:22 -0300 Subject: [PATCH 61/71] =?UTF-8?q?=F0=9F=94=A7=20chore(logger.py):=20refact?= =?UTF-8?q?or=20logger=20configuration=20to=20use=20loguru=20library=20and?= =?UTF-8?q?=20improve=20log=20formatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/utils/logger.py | 36 +++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/backend/langflow/utils/logger.py b/src/backend/langflow/utils/logger.py index deb0f75ca..b881a614c 100644 --- a/src/backend/langflow/utils/logger.py +++ b/src/backend/langflow/utils/logger.py @@ -1,30 +1,34 @@ -import logging +from loguru import logger from pathlib import Path - from rich.logging import RichHandler -logger = logging.getLogger("langflow") +def configure(log_level: str = "DEBUG", log_file: Path = None): + log_format = "{time:HH:mm:ss} - {level: <8} - {message}" + logger.remove() # Remove default handlers -def configure(log_level: str = "DEBUG", log_file: Path = None): # type: ignore - log_format = "%(asctime)s - %(levelname)s - %(message)s" - log_level_value = getattr(logging, log_level.upper(), logging.INFO) - - logging.basicConfig( - level=log_level_value, - format=log_format, - datefmt="[%X]", - handlers=[RichHandler(rich_tracebacks=True)], + # Configure loguru to use RichHandler + logger.configure( + handlers=[ + { + "sink": RichHandler(rich_tracebacks=True, markup=True), + "format": log_format, + "level": log_level, + } + ] ) if log_file: log_file = Path(log_file) log_file.parent.mkdir(parents=True, exist_ok=True) - file_handler = logging.FileHandler(log_file) - file_handler.setFormatter(logging.Formatter(log_format)) - logger.addHandler(file_handler) + logger.add( + sink=str(log_file), + level=log_level, + format=log_format, + rotation="10 MB", # Log rotation based on file size + ) - logger.info(f"Logger set up with log level: {log_level_value}({log_level})") + logger.info(f"Logger set up with log level: {log_level}") if log_file: logger.info(f"Log file: {log_file}") From 58c3e5e9dc588dee88600927a2f5b21a1ed545ba Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 11:38:39 -0300 Subject: [PATCH 62/71] refactor: :sparkles: replace loggers with loguru --- src/backend/langflow/api/v1/callback.py | 2 +- src/backend/langflow/api/v1/chat.py | 2 +- src/backend/langflow/api/v1/endpoints.py | 2 +- src/backend/langflow/api/v1/validate.py | 2 +- src/backend/langflow/graph/edge/base.py | 2 +- src/backend/langflow/graph/graph/base.py | 2 +- src/backend/langflow/graph/vertex/base.py | 2 +- src/backend/langflow/interface/agents/base.py | 2 +- src/backend/langflow/interface/base.py | 2 +- src/backend/langflow/interface/chains/base.py | 2 +- src/backend/langflow/interface/custom/base.py | 2 +- src/backend/langflow/interface/custom/directory_reader.py | 2 +- src/backend/langflow/interface/document_loaders/base.py | 2 +- src/backend/langflow/interface/embeddings/base.py | 2 +- src/backend/langflow/interface/initialize/loading.py | 2 +- src/backend/langflow/interface/llms/base.py | 2 +- src/backend/langflow/interface/memories/base.py | 2 +- src/backend/langflow/interface/output_parsers/base.py | 2 +- src/backend/langflow/interface/prompts/base.py | 2 +- src/backend/langflow/interface/retrievers/base.py | 2 +- src/backend/langflow/interface/run.py | 2 +- src/backend/langflow/interface/text_splitters/base.py | 2 +- src/backend/langflow/interface/toolkits/base.py | 2 +- src/backend/langflow/interface/tools/util.py | 2 +- src/backend/langflow/interface/types.py | 2 +- src/backend/langflow/interface/utilities/base.py | 2 +- src/backend/langflow/interface/utils.py | 2 +- src/backend/langflow/interface/vector_store/base.py | 2 +- src/backend/langflow/interface/wrappers/base.py | 2 +- src/backend/langflow/processing/base.py | 2 +- src/backend/langflow/processing/process.py | 2 +- src/backend/langflow/services/chat/manager.py | 2 +- src/backend/langflow/services/chat/utils.py | 2 +- src/backend/langflow/services/database/manager.py | 2 +- src/backend/langflow/services/database/utils.py | 2 +- src/backend/langflow/services/manager.py | 2 +- src/backend/langflow/services/settings/auth.py | 2 +- src/backend/langflow/services/settings/base.py | 2 +- src/backend/langflow/services/settings/manager.py | 2 +- src/backend/langflow/services/settings/utils.py | 2 +- 40 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/backend/langflow/api/v1/callback.py b/src/backend/langflow/api/v1/callback.py index 69dbf5082..2a16a0bd2 100644 --- a/src/backend/langflow/api/v1/callback.py +++ b/src/backend/langflow/api/v1/callback.py @@ -10,7 +10,7 @@ from fastapi import WebSocket from langchain.schema import AgentAction, LLMResult, AgentFinish -from langflow.utils.logger import logger +from loguru import logger # https://github.com/hwchase17/chat-langchain/blob/master/callback.py diff --git a/src/backend/langflow/api/v1/chat.py b/src/backend/langflow/api/v1/chat.py index 9d322b03c..a79ed2ccd 100644 --- a/src/backend/langflow/api/v1/chat.py +++ b/src/backend/langflow/api/v1/chat.py @@ -15,7 +15,7 @@ from langflow.services import service_manager, ServiceType from langflow.graph.graph.base import Graph from langflow.services.auth.utils import get_current_active_user, get_current_user from langflow.services.utils import get_session -from langflow.utils.logger import logger +from loguru import logger from cachetools import LRUCache from sqlmodel import Session from typing import TYPE_CHECKING diff --git a/src/backend/langflow/api/v1/endpoints.py b/src/backend/langflow/api/v1/endpoints.py index 813aaf415..957e003bc 100644 --- a/src/backend/langflow/api/v1/endpoints.py +++ b/src/backend/langflow/api/v1/endpoints.py @@ -7,7 +7,7 @@ from langflow.services.database.models.flow import Flow from langflow.processing.process import process_graph_cached, process_tweaks from langflow.services.database.models.user.user import User from langflow.services.utils import get_settings_manager -from langflow.utils.logger import logger +from loguru import logger from fastapi import APIRouter, Depends, HTTPException, UploadFile, Body, status import sqlalchemy as sa from langflow.interface.custom.custom_component import CustomComponent diff --git a/src/backend/langflow/api/v1/validate.py b/src/backend/langflow/api/v1/validate.py index da76d25bc..4a3ee71c6 100644 --- a/src/backend/langflow/api/v1/validate.py +++ b/src/backend/langflow/api/v1/validate.py @@ -8,7 +8,7 @@ from langflow.api.v1.base import ( validate_prompt, ) from langflow.template.field.base import TemplateField -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.validate import validate_code # build router diff --git a/src/backend/langflow/graph/edge/base.py b/src/backend/langflow/graph/edge/base.py index dc7eab328..2df20cbde 100644 --- a/src/backend/langflow/graph/edge/base.py +++ b/src/backend/langflow/graph/edge/base.py @@ -1,4 +1,4 @@ -from langflow.utils.logger import logger +from loguru import logger from typing import TYPE_CHECKING if TYPE_CHECKING: diff --git a/src/backend/langflow/graph/graph/base.py b/src/backend/langflow/graph/graph/base.py index 2b22d352c..94964e472 100644 --- a/src/backend/langflow/graph/graph/base.py +++ b/src/backend/langflow/graph/graph/base.py @@ -10,7 +10,7 @@ from langflow.graph.vertex.types import ( ) from langflow.interface.tools.constants import FILE_TOOLS from langflow.utils import payload -from langflow.utils.logger import logger +from loguru import logger from langchain.chains.base import Chain diff --git a/src/backend/langflow/graph/vertex/base.py b/src/backend/langflow/graph/vertex/base.py index d5c4beed9..0f9a5e8a9 100644 --- a/src/backend/langflow/graph/vertex/base.py +++ b/src/backend/langflow/graph/vertex/base.py @@ -3,7 +3,7 @@ from langflow.graph.utils import UnbuiltObject from langflow.interface.initialize import loading from langflow.interface.listing import lazy_load_dict from langflow.utils.constants import DIRECT_TYPES -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import sync_to_async diff --git a/src/backend/langflow/interface/agents/base.py b/src/backend/langflow/interface/agents/base.py index ec8c42aba..574264e47 100644 --- a/src/backend/langflow/interface/agents/base.py +++ b/src/backend/langflow/interface/agents/base.py @@ -8,7 +8,7 @@ from langflow.interface.base import LangChainTypeCreator from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.agents import AgentFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class, build_template_from_method diff --git a/src/backend/langflow/interface/base.py b/src/backend/langflow/interface/base.py index d1ed83b5a..b006a3174 100644 --- a/src/backend/langflow/interface/base.py +++ b/src/backend/langflow/interface/base.py @@ -8,7 +8,7 @@ from pydantic import BaseModel from langflow.template.field.base import TemplateField from langflow.template.frontend_node.base import FrontendNode from langflow.template.template.base import Template -from langflow.utils.logger import logger +from loguru import logger # Assuming necessary imports for Field, Template, and FrontendNode classes diff --git a/src/backend/langflow/interface/chains/base.py b/src/backend/langflow/interface/chains/base.py index b906dbd25..755ac82dd 100644 --- a/src/backend/langflow/interface/chains/base.py +++ b/src/backend/langflow/interface/chains/base.py @@ -6,7 +6,7 @@ from langflow.interface.importing.utils import import_class from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.chains import ChainFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class, build_template_from_method from langchain import chains from langchain_experimental.sql import SQLDatabaseChain # type: ignore diff --git a/src/backend/langflow/interface/custom/base.py b/src/backend/langflow/interface/custom/base.py index 06e874fa7..45a3ea215 100644 --- a/src/backend/langflow/interface/custom/base.py +++ b/src/backend/langflow/interface/custom/base.py @@ -8,7 +8,7 @@ from langflow.interface.custom.custom_component import CustomComponent from langflow.template.frontend_node.custom_components import ( CustomComponentFrontendNode, ) -from langflow.utils.logger import logger +from loguru import logger # Assuming necessary imports for Field, Template, and FrontendNode classes diff --git a/src/backend/langflow/interface/custom/directory_reader.py b/src/backend/langflow/interface/custom/directory_reader.py index 44b2d4f1b..01b11a4a6 100644 --- a/src/backend/langflow/interface/custom/directory_reader.py +++ b/src/backend/langflow/interface/custom/directory_reader.py @@ -1,7 +1,7 @@ import os import ast import zlib -from langflow.utils.logger import logger +from loguru import logger class CustomComponentPathValueError(ValueError): diff --git a/src/backend/langflow/interface/document_loaders/base.py b/src/backend/langflow/interface/document_loaders/base.py index db0832ff3..a2c147e16 100644 --- a/src/backend/langflow/interface/document_loaders/base.py +++ b/src/backend/langflow/interface/document_loaders/base.py @@ -5,7 +5,7 @@ from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.documentloaders import DocumentLoaderFrontNode from langflow.interface.custom_lists import documentloaders_type_to_cls_dict -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/embeddings/base.py b/src/backend/langflow/interface/embeddings/base.py index 169985d37..1063d10d1 100644 --- a/src/backend/langflow/interface/embeddings/base.py +++ b/src/backend/langflow/interface/embeddings/base.py @@ -6,7 +6,7 @@ from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.base import FrontendNode from langflow.template.frontend_node.embeddings import EmbeddingFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/initialize/loading.py b/src/backend/langflow/interface/initialize/loading.py index 589d4b3ff..b600fb5b2 100644 --- a/src/backend/langflow/interface/initialize/loading.py +++ b/src/backend/langflow/interface/initialize/loading.py @@ -34,7 +34,7 @@ from langflow.utils import validate from langchain.chains.base import Chain from langchain.vectorstores.base import VectorStore from langchain.document_loaders.base import BaseLoader -from langflow.utils.logger import logger +from loguru import logger if TYPE_CHECKING: from langflow import CustomComponent diff --git a/src/backend/langflow/interface/llms/base.py b/src/backend/langflow/interface/llms/base.py index f562b99ed..87e4937cf 100644 --- a/src/backend/langflow/interface/llms/base.py +++ b/src/backend/langflow/interface/llms/base.py @@ -5,7 +5,7 @@ from langflow.interface.custom_lists import llm_type_to_cls_dict from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.llms import LLMFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/memories/base.py b/src/backend/langflow/interface/memories/base.py index 70665602c..61c6cc430 100644 --- a/src/backend/langflow/interface/memories/base.py +++ b/src/backend/langflow/interface/memories/base.py @@ -6,7 +6,7 @@ from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.base import FrontendNode from langflow.template.frontend_node.memories import MemoryFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class, build_template_from_method from langflow.custom.customs import get_custom_nodes diff --git a/src/backend/langflow/interface/output_parsers/base.py b/src/backend/langflow/interface/output_parsers/base.py index 256b521e1..b6eb36a0e 100644 --- a/src/backend/langflow/interface/output_parsers/base.py +++ b/src/backend/langflow/interface/output_parsers/base.py @@ -7,7 +7,7 @@ from langflow.interface.importing.utils import import_class from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.output_parsers import OutputParserFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class, build_template_from_method diff --git a/src/backend/langflow/interface/prompts/base.py b/src/backend/langflow/interface/prompts/base.py index 5aa41dfb2..70818429e 100644 --- a/src/backend/langflow/interface/prompts/base.py +++ b/src/backend/langflow/interface/prompts/base.py @@ -8,7 +8,7 @@ from langflow.interface.importing.utils import import_class from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.prompts import PromptFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/retrievers/base.py b/src/backend/langflow/interface/retrievers/base.py index db1cfd165..92e3f2f61 100644 --- a/src/backend/langflow/interface/retrievers/base.py +++ b/src/backend/langflow/interface/retrievers/base.py @@ -7,7 +7,7 @@ from langflow.interface.importing.utils import import_class from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.retrievers import RetrieverFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_method, build_template_from_class diff --git a/src/backend/langflow/interface/run.py b/src/backend/langflow/interface/run.py index 42cea0e98..9d3d95cda 100644 --- a/src/backend/langflow/interface/run.py +++ b/src/backend/langflow/interface/run.py @@ -1,7 +1,7 @@ from typing import Any, Dict, Tuple from langflow.services.cache.utils import memoize_dict from langflow.graph import Graph -from langflow.utils.logger import logger +from loguru import logger @memoize_dict(maxsize=10) diff --git a/src/backend/langflow/interface/text_splitters/base.py b/src/backend/langflow/interface/text_splitters/base.py index 87b778c4c..8b21303ce 100644 --- a/src/backend/langflow/interface/text_splitters/base.py +++ b/src/backend/langflow/interface/text_splitters/base.py @@ -5,7 +5,7 @@ from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.textsplitters import TextSplittersFrontendNode from langflow.interface.custom_lists import textsplitter_type_to_cls_dict -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/toolkits/base.py b/src/backend/langflow/interface/toolkits/base.py index c13ffdbd9..fe0003b15 100644 --- a/src/backend/langflow/interface/toolkits/base.py +++ b/src/backend/langflow/interface/toolkits/base.py @@ -6,7 +6,7 @@ from langflow.interface.base import LangChainTypeCreator from langflow.interface.importing.utils import import_class, import_module from langflow.services.utils import get_settings_manager -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/tools/util.py b/src/backend/langflow/interface/tools/util.py index 38276c620..f92386f18 100644 --- a/src/backend/langflow/interface/tools/util.py +++ b/src/backend/langflow/interface/tools/util.py @@ -3,7 +3,7 @@ import inspect from typing import Dict, Union from langchain.agents.tools import Tool -from langflow.utils.logger import logger +from loguru import logger def get_func_tool_params(func, **kwargs) -> Union[Dict, None]: diff --git a/src/backend/langflow/interface/types.py b/src/backend/langflow/interface/types.py index 824b0af50..47743560e 100644 --- a/src/backend/langflow/interface/types.py +++ b/src/backend/langflow/interface/types.py @@ -29,7 +29,7 @@ from langflow.template.frontend_node.custom_components import ( from langflow.interface.retrievers.base import retriever_creator from langflow.interface.custom.directory_reader import DirectoryReader -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import get_base_classes import re diff --git a/src/backend/langflow/interface/utilities/base.py b/src/backend/langflow/interface/utilities/base.py index eb8cd60af..9009983b0 100644 --- a/src/backend/langflow/interface/utilities/base.py +++ b/src/backend/langflow/interface/utilities/base.py @@ -8,7 +8,7 @@ from langflow.interface.importing.utils import import_class from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.utilities import UtilitiesFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class diff --git a/src/backend/langflow/interface/utils.py b/src/backend/langflow/interface/utils.py index 1fddbf80f..75e854e16 100644 --- a/src/backend/langflow/interface/utils.py +++ b/src/backend/langflow/interface/utils.py @@ -8,7 +8,7 @@ import re import yaml from langchain.base_language import BaseLanguageModel from PIL.Image import Image -from langflow.utils.logger import logger +from loguru import logger from langflow.services.chat.config import ChatConfig from langflow.services.utils import get_settings_manager diff --git a/src/backend/langflow/interface/vector_store/base.py b/src/backend/langflow/interface/vector_store/base.py index 4b8ca2b64..f7aca8c9c 100644 --- a/src/backend/langflow/interface/vector_store/base.py +++ b/src/backend/langflow/interface/vector_store/base.py @@ -7,7 +7,7 @@ from langflow.interface.importing.utils import import_class from langflow.services.utils import get_settings_manager from langflow.template.frontend_node.vectorstores import VectorStoreFrontendNode -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_method diff --git a/src/backend/langflow/interface/wrappers/base.py b/src/backend/langflow/interface/wrappers/base.py index 77e38f921..c4399fb3e 100644 --- a/src/backend/langflow/interface/wrappers/base.py +++ b/src/backend/langflow/interface/wrappers/base.py @@ -3,7 +3,7 @@ from typing import Dict, List, Optional from langchain import requests, sql_database from langflow.interface.base import LangChainTypeCreator -from langflow.utils.logger import logger +from loguru import logger from langflow.utils.util import build_template_from_class, build_template_from_method diff --git a/src/backend/langflow/processing/base.py b/src/backend/langflow/processing/base.py index 13ff6a385..c3d766f15 100644 --- a/src/backend/langflow/processing/base.py +++ b/src/backend/langflow/processing/base.py @@ -4,7 +4,7 @@ from langflow.api.v1.callback import ( StreamingLLMCallbackHandler, ) from langflow.processing.process import fix_memory_inputs, format_actions -from langflow.utils.logger import logger +from loguru import logger from langchain.agents.agent import AgentExecutor diff --git a/src/backend/langflow/processing/process.py b/src/backend/langflow/processing/process.py index 4b2e7b178..c60a53de5 100644 --- a/src/backend/langflow/processing/process.py +++ b/src/backend/langflow/processing/process.py @@ -6,7 +6,7 @@ from langflow.interface.run import ( get_memory_key, update_memory_keys, ) -from langflow.utils.logger import logger +from loguru import logger from langflow.graph import Graph from langchain.chains.base import Chain from langchain.vectorstores.base import VectorStore diff --git a/src/backend/langflow/services/chat/manager.py b/src/backend/langflow/services/chat/manager.py index 6751e97e7..d8492e961 100644 --- a/src/backend/langflow/services/chat/manager.py +++ b/src/backend/langflow/services/chat/manager.py @@ -7,7 +7,7 @@ from langflow.services.cache.manager import Subject from langflow.services.chat.utils import process_graph from langflow.interface.utils import pil_to_base64 from langflow.services.schema import ServiceType -from langflow.utils.logger import logger +from loguru import logger import asyncio diff --git a/src/backend/langflow/services/chat/utils.py b/src/backend/langflow/services/chat/utils.py index 17c976eb9..d9c291757 100644 --- a/src/backend/langflow/services/chat/utils.py +++ b/src/backend/langflow/services/chat/utils.py @@ -2,7 +2,7 @@ from fastapi import WebSocket from langflow.api.v1.schemas import ChatMessage from langflow.processing.base import get_result_and_steps from langflow.interface.utils import try_setting_streaming_options -from langflow.utils.logger import logger +from loguru import logger async def process_graph( diff --git a/src/backend/langflow/services/database/manager.py b/src/backend/langflow/services/database/manager.py index 1159cbf7a..c8826e31b 100644 --- a/src/backend/langflow/services/database/manager.py +++ b/src/backend/langflow/services/database/manager.py @@ -7,7 +7,7 @@ from langflow.services.utils import get_settings_manager from sqlalchemy import inspect import sqlalchemy as sa from sqlmodel import SQLModel, Session, create_engine -from langflow.utils.logger import logger +from loguru import logger from alembic.config import Config from alembic import command from langflow.services.database import models # noqa diff --git a/src/backend/langflow/services/database/utils.py b/src/backend/langflow/services/database/utils.py index e6afae184..fd0a8856a 100644 --- a/src/backend/langflow/services/database/utils.py +++ b/src/backend/langflow/services/database/utils.py @@ -1,6 +1,6 @@ from dataclasses import dataclass from typing import TYPE_CHECKING -from langflow.utils.logger import logger +from loguru import logger from contextlib import contextmanager from alembic.util.exc import CommandError from sqlmodel import Session diff --git a/src/backend/langflow/services/manager.py b/src/backend/langflow/services/manager.py index ca9eb4e70..60a93fe16 100644 --- a/src/backend/langflow/services/manager.py +++ b/src/backend/langflow/services/manager.py @@ -1,6 +1,6 @@ from langflow.services.schema import ServiceType from typing import TYPE_CHECKING, List, Optional -from langflow.utils.logger import logger +from loguru import logger if TYPE_CHECKING: from langflow.services.factory import ServiceFactory diff --git a/src/backend/langflow/services/settings/auth.py b/src/backend/langflow/services/settings/auth.py index 582aecb90..d1f8197f0 100644 --- a/src/backend/langflow/services/settings/auth.py +++ b/src/backend/langflow/services/settings/auth.py @@ -5,7 +5,7 @@ from langflow.services.settings.utils import read_secret_from_file, write_secret from pydantic import BaseSettings, Field, validator from passlib.context import CryptContext -from langflow.utils.logger import logger +from loguru import logger class AuthSettings(BaseSettings): diff --git a/src/backend/langflow/services/settings/base.py b/src/backend/langflow/services/settings/base.py index 00cd2085f..366ff474d 100644 --- a/src/backend/langflow/services/settings/base.py +++ b/src/backend/langflow/services/settings/base.py @@ -8,7 +8,7 @@ from pathlib import Path import yaml from pydantic import BaseSettings, root_validator, validator -from langflow.utils.logger import logger +from loguru import logger # BASE_COMPONENTS_PATH = str(Path(__file__).parent / "components") BASE_COMPONENTS_PATH = str(Path(__file__).parent.parent.parent / "components") diff --git a/src/backend/langflow/services/settings/manager.py b/src/backend/langflow/services/settings/manager.py index b0af8b7f1..2d687d784 100644 --- a/src/backend/langflow/services/settings/manager.py +++ b/src/backend/langflow/services/settings/manager.py @@ -1,7 +1,7 @@ from langflow.services.base import Service from langflow.services.settings.auth import AuthSettings from langflow.services.settings.base import Settings -from langflow.utils.logger import logger +from loguru import logger import os import yaml diff --git a/src/backend/langflow/services/settings/utils.py b/src/backend/langflow/services/settings/utils.py index bb411a299..fae96ff28 100644 --- a/src/backend/langflow/services/settings/utils.py +++ b/src/backend/langflow/services/settings/utils.py @@ -2,7 +2,7 @@ import os from pathlib import Path import platform -from langflow.utils.logger import logger +from loguru import logger def set_secure_permissions(file_path): From 7e336bbee685099f67ff6f80fcdbf6dce446a64e Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 16:13:01 -0300 Subject: [PATCH 63/71] =?UTF-8?q?=F0=9F=90=9B=20fix(logger.py):=20change?= =?UTF-8?q?=20log=5Flevel=20variable=20to=20uppercase=20to=20improve=20con?= =?UTF-8?q?sistency=20and=20semantics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/langflow/utils/logger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/utils/logger.py b/src/backend/langflow/utils/logger.py index b881a614c..4e93874af 100644 --- a/src/backend/langflow/utils/logger.py +++ b/src/backend/langflow/utils/logger.py @@ -13,7 +13,7 @@ def configure(log_level: str = "DEBUG", log_file: Path = None): { "sink": RichHandler(rich_tracebacks=True, markup=True), "format": log_format, - "level": log_level, + "level": log_level.upper(), } ] ) @@ -24,7 +24,7 @@ def configure(log_level: str = "DEBUG", log_file: Path = None): logger.add( sink=str(log_file), - level=log_level, + level=log_level.upper(), format=log_format, rotation="10 MB", # Log rotation based on file size ) From 28b487dc33cc097425fdc61b0a3a06e5dd146892 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 4 Sep 2023 16:15:41 -0300 Subject: [PATCH 64/71] =?UTF-8?q?=F0=9F=94=A7=20fix(manager.py):=20change?= =?UTF-8?q?=20logger.warn=20to=20logger.warning=20for=20consistency=20and?= =?UTF-8?q?=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔧 fix(logger.py): change log_file parameter type annotation to Optional[Path] to indicate that it is an optional argument --- src/backend/langflow/services/database/manager.py | 2 +- src/backend/langflow/utils/logger.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backend/langflow/services/database/manager.py b/src/backend/langflow/services/database/manager.py index c8826e31b..7f8afab6f 100644 --- a/src/backend/langflow/services/database/manager.py +++ b/src/backend/langflow/services/database/manager.py @@ -89,7 +89,7 @@ class DatabaseManager(Service): for table in legacy_tables: if table in inspector.get_table_names(): - logger.warn(f"Legacy table exists: {table}") + logger.warning(f"Legacy table exists: {table}") return True diff --git a/src/backend/langflow/utils/logger.py b/src/backend/langflow/utils/logger.py index 4e93874af..1f616486b 100644 --- a/src/backend/langflow/utils/logger.py +++ b/src/backend/langflow/utils/logger.py @@ -1,9 +1,10 @@ +from typing import Optional from loguru import logger from pathlib import Path from rich.logging import RichHandler -def configure(log_level: str = "DEBUG", log_file: Path = None): +def configure(log_level: str = "DEBUG", log_file: Optional[Path] = None): log_format = "{time:HH:mm:ss} - {level: <8} - {message}" logger.remove() # Remove default handlers From 5df8b11d9fbfce56833ab584a0eeab799e789420 Mon Sep 17 00:00:00 2001 From: Lucas Oliveira Date: Mon, 4 Sep 2023 16:37:43 -0300 Subject: [PATCH 65/71] Changed autocomplete to only fill when on form --- src/frontend/src/components/inputComponent/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx index 46acdc1b0..490be0fb0 100644 --- a/src/frontend/src/components/inputComponent/index.tsx +++ b/src/frontend/src/components/inputComponent/index.tsx @@ -54,7 +54,7 @@ export default function InputComponent({ ) : ( Date: Mon, 4 Sep 2023 18:48:50 -0300 Subject: [PATCH 66/71] revert to default animation of radixUI --- src/frontend/src/components/ui/dialog.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/components/ui/dialog.tsx b/src/frontend/src/components/ui/dialog.tsx index 57dda0fef..ee673bf2b 100644 --- a/src/frontend/src/components/ui/dialog.tsx +++ b/src/frontend/src/components/ui/dialog.tsx @@ -27,7 +27,7 @@ const DialogOverlay = React.forwardRef< Date: Mon, 4 Sep 2023 19:29:20 -0300 Subject: [PATCH 67/71] fix animation --- src/frontend/src/components/ui/dialog.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/components/ui/dialog.tsx b/src/frontend/src/components/ui/dialog.tsx index ee673bf2b..93680ce7e 100644 --- a/src/frontend/src/components/ui/dialog.tsx +++ b/src/frontend/src/components/ui/dialog.tsx @@ -27,7 +27,7 @@ const DialogOverlay = React.forwardRef< Date: Mon, 4 Sep 2023 19:33:21 -0300 Subject: [PATCH 68/71] refactor(codeTabsComponent): wrap code tabs in a div with flex column layout for better styling and readability --- src/frontend/src/components/codeTabsComponent/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/src/components/codeTabsComponent/index.tsx b/src/frontend/src/components/codeTabsComponent/index.tsx index d807326f0..9868b709a 100644 --- a/src/frontend/src/components/codeTabsComponent/index.tsx +++ b/src/frontend/src/components/codeTabsComponent/index.tsx @@ -180,7 +180,7 @@ export default function CodeTabsComponent({ key={idx} // Remember to add a unique key prop > {idx < 4 ? ( - <> +
{tab.description && (
{tab.code} - +
) : idx === 4 ? ( <>
From e50b59368101a0af72ed431017ea94944133892d Mon Sep 17 00:00:00 2001 From: Cristhian Zanforlin Lousa Date: Mon, 4 Sep 2023 20:18:10 -0300 Subject: [PATCH 69/71] =?UTF-8?q?=F0=9F=90=9B=20fix(API/index.ts):=20handl?= =?UTF-8?q?e=20potential=20undefined=20response=20object=20properties=20to?= =?UTF-8?q?=20prevent=20errors?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/frontend/src/controllers/API/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index d9ea890c8..bdf7e5221 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -164,7 +164,7 @@ export async function readFlowsFromDatabase() { try { const response = await api.get(`${BASE_URL_API}flows/`); if (response?.status !== 200) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`HTTP error! status: ${response?.status}`); } return response.data; } catch (error) { @@ -177,7 +177,7 @@ export async function downloadFlowsFromDatabase() { try { const response = await api.get(`${BASE_URL_API}flows/download/`); if (response?.status !== 200) { - throw new Error(`HTTP error! status: ${response.status}`); + throw new Error(`HTTP error! status: ${response?.status}`); } return response.data; } catch (error) { @@ -190,8 +190,8 @@ export async function uploadFlowsToDatabase(flows: FormData) { try { const response = await api.post(`${BASE_URL_API}flows/upload/`, flows); - if (response.status !== 201) { - throw new Error(`HTTP error! status: ${response.status}`); + if (response?.status !== 201) { + throw new Error(`HTTP error! status: ${response?.status}`); } return response.data; } catch (error) { From 25949b97a7ad6c59817eddf059e70f52fc9d730b Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Tue, 5 Sep 2023 16:08:46 -0300 Subject: [PATCH 70/71] Fix: user not having icon when id starts with a letter --- src/frontend/src/components/headerComponent/index.tsx | 6 +++--- src/frontend/src/contexts/darkContext.tsx | 10 ++++++++++ src/frontend/src/types/typesContext/index.ts | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index 4388fb081..4c2eaa31e 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -1,4 +1,4 @@ -import { useContext } from "react"; +import { useContext, useEffect, useState } from "react"; import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa"; import { Link, useLocation, useNavigate } from "react-router-dom"; import AlertDropdown from "../../alerts/alertDropDown"; @@ -27,7 +27,7 @@ export default function Header(): JSX.Element { const { notificationCenter } = useContext(alertContext); const location = useLocation(); const { logout, autoLogin, isAdmin, userData } = useContext(AuthContext); - const { stars } = useContext(darkContext); + const { stars, gradientIndex } = useContext(darkContext); const navigate = useNavigate(); return ( @@ -140,7 +140,7 @@ export default function Header(): JSX.Element { className={ "h-7 w-7 rounded-full focus-visible:outline-0 " + gradients[ - parseInt(userData?.id ?? "", 10) % gradients.length + gradientIndex ] } /> diff --git a/src/frontend/src/contexts/darkContext.tsx b/src/frontend/src/contexts/darkContext.tsx index bfb758009..32d1453e2 100644 --- a/src/frontend/src/contexts/darkContext.tsx +++ b/src/frontend/src/contexts/darkContext.tsx @@ -7,6 +7,8 @@ const initialValue = { setDark: () => {}, stars: 0, setStars: (stars) => 0, + gradientIndex: 0, + setGradientIndex: () => 0, }; export const darkContext = createContext(initialValue); @@ -16,6 +18,7 @@ export function DarkProvider({ children }) { JSON.parse(window.localStorage.getItem("isDark")!) ?? false ); const [stars, setStars] = useState(0); + const [gradientIndex, setGradientIndex] = useState(0); useEffect(() => { async function fetchStars() { @@ -23,6 +26,11 @@ export function DarkProvider({ children }) { setStars(starsCount); } fetchStars(); + const min = 0; + const max = 30; + setGradientIndex( + Math.floor(Math.random() * (max - min + 1)) + min + ) }, []); useEffect(() => { @@ -41,6 +49,8 @@ export function DarkProvider({ children }) { stars, dark, setDark, + setGradientIndex, + gradientIndex, }} > {children} diff --git a/src/frontend/src/types/typesContext/index.ts b/src/frontend/src/types/typesContext/index.ts index 73cb1ce2a..40f5b21ab 100644 --- a/src/frontend/src/types/typesContext/index.ts +++ b/src/frontend/src/types/typesContext/index.ts @@ -48,6 +48,8 @@ export type darkContextType = { setDark: (newState: {}) => void; stars: number; setStars: (stars: number) => void; + gradientIndex: number; + setGradientIndex: (index: number) => void; }; export type locationContextType = { From f44b0e33b1d292c1111d0fdeed0153a1761e341f Mon Sep 17 00:00:00 2001 From: igorrCarvalho Date: Tue, 5 Sep 2023 16:32:07 -0300 Subject: [PATCH 71/71] remove unnused imports --- src/frontend/src/components/headerComponent/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index 4c2eaa31e..2d63d0ecf 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useState } from "react"; +import { useContext } from "react"; import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa"; import { Link, useLocation, useNavigate } from "react-router-dom"; import AlertDropdown from "../../alerts/alertDropDown";