merge dev

This commit is contained in:
Cristhian Zanforlin Lousa 2023-09-05 11:44:16 -03:00
commit 20014f4937
79 changed files with 887 additions and 582 deletions

0
.githooks/pre-commit Normal file → Executable file
View file

View file

@ -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

21
poetry.lock generated
View file

@ -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"
@ -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 = "6523f2e35458c6d0b8d281e20dd2233180128805ea07199c073224b0d6f75ee7"

View file

@ -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"
@ -103,6 +104,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]

View file

@ -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

View file

@ -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 = []

View file

@ -21,8 +21,8 @@ class FrontendNodeRequest(FrontendNode):
class ValidatePromptRequest(BaseModel):
name: str
template: str
#optional for tweak call
frontend_node: Optional[FrontendNodeRequest]
# optional for tweak call
frontend_node: Optional[FrontendNodeRequest] = None
# Build ValidationResponse class for {"imports": {"errors": []}, "function": {"errors": []}}
@ -41,8 +41,8 @@ class CodeValidationResponse(BaseModel):
class PromptValidationResponse(BaseModel):
input_variables: list
#object return for tweak call
frontend_node: FrontendNodeRequest | object
# object return for tweak call
frontend_node: Optional[FrontendNodeRequest] = None
INVALID_CHARACTERS = {

View file

@ -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

View file

@ -11,17 +11,15 @@ 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.utils.logger import logger
from loguru import logger
from langflow.services.utils import get_chat_manager, get_session
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 +32,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 +47,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:
@ -61,19 +59,21 @@ 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)
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."""
@ -88,7 +88,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)
@ -124,7 +123,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):
@ -203,7 +204,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)

View file

@ -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
@ -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}"

View file

@ -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():

View file

@ -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)

View file

@ -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,12 +38,14 @@ 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()
raise HTTPException(status_code=400, detail="This username is unavailable.") from e
session.rollback()
raise HTTPException(
status_code=400, detail="This username is unavailable."
) from e
return new_user
@ -63,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
@ -85,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.
@ -111,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"}
@ -124,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.
@ -139,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

View file

@ -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
@ -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)

View file

@ -1,4 +1,4 @@
from langflow.utils.logger import logger
from loguru import logger
from typing import TYPE_CHECKING
if TYPE_CHECKING:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more