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
diff --git a/src/backend/langflow/api/v1/base.py b/src/backend/langflow/api/v1/base.py
index acffc1bc3..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": []}}
@@ -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 = {
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/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
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)
diff --git a/src/backend/langflow/services/utils.py b/src/backend/langflow/services/utils.py
index 6860f8928..8b32aef02 100644
--- a/src/backend/langflow/services/utils.py
+++ b/src/backend/langflow/services/utils.py
@@ -1,10 +1,12 @@
from langflow.services import ServiceType, service_manager
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Generator
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() -> Generator["Session", None, None]:
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)
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 ? (
-