Add support for Python 3.12 (#1873)
* Add support for Python 3.12 * chore: Update Python version to 3.11 and DuckDB dependency to 0.10.2 * chore: fix mistral components lint * Update SQLAgent and SQLExecutor imports to use langchain_community utilities * Update langchain import to langchain_community * Update langchain import to langchain_community * 📝 (langflow/__main__.py): Import warnings module to suppress warnings during app execution 📝 (langflow/api/v1/schemas.py): Update timestamp field default value to use datetime.now with timezone.utc 📝 (auth/utils.py): Ignore warnings related to datetime.utcnow when decoding JWT tokens and creating refresh tokens 📝 (models/flow/model.py): Update updated_at field default value to use lambda function with timezone.utc 📝 (models/user/model.py): Update create_at and updated_at field default values to use lambda function with timezone.utc
This commit is contained in:
parent
919db5d928
commit
5ca1c22893
36 changed files with 470 additions and 876 deletions
3
.github/workflows/lint.yml
vendored
3
.github/workflows/lint.yml
vendored
|
|
@ -22,8 +22,9 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.10"
|
||||
- "3.12"
|
||||
- "3.11"
|
||||
- "3.10"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }}
|
||||
|
|
|
|||
3
.github/workflows/python_test.yml
vendored
3
.github/workflows/python_test.yml
vendored
|
|
@ -23,8 +23,9 @@ jobs:
|
|||
strategy:
|
||||
matrix:
|
||||
python-version:
|
||||
- "3.10"
|
||||
- "3.12"
|
||||
- "3.11"
|
||||
- "3.10"
|
||||
env:
|
||||
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
||||
steps:
|
||||
|
|
|
|||
2
.github/workflows/typescript_test.yml
vendored
2
.github/workflows/typescript_test.yml
vendored
|
|
@ -8,7 +8,7 @@ on:
|
|||
env:
|
||||
POETRY_VERSION: "1.8.2"
|
||||
NODE_VERSION: "21"
|
||||
PYTHON_VERSION: "3.10"
|
||||
PYTHON_VERSION: "3.12"
|
||||
# Define the directory where Playwright browsers will be installed.
|
||||
# Adjust if your project uses a different path.
|
||||
PLAYWRIGHT_BROWSERS_PATH: "ms-playwright"
|
||||
|
|
|
|||
869
poetry.lock
generated
869
poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -25,7 +25,7 @@ langflow = "langflow.__main__:main"
|
|||
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.10,<3.12"
|
||||
python = ">=3.10,<3.13"
|
||||
langflow-base = { path = "./src/backend/base", develop = true }
|
||||
beautifulsoup4 = "^4.12.2"
|
||||
google-search-results = "^2.4.1"
|
||||
|
|
@ -72,7 +72,7 @@ langchain-cohere = "^0.1.0rc1"
|
|||
elasticsearch = "^8.12.0"
|
||||
pytube = "^15.0.0"
|
||||
llama-index = "^0.10.13"
|
||||
unstructured = { extras = ["md"], version = "^0.12.4" }
|
||||
# unstructured = { extras = ["md"], version = "^0.12.4" }
|
||||
dspy-ai = "^2.4.0"
|
||||
html2text = "^2024.2.26"
|
||||
assemblyai = "^0.23.1"
|
||||
|
|
@ -85,7 +85,7 @@ zep-python = { version = "^2.0.0rc5", allow-prereleases = true }
|
|||
langchain-google-vertexai = "^1.0.3"
|
||||
langchain-groq = "^0.1.3"
|
||||
langchain-pinecone = "^0.1.0"
|
||||
langchain-mistralai ="^0.1.6"
|
||||
langchain-mistralai = "^0.1.6"
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import sys
|
|||
import time
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
import warnings
|
||||
|
||||
import click
|
||||
import httpx
|
||||
|
|
@ -468,7 +469,9 @@ def migration(
|
|||
|
||||
|
||||
def main():
|
||||
app()
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter("ignore")
|
||||
app()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from typing import List
|
||||
from uuid import UUID
|
||||
|
||||
|
|
@ -33,7 +33,7 @@ def create_flow(
|
|||
flow.user_id = current_user.id
|
||||
|
||||
db_flow = Flow.model_validate(flow, from_attributes=True)
|
||||
db_flow.updated_at = datetime.utcnow()
|
||||
db_flow.updated_at = datetime.now(timezone.utc)
|
||||
|
||||
session.add(db_flow)
|
||||
session.commit()
|
||||
|
|
@ -128,7 +128,7 @@ def update_flow(
|
|||
for key, value in flow_data.items():
|
||||
if value is not None:
|
||||
setattr(db_flow, key, value)
|
||||
db_flow.updated_at = datetime.utcnow()
|
||||
db_flow.updated_at = datetime.now(timezone.utc)
|
||||
session.add(db_flow)
|
||||
session.commit()
|
||||
session.refresh(db_flow)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from datetime import datetime
|
||||
from datetime import datetime, timezone
|
||||
from enum import Enum
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
|
|
@ -250,7 +250,7 @@ class VertexBuildResponse(BaseModel):
|
|||
"""JSON string of the params."""
|
||||
data: ResultDataResponse
|
||||
"""Mapping of vertex ids to result dict containing the param name and result value."""
|
||||
timestamp: Optional[datetime] = Field(default_factory=datetime.utcnow)
|
||||
timestamp: Optional[datetime] = Field(default_factory=lambda: datetime.now(timezone.utc))
|
||||
"""Timestamp of the build."""
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,23 +67,25 @@ def retrieve_file_paths(
|
|||
return file_paths
|
||||
|
||||
|
||||
def partition_file_to_record(file_path: str, silent_errors: bool) -> Optional[Record]:
|
||||
# Use the partition function to load the file
|
||||
from unstructured.partition.auto import partition # type: ignore
|
||||
# ! Removing unstructured dependency until
|
||||
# ! 3.12 is supported
|
||||
# def partition_file_to_record(file_path: str, silent_errors: bool) -> Optional[Record]:
|
||||
# # Use the partition function to load the file
|
||||
# from unstructured.partition.auto import partition # type: ignore
|
||||
|
||||
try:
|
||||
elements = partition(file_path)
|
||||
except Exception as e:
|
||||
if not silent_errors:
|
||||
raise ValueError(f"Error loading file {file_path}: {e}") from e
|
||||
return None
|
||||
# try:
|
||||
# elements = partition(file_path)
|
||||
# except Exception as e:
|
||||
# if not silent_errors:
|
||||
# raise ValueError(f"Error loading file {file_path}: {e}") from e
|
||||
# return None
|
||||
|
||||
# Create a Record
|
||||
text = "\n\n".join([Text(el) for el in elements])
|
||||
metadata = elements.metadata if hasattr(elements, "metadata") else {}
|
||||
metadata["file_path"] = file_path
|
||||
record = Record(text=text, data=metadata)
|
||||
return record
|
||||
# # Create a Record
|
||||
# text = "\n\n".join([Text(el) for el in elements])
|
||||
# metadata = elements.metadata if hasattr(elements, "metadata") else {}
|
||||
# metadata["file_path"] = file_path
|
||||
# record = Record(text=text, data=metadata)
|
||||
# return record
|
||||
|
||||
|
||||
def read_text_file(file_path: str) -> str:
|
||||
|
|
@ -131,18 +133,20 @@ def parse_text_file_to_record(file_path: str, silent_errors: bool) -> Optional[R
|
|||
return record
|
||||
|
||||
|
||||
def get_elements(
|
||||
file_paths: List[str],
|
||||
silent_errors: bool,
|
||||
max_concurrency: int,
|
||||
use_multithreading: bool,
|
||||
) -> List[Optional[Record]]:
|
||||
if use_multithreading:
|
||||
records = parallel_load_records(file_paths, silent_errors, max_concurrency)
|
||||
else:
|
||||
records = [partition_file_to_record(file_path, silent_errors) for file_path in file_paths]
|
||||
records = list(filter(None, records))
|
||||
return records
|
||||
# ! Removing unstructured dependency until
|
||||
# ! 3.12 is supported
|
||||
# def get_elements(
|
||||
# file_paths: List[str],
|
||||
# silent_errors: bool,
|
||||
# max_concurrency: int,
|
||||
# use_multithreading: bool,
|
||||
# ) -> List[Optional[Record]]:
|
||||
# if use_multithreading:
|
||||
# records = parallel_load_records(file_paths, silent_errors, max_concurrency)
|
||||
# else:
|
||||
# records = [partition_file_to_record(file_path, silent_errors) for file_path in file_paths]
|
||||
# records = list(filter(None, records))
|
||||
# return records
|
||||
|
||||
|
||||
def parallel_load_records(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from typing import Callable, Union
|
||||
|
||||
from langchain.agents import AgentExecutor
|
||||
from langchain.sql_database import SQLDatabase
|
||||
from langchain_community.utilities import SQLDatabase
|
||||
from langchain_community.agent_toolkits import SQLDatabaseToolkit
|
||||
from langchain_community.agent_toolkits.sql.base import create_sql_agent
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
|
||||
from langchain_experimental.sql.base import SQLDatabase
|
||||
from langchain_community.utilities import SQLDatabase
|
||||
|
||||
from langflow.field_typing import Text
|
||||
from langflow.interface.custom.custom_component import CustomComponent
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
from typing import Optional
|
||||
|
||||
from langchain.llms.baidu_qianfan_endpoint import QianfanLLMEndpoint
|
||||
from langchain_community.llms.baidu_qianfan_endpoint import QianfanLLMEndpoint
|
||||
|
||||
from langflow.interface.custom.custom_component import CustomComponent
|
||||
from langflow.field_typing import BaseLanguageModel
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class MistralAIModelComponent(CustomComponent):
|
|||
"open-mixtral-8x22b",
|
||||
"mistral-small-latest",
|
||||
"mistral-medium-latest",
|
||||
"mistral-large-latest"
|
||||
"mistral-large-latest",
|
||||
],
|
||||
"info": "Name of the model to use.",
|
||||
"required": True,
|
||||
|
|
@ -64,9 +64,9 @@ class MistralAIModelComponent(CustomComponent):
|
|||
def build(
|
||||
self,
|
||||
model: str,
|
||||
temperature: float = 0.1,
|
||||
mistral_api_key: Optional[str] = None,
|
||||
max_tokens: Optional[int] = None,
|
||||
temperature: Optional[float] = None,
|
||||
mistral_api_base: Optional[str] = None,
|
||||
) -> BaseLanguageModel:
|
||||
# Set default API endpoint if not provided
|
||||
|
|
@ -75,11 +75,11 @@ class MistralAIModelComponent(CustomComponent):
|
|||
|
||||
try:
|
||||
output = ChatMistralAI(
|
||||
model=model,
|
||||
model_name=model,
|
||||
api_key=(SecretStr(mistral_api_key) if mistral_api_key else None),
|
||||
max_tokens=max_tokens,
|
||||
temperature=temperature,
|
||||
base_url=mistral_api_base,
|
||||
endpoint=mistral_api_base,
|
||||
)
|
||||
except Exception as e:
|
||||
raise ValueError("Could not connect to Mistral API.") from e
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from typing import Optional
|
||||
|
||||
from langflow.field_typing import BaseLanguageModel
|
||||
from langchain.llms.huggingface_endpoint import HuggingFaceEndpoint
|
||||
from langchain_community.llms.huggingface_endpoint import HuggingFaceEndpoint
|
||||
|
||||
from langflow.interface.custom.custom_component import CustomComponent
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from pydantic.v1 import SecretStr
|
|||
|
||||
from langflow.base.constants import STREAM_INFO_TEXT
|
||||
from langflow.base.models.model import LCModelComponent
|
||||
from langflow.field_typing import NestedDict, Text
|
||||
from langflow.field_typing import Text
|
||||
|
||||
|
||||
class MistralAIModelComponent(LCModelComponent):
|
||||
|
|
@ -32,10 +32,6 @@ class MistralAIModelComponent(LCModelComponent):
|
|||
"display_name": "Max Tokens",
|
||||
"advanced": True,
|
||||
},
|
||||
"model_kwargs": {
|
||||
"display_name": "Model Kwargs",
|
||||
"advanced": True,
|
||||
},
|
||||
"model_name": {
|
||||
"display_name": "Model Name",
|
||||
"advanced": False,
|
||||
|
|
@ -45,7 +41,7 @@ class MistralAIModelComponent(LCModelComponent):
|
|||
"open-mixtral-8x22b",
|
||||
"mistral-small-latest",
|
||||
"mistral-medium-latest",
|
||||
"mistral-large-latest"
|
||||
"mistral-large-latest",
|
||||
],
|
||||
"value": "open-mistral-7b",
|
||||
},
|
||||
|
|
@ -78,19 +74,48 @@ class MistralAIModelComponent(LCModelComponent):
|
|||
"info": "System message to pass to the model.",
|
||||
"advanced": True,
|
||||
},
|
||||
"max_retries": {
|
||||
"display_name": "Max Retries",
|
||||
"advanced": True,
|
||||
},
|
||||
"timeout": {
|
||||
"display_name": "Timeout",
|
||||
"advanced": True,
|
||||
},
|
||||
"max_concurrent_requests": {
|
||||
"display_name": "Max Concurrent Requests",
|
||||
"advanced": True,
|
||||
},
|
||||
"top_p": {
|
||||
"display_name": "Top P",
|
||||
"advanced": True,
|
||||
},
|
||||
"random_seed": {
|
||||
"display_name": "Random Seed",
|
||||
"advanced": True,
|
||||
},
|
||||
"safe_mode": {
|
||||
"display_name": "Safe Mode",
|
||||
"advanced": True,
|
||||
},
|
||||
}
|
||||
|
||||
def build(
|
||||
self,
|
||||
input_value: Text,
|
||||
mistral_api_key: str,
|
||||
temperature: float,
|
||||
model_name: str,
|
||||
temperature: float = 0.1,
|
||||
max_tokens: Optional[int] = 256,
|
||||
model_kwargs: NestedDict = {},
|
||||
mistral_api_base: Optional[str] = None,
|
||||
stream: bool = False,
|
||||
system_message: Optional[str] = None,
|
||||
max_retries: int = 5,
|
||||
timeout: int = 120,
|
||||
max_concurrent_requests: int = 64,
|
||||
top_p: float = 1,
|
||||
random_seed: Optional[int] = None,
|
||||
safe_mode: bool = False,
|
||||
) -> Text:
|
||||
if not mistral_api_base:
|
||||
mistral_api_base = "https://api.mistral.ai"
|
||||
|
|
@ -101,11 +126,16 @@ class MistralAIModelComponent(LCModelComponent):
|
|||
|
||||
chat_model = ChatMistralAI(
|
||||
max_tokens=max_tokens,
|
||||
model_kwargs=model_kwargs,
|
||||
model=model_name,
|
||||
base_url=mistral_api_base,
|
||||
model_name=model_name,
|
||||
endpoint=mistral_api_base,
|
||||
api_key=api_key,
|
||||
temperature=temperature,
|
||||
max_retries=max_retries,
|
||||
timeout=timeout,
|
||||
max_concurrent_requests=max_concurrent_requests,
|
||||
top_p=top_p,
|
||||
random_seed=random_seed,
|
||||
safe_mode=safe_mode,
|
||||
)
|
||||
|
||||
return self.get_chat_result(chat_model, stream, input_value, system_message)
|
||||
|
|
|
|||
|
|
@ -224,11 +224,6 @@ wrappers:
|
|||
documentation: ""
|
||||
SQLDatabase:
|
||||
documentation: ""
|
||||
output_parsers:
|
||||
StructuredOutputParser:
|
||||
documentation: "https://python.langchain.com/docs/modules/model_io/output_parsers/structured"
|
||||
ResponseSchema:
|
||||
documentation: "https://python.langchain.com/docs/modules/model_io/output_parsers/structured"
|
||||
custom_components:
|
||||
CustomComponent:
|
||||
documentation: "https://docs.langflow.org/guidelines/custom-component"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ from langflow.interface.document_loaders.base import documentloader_creator
|
|||
from langflow.interface.embeddings.base import embedding_creator
|
||||
from langflow.interface.llms.base import llm_creator
|
||||
from langflow.interface.memories.base import memory_creator
|
||||
from langflow.interface.output_parsers.base import output_parser_creator
|
||||
from langflow.interface.prompts.base import prompt_creator
|
||||
from langflow.interface.retrievers.base import retriever_creator
|
||||
from langflow.interface.text_splitters.base import textsplitter_creator
|
||||
|
|
@ -46,7 +45,6 @@ class VertexTypesDict(LazyLoadDictBase):
|
|||
# **{t: types.VectorStoreVertex for t in vectorstore_creator.to_list()},
|
||||
**{t: types.DocumentLoaderVertex for t in documentloader_creator.to_list()},
|
||||
**{t: types.TextSplitterVertex for t in textsplitter_creator.to_list()},
|
||||
**{t: types.OutputParserVertex for t in output_parser_creator.to_list()},
|
||||
**{t: types.CustomComponentVertex for t in custom_component_creator.to_list()},
|
||||
**{t: types.RetrieverVertex for t in retriever_creator.to_list()},
|
||||
**{t: types.ChatVertex for t in CHAT_COMPONENTS},
|
||||
|
|
|
|||
|
|
@ -300,11 +300,6 @@ class PromptVertex(Vertex):
|
|||
return str(self._built_object)
|
||||
|
||||
|
||||
class OutputParserVertex(Vertex):
|
||||
def __init__(self, data: Dict, graph):
|
||||
super().__init__(data, graph=graph, base_type="output_parsers")
|
||||
|
||||
|
||||
class CustomComponentVertex(Vertex):
|
||||
def __init__(self, data: Dict, graph):
|
||||
super().__init__(data, graph=graph, base_type="custom_components")
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from langchain.agents.agent_toolkits.vectorstore.prompt import ROUTER_PREFIX as
|
|||
from langchain.agents.mrkl.prompt import FORMAT_INSTRUCTIONS
|
||||
from langchain.base_language import BaseLanguageModel
|
||||
from langchain.chains.llm import LLMChain
|
||||
from langchain.sql_database import SQLDatabase
|
||||
from langchain_community.utilities import SQLDatabase
|
||||
from langchain.tools.sql_database.prompt import QUERY_CHECKER
|
||||
from langchain_community.agent_toolkits import SQLDatabaseToolkit
|
||||
from langchain_community.agent_toolkits.json.prompt import JSON_PREFIX, JSON_SUFFIX
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import inspect
|
||||
from typing import Any
|
||||
|
||||
from langchain import llms, memory, requests, text_splitter
|
||||
from langchain import llms, memory, text_splitter
|
||||
from langchain_community import agent_toolkits, document_loaders, embeddings
|
||||
from langchain_community.chat_models import AzureChatOpenAI, ChatAnthropic, ChatOpenAI, ChatVertexAI
|
||||
|
||||
|
|
@ -43,8 +43,6 @@ memory_type_to_cls_dict: dict[str, Any] = {
|
|||
memory_name: import_class(f"langchain.memory.{memory_name}") for memory_name in memory.__all__
|
||||
}
|
||||
|
||||
# Wrappers
|
||||
wrapper_type_to_cls_dict: dict[str, Any] = {wrapper.__name__: wrapper for wrapper in [requests.RequestsWrapper]}
|
||||
|
||||
# Embeddings
|
||||
embedding_type_to_cls_dict: dict[str, Any] = {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue