diff --git a/backend/build.py b/backend/build.py index 951c496753..73c8ddd2b0 100644 --- a/backend/build.py +++ b/backend/build.py @@ -3,11 +3,8 @@ import os import pathlib import shutil -import signal import subprocess import sys -from contextlib import contextmanager -from typing import Optional class BuildError(Exception): @@ -50,7 +47,7 @@ def copy_directory(src, dst, description): shutil.rmtree(dst) raise except Exception as e: - raise BuildError(f"Failed to copy {src} to {dst}: {str(e)}") + raise BuildError(f"Failed to copy {src} to {dst}: {e!s}") def copy_frontend(project_root): @@ -94,10 +91,10 @@ def build(): print("\nBuild interrupted by user") sys.exit(1) except BuildError as e: - print(f"\nBuild failed: {str(e)}") + print(f"\nBuild failed: {e!s}") sys.exit(1) except Exception as e: - print(f"\nUnexpected error: {str(e)}") + print(f"\nUnexpected error: {e!s}") sys.exit(1) diff --git a/backend/chainlit/__init__.py b/backend/chainlit/__init__.py index 37ae77594a..496afb1087 100644 --- a/backend/chainlit/__init__.py +++ b/backend/chainlit/__init__.py @@ -134,6 +134,7 @@ def acall(self): "Image", "Text", "Component", + "Dataframe", "Pyplot", "File", "Task", diff --git a/backend/chainlit/action.py b/backend/chainlit/action.py index 088523da37..200bbf9c30 100644 --- a/backend/chainlit/action.py +++ b/backend/chainlit/action.py @@ -1,11 +1,12 @@ import uuid from typing import Optional -from chainlit.context import context -from chainlit.telemetry import trace_event from dataclasses_json import DataClassJsonMixin from pydantic.dataclasses import Field, dataclass +from chainlit.context import context +from chainlit.telemetry import trace_event + @dataclass class Action(DataClassJsonMixin): diff --git a/backend/chainlit/auth.py b/backend/chainlit/auth.py index 8ee0943f84..f45bb53b49 100644 --- a/backend/chainlit/auth.py +++ b/backend/chainlit/auth.py @@ -3,12 +3,13 @@ from typing import Any, Dict import jwt +from fastapi import Depends, HTTPException +from fastapi.security import OAuth2PasswordBearer + from chainlit.config import config from chainlit.data import get_data_layer from chainlit.oauth_providers import get_configured_oauth_providers from chainlit.user import User -from fastapi import Depends, HTTPException -from fastapi.security import OAuth2PasswordBearer reuseable_oauth = OAuth2PasswordBearer(tokenUrl="/login", auto_error=False) @@ -52,9 +53,8 @@ def create_jwt(data: User) -> str: to_encode: Dict[str, Any] = data.to_dict() to_encode.update( { - "exp": datetime.utcnow() + timedelta( - seconds=config.project.user_session_timeout - ), + "exp": datetime.utcnow() + + timedelta(seconds=config.project.user_session_timeout), } ) encoded_jwt = jwt.encode(to_encode, get_jwt_secret(), algorithm="HS256") diff --git a/backend/chainlit/chat_context.py b/backend/chainlit/chat_context.py index 5f7215ba56..81bf66b3d2 100644 --- a/backend/chainlit/chat_context.py +++ b/backend/chainlit/chat_context.py @@ -25,10 +25,10 @@ def add(self, message: "Message"): if context.session.id not in chat_contexts: chat_contexts[context.session.id] = [] - + if message not in chat_contexts[context.session.id]: chat_contexts[context.session.id].append(message) - + return message def remove(self, message: "Message") -> bool: diff --git a/backend/chainlit/chat_settings.py b/backend/chainlit/chat_settings.py index d6df3bd28a..f29e40812b 100644 --- a/backend/chainlit/chat_settings.py +++ b/backend/chainlit/chat_settings.py @@ -1,8 +1,9 @@ from typing import List +from pydantic.dataclasses import Field, dataclass + from chainlit.context import context from chainlit.input_widget import InputWidget -from pydantic.dataclasses import Field, dataclass @dataclass diff --git a/backend/chainlit/config.py b/backend/chainlit/config.py index d59da1bca1..5a0d2c4178 100644 --- a/backend/chainlit/config.py +++ b/backend/chainlit/config.py @@ -400,7 +400,7 @@ def init_config(log=False): dst = os.path.join(config_translation_dir, file) if not os.path.exists(dst): src = os.path.join(TRANSLATIONS_DIR, file) - with open(src, "r", encoding="utf-8") as f: + with open(src, encoding="utf-8") as f: translation = json.load(f) with open(dst, "w", encoding="utf-8") as f: json.dump(translation, f, indent=4) @@ -515,7 +515,7 @@ def load_config(): def lint_translations(): # Load the ground truth (en-US.json file from chainlit source code) src = os.path.join(TRANSLATIONS_DIR, "en-US.json") - with open(src, "r", encoding="utf-8") as f: + with open(src, encoding="utf-8") as f: truth = json.load(f) # Find the local app translations @@ -523,7 +523,7 @@ def lint_translations(): if file.endswith(".json"): # Load the translation file to_lint = os.path.join(config_translation_dir, file) - with open(to_lint, "r", encoding="utf-8") as f: + with open(to_lint, encoding="utf-8") as f: translation = json.load(f) # Lint the translation file diff --git a/backend/chainlit/context.py b/backend/chainlit/context.py index 9c8d653052..42333d091d 100644 --- a/backend/chainlit/context.py +++ b/backend/chainlit/context.py @@ -3,9 +3,10 @@ from contextvars import ContextVar from typing import TYPE_CHECKING, Dict, List, Optional, Union -from chainlit.session import ClientType, HTTPSession, WebsocketSession from lazify import LazyProxy +from chainlit.session import ClientType, HTTPSession, WebsocketSession + if TYPE_CHECKING: from chainlit.emitter import BaseChainlitEmitter from chainlit.step import Step @@ -104,7 +105,7 @@ def get_context() -> ChainlitContext: try: return context_var.get() except LookupError as e: - raise ChainlitContextException() from e + raise ChainlitContextException from e context: ChainlitContext = LazyProxy(get_context, enable_cache=False) diff --git a/backend/chainlit/data/acl.py b/backend/chainlit/data/acl.py index 65c040170a..60e45ac97f 100644 --- a/backend/chainlit/data/acl.py +++ b/backend/chainlit/data/acl.py @@ -1,6 +1,7 @@ -from chainlit.data import get_data_layer from fastapi import HTTPException +from chainlit.data import get_data_layer + async def is_thread_author(username: str, thread_id: str): data_layer = get_data_layer() @@ -8,7 +9,7 @@ async def is_thread_author(username: str, thread_id: str): raise HTTPException(status_code=400, detail="Data layer not initialized") thread_author = await data_layer.get_thread_author(thread_id) - + if not thread_author: raise HTTPException(status_code=404, detail="Thread not found") diff --git a/backend/chainlit/data/base.py b/backend/chainlit/data/base.py index d0df7187cd..2e268f3863 100644 --- a/backend/chainlit/data/base.py +++ b/backend/chainlit/data/base.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union +from typing import TYPE_CHECKING, Dict, List, Optional from chainlit.types import ( Feedback, diff --git a/backend/chainlit/data/dynamodb.py b/backend/chainlit/data/dynamodb.py index e067378b0e..c04f1c9883 100644 --- a/backend/chainlit/data/dynamodb.py +++ b/backend/chainlit/data/dynamodb.py @@ -11,6 +11,7 @@ import aiohttp import boto3 # type: ignore from boto3.dynamodb.types import TypeDeserializer, TypeSerializer + from chainlit.context import context from chainlit.data.base import BaseDataLayer from chainlit.data.storage_clients.base import BaseStorageClient @@ -29,9 +30,10 @@ from chainlit.user import PersistedUser, User if TYPE_CHECKING: - from chainlit.element import Element from mypy_boto3_dynamodb import DynamoDBClient + from chainlit.element import Element + _logger = logger.getChild("DynamoDB") _logger.setLevel(logging.WARNING) @@ -402,7 +404,7 @@ async def delete_thread(self, thread_id: str): BATCH_ITEM_SIZE = 25 # pylint: disable=invalid-name for i in range(0, len(delete_requests), BATCH_ITEM_SIZE): - chunk = delete_requests[i : i + BATCH_ITEM_SIZE] # noqa: E203 + chunk = delete_requests[i : i + BATCH_ITEM_SIZE] response = self.client.batch_write_item( RequestItems={ self.table_name: chunk, # type: ignore @@ -410,7 +412,7 @@ async def delete_thread(self, thread_id: str): ) backoff_time = 1 - while "UnprocessedItems" in response and response["UnprocessedItems"]: + while response.get("UnprocessedItems"): backoff_time *= 2 # Cap the backoff time at 32 seconds & add jitter delay = min(backoff_time, 32) + random.uniform(0, 1) diff --git a/backend/chainlit/data/literalai.py b/backend/chainlit/data/literalai.py index 7b2e39fbed..340fbdb5f9 100644 --- a/backend/chainlit/data/literalai.py +++ b/backend/chainlit/data/literalai.py @@ -349,11 +349,9 @@ async def delete_element(self, element_id: str, thread_id: Optional[str] = None) async def create_step(self, step_dict: "StepDict"): metadata = dict( step_dict.get("metadata", {}), - **{ - "waitForAnswer": step_dict.get("waitForAnswer"), - "language": step_dict.get("language"), - "showInput": step_dict.get("showInput"), - }, + waitForAnswer=step_dict.get("waitForAnswer"), + language=step_dict.get("language"), + showInput=step_dict.get("showInput"), ) step: LiteralStepDict = { diff --git a/backend/chainlit/data/sql_alchemy.py b/backend/chainlit/data/sql_alchemy.py index bb43ef7c16..5a694b081f 100644 --- a/backend/chainlit/data/sql_alchemy.py +++ b/backend/chainlit/data/sql_alchemy.py @@ -7,6 +7,11 @@ import aiofiles import aiohttp +from sqlalchemy import text +from sqlalchemy.exc import SQLAlchemyError +from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine +from sqlalchemy.orm import sessionmaker + from chainlit.data.base import BaseDataLayer from chainlit.data.storage_clients.base import BaseStorageClient from chainlit.data.utils import queue_until_user_message @@ -23,10 +28,6 @@ ThreadFilter, ) from chainlit.user import PersistedUser, User -from sqlalchemy import text -from sqlalchemy.exc import SQLAlchemyError -from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine -from sqlalchemy.orm import sessionmaker if TYPE_CHECKING: from chainlit.element import Element, ElementDict @@ -167,7 +168,7 @@ async def _get_user_id_by_thread(self, thread_id: str) -> Optional[str]: async def create_user(self, user: User) -> Optional[PersistedUser]: if self.show_logger: logger.info(f"SQLAlchemy: create_user, user_identifier={user.identifier}") - existing_user: Optional["PersistedUser"] = await self.get_user(user.identifier) + existing_user: Optional[PersistedUser] = await self.get_user(user.identifier) user_dict: Dict[str, Any] = { "identifier": str(user.identifier), "metadata": json.dumps(user.metadata) or {}, diff --git a/backend/chainlit/data/storage_clients/azure.py b/backend/chainlit/data/storage_clients/azure.py index fac2164e8a..d6a075d7e0 100644 --- a/backend/chainlit/data/storage_clients/azure.py +++ b/backend/chainlit/data/storage_clients/azure.py @@ -6,6 +6,7 @@ DataLakeServiceClient, FileSystemClient, ) + from chainlit.data.storage_clients.base import BaseStorageClient from chainlit.logger import logger diff --git a/backend/chainlit/data/storage_clients/s3.py b/backend/chainlit/data/storage_clients/s3.py index 4cfd6923c6..e982db07a7 100644 --- a/backend/chainlit/data/storage_clients/s3.py +++ b/backend/chainlit/data/storage_clients/s3.py @@ -1,6 +1,7 @@ from typing import Any, Dict, Union import boto3 # type: ignore + from chainlit.data.storage_clients.base import BaseStorageClient from chainlit.logger import logger diff --git a/backend/chainlit/discord/app.py b/backend/chainlit/discord/app.py index 4bee63628f..bf1732fcf8 100644 --- a/backend/chainlit/discord/app.py +++ b/backend/chainlit/discord/app.py @@ -12,6 +12,8 @@ import discord import filetype import httpx +from discord.ui import Button, View + from chainlit.config import config from chainlit.context import ChainlitContext, HTTPSession, context, context_var from chainlit.data import get_data_layer @@ -23,7 +25,6 @@ from chainlit.types import Feedback from chainlit.user import PersistedUser, User from chainlit.user_session import user_session -from discord.ui import Button, View class FeedbackView(View): diff --git a/backend/chainlit/element.py b/backend/chainlit/element.py index 4c26464a59..3012af7b4a 100644 --- a/backend/chainlit/element.py +++ b/backend/chainlit/element.py @@ -16,13 +16,14 @@ ) import filetype +from pydantic.dataclasses import Field, dataclass +from syncer import asyncio + from chainlit.context import context from chainlit.data import get_data_layer from chainlit.logger import logger from chainlit.telemetry import trace_event from chainlit.types import FileDict -from pydantic.dataclasses import Field, dataclass -from syncer import asyncio mime_types = { "text": "text/plain", @@ -154,7 +155,7 @@ async def _create(self) -> bool: try: asyncio.create_task(data_layer.create_element(self)) except Exception as e: - logger.error(f"Failed to create element: {str(e)}") + logger.error(f"Failed to create element: {e!s}") if not self.url and (not self.chainlit_key or self.updatable): file_dict = await context.session.persist_file( name=self.name, @@ -352,8 +353,7 @@ class Plotly(Element): content: str = "" def __post_init__(self) -> None: - from plotly import graph_objects as go - from plotly import io as pio + from plotly import graph_objects as go, io as pio if not isinstance(self.figure, go.Figure): raise TypeError("figure must be a plotly.graph_objects.Figure") diff --git a/backend/chainlit/emitter.py b/backend/chainlit/emitter.py index 5cc6a905b6..abf3fc43f1 100644 --- a/backend/chainlit/emitter.py +++ b/backend/chainlit/emitter.py @@ -288,9 +288,9 @@ async def send_ask_user( # End the task temporarily so that the User can answer the prompt await self.task_end() - final_res: Optional[ - Union["StepDict", "AskActionResponse", List["FileDict"]] - ] = None + final_res: Optional[Union[StepDict, AskActionResponse, List[FileDict]]] = ( + None + ) if user_res: interaction: Union[str, None] = None diff --git a/backend/chainlit/haystack/callbacks.py b/backend/chainlit/haystack/callbacks.py index 687ec7d4b0..bed15d8afd 100644 --- a/backend/chainlit/haystack/callbacks.py +++ b/backend/chainlit/haystack/callbacks.py @@ -1,13 +1,14 @@ import re from typing import Any, Generic, List, Optional, TypeVar -from chainlit import Message -from chainlit.step import Step -from chainlit.sync import run_sync from haystack.agents import Agent, Tool from haystack.agents.agent_step import AgentStep from literalai.helper import utc_now +from chainlit import Message +from chainlit.step import Step +from chainlit.sync import run_sync + T = TypeVar("T") @@ -131,7 +132,7 @@ def on_tool_finish( tool_result: str, tool_name: Optional[str] = None, tool_input: Optional[str] = None, - **kwargs: Any + **kwargs: Any, ) -> None: # Tool finished, send step with tool_result tool_step = self.stack.pop() diff --git a/backend/chainlit/input_widget.py b/backend/chainlit/input_widget.py index 58ee591653..6d33c48590 100644 --- a/backend/chainlit/input_widget.py +++ b/backend/chainlit/input_widget.py @@ -2,9 +2,10 @@ from collections import defaultdict from typing import Any, Dict, List, Optional -from chainlit.types import InputWidgetType from pydantic.dataclasses import Field, dataclass +from chainlit.types import InputWidgetType + @dataclass class InputWidget: @@ -75,7 +76,7 @@ class Select(InputWidget): initial: Optional[str] = None initial_index: Optional[int] = None initial_value: Optional[str] = None - values: List[str] = Field(default_factory=lambda: []) + values: List[str] = Field(default_factory=list) items: Dict[str, str] = Field(default_factory=lambda: defaultdict(dict)) def __post_init__( @@ -167,8 +168,8 @@ class Tags(InputWidget): """Useful to create an input for an array of strings.""" type: InputWidgetType = "tags" - initial: List[str] = Field(default_factory=lambda: []) - values: List[str] = Field(default_factory=lambda: []) + initial: List[str] = Field(default_factory=list) + values: List[str] = Field(default_factory=list) def to_dict(self) -> Dict[str, Any]: return { diff --git a/backend/chainlit/langchain/callbacks.py b/backend/chainlit/langchain/callbacks.py index 7449663dd4..526002cd36 100644 --- a/backend/chainlit/langchain/callbacks.py +++ b/backend/chainlit/langchain/callbacks.py @@ -468,7 +468,7 @@ async def _start_trace(self, run: Run) -> None: if ignore: return - step_type: "TrueStepType" = "undefined" + step_type: TrueStepType = "undefined" if run.run_type == "agent": step_type = "run" elif run.run_type == "chain": diff --git a/backend/chainlit/langflow/__init__.py b/backend/chainlit/langflow/__init__.py index ee8094fc0b..b11de4d5ac 100644 --- a/backend/chainlit/langflow/__init__.py +++ b/backend/chainlit/langflow/__init__.py @@ -8,6 +8,7 @@ from typing import Dict, Optional, Union import httpx + from chainlit.telemetry import trace_event diff --git a/backend/chainlit/llama_index/callbacks.py b/backend/chainlit/llama_index/callbacks.py index 88c8170962..6ca0081cfe 100644 --- a/backend/chainlit/llama_index/callbacks.py +++ b/backend/chainlit/llama_index/callbacks.py @@ -1,8 +1,5 @@ from typing import Any, Dict, List, Optional -from chainlit.context import context_var -from chainlit.element import Text -from chainlit.step import Step, StepType from literalai import ChatGeneration, CompletionGeneration, GenerationMessage from literalai.helper import utc_now from llama_index.core.callbacks import TokenCountingHandler @@ -10,6 +7,10 @@ from llama_index.core.llms import ChatMessage, ChatResponse, CompletionResponse from llama_index.core.tools.types import ToolMetadata +from chainlit.context import context_var +from chainlit.element import Text +from chainlit.step import Step, StepType + DEFAULT_IGNORE = [ CBEventType.CHUNKING, CBEventType.SYNTHESIZE, @@ -143,16 +144,15 @@ def on_event_end( context_var.get().loop.create_task(step.update()) elif event_type == CBEventType.LLM: - formatted_messages = payload.get( - EventPayload.MESSAGES - ) # type: Optional[List[ChatMessage]] + formatted_messages = payload.get(EventPayload.MESSAGES) # type: Optional[List[ChatMessage]] formatted_prompt = payload.get(EventPayload.PROMPT) response = payload.get(EventPayload.RESPONSE) if formatted_messages: messages = [ GenerationMessage( - role=m.role.value, content=m.content or "" # type: ignore + role=m.role.value, # type: ignore + content=m.content or "", ) for m in formatted_messages ] diff --git a/backend/chainlit/message.py b/backend/chainlit/message.py index 051089c119..88c071abeb 100644 --- a/backend/chainlit/message.py +++ b/backend/chainlit/message.py @@ -5,6 +5,9 @@ from abc import ABC from typing import Dict, List, Optional, Union, cast +from literalai.helper import utc_now +from literalai.observability.step import MessageStepType + from chainlit.action import Action from chainlit.chat_context import chat_context from chainlit.config import config @@ -22,8 +25,6 @@ AskSpec, FileDict, ) -from literalai.helper import utc_now -from literalai.observability.step import MessageStepType class MessageBase(ABC): @@ -113,7 +114,7 @@ async def update( except Exception as e: if self.fail_on_persist_error: raise e - logger.error(f"Failed to persist message update: {str(e)}") + logger.error(f"Failed to persist message update: {e!s}") await context.emitter.update_step(step_dict) @@ -133,7 +134,7 @@ async def remove(self): except Exception as e: if self.fail_on_persist_error: raise e - logger.error(f"Failed to persist message deletion: {str(e)}") + logger.error(f"Failed to persist message deletion: {e!s}") await context.emitter.delete_step(step_dict) @@ -149,7 +150,7 @@ async def _create(self): except Exception as e: if self.fail_on_persist_error: raise e - logger.error(f"Failed to persist message creation: {str(e)}") + logger.error(f"Failed to persist message creation: {e!s}") return step_dict diff --git a/backend/chainlit/mistralai/__init__.py b/backend/chainlit/mistralai/__init__.py index 2e4be2f3a4..4190352ccf 100644 --- a/backend/chainlit/mistralai/__init__.py +++ b/backend/chainlit/mistralai/__init__.py @@ -1,11 +1,12 @@ import asyncio from typing import Union -from chainlit.context import get_context -from chainlit.step import Step from literalai import ChatGeneration, CompletionGeneration from literalai.helper import timestamp_utc +from chainlit.context import get_context +from chainlit.step import Step + def instrument_mistralai(): from literalai.instrumentation.mistralai import instrument_mistralai diff --git a/backend/chainlit/oauth_providers.py b/backend/chainlit/oauth_providers.py index 5ed9228f51..82b09eeef2 100644 --- a/backend/chainlit/oauth_providers.py +++ b/backend/chainlit/oauth_providers.py @@ -4,9 +4,10 @@ from typing import Dict, List, Optional, Tuple import httpx +from fastapi import HTTPException + from chainlit.secret import random_secret from chainlit.user import User -from fastapi import HTTPException class OAuthProvider: @@ -22,10 +23,10 @@ def is_configured(self): return all([os.environ.get(env) for env in self.env]) async def get_token(self, code: str, url: str) -> str: - raise NotImplementedError() + raise NotImplementedError async def get_user_info(self, token: str) -> Tuple[Dict[str, str], User]: - raise NotImplementedError() + raise NotImplementedError def get_env_prefix(self) -> str: """Return environment prefix, like AZURE_AD.""" diff --git a/backend/chainlit/openai/__init__.py b/backend/chainlit/openai/__init__.py index 31fe793a22..11956ed9a8 100644 --- a/backend/chainlit/openai/__init__.py +++ b/backend/chainlit/openai/__init__.py @@ -1,11 +1,12 @@ import asyncio from typing import Union +from literalai import ChatGeneration, CompletionGeneration +from literalai.helper import timestamp_utc + from chainlit.context import local_steps from chainlit.step import Step from chainlit.utils import check_module_version -from literalai import ChatGeneration, CompletionGeneration -from literalai.helper import timestamp_utc def instrument_openai(): diff --git a/backend/chainlit/secret.py b/backend/chainlit/secret.py index 968193bf16..cc85257abe 100644 --- a/backend/chainlit/secret.py +++ b/backend/chainlit/secret.py @@ -6,4 +6,4 @@ def random_secret(length: int = 64): - return "".join((secrets.choice(chars) for i in range(length))) + return "".join(secrets.choice(chars) for i in range(length)) diff --git a/backend/chainlit/server.py b/backend/chainlit/server.py index 4893c8d03c..259cf57e14 100644 --- a/backend/chainlit/server.py +++ b/backend/chainlit/server.py @@ -12,6 +12,26 @@ from typing import Any, Optional, Union import socketio +from fastapi import ( + APIRouter, + Depends, + FastAPI, + Form, + HTTPException, + Query, + Request, + Response, + UploadFile, + status, +) +from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, RedirectResponse +from fastapi.security import OAuth2PasswordRequestForm +from fastapi.staticfiles import StaticFiles +from starlette.datastructures import URL +from starlette.middleware.cors import CORSMiddleware +from typing_extensions import Annotated +from watchfiles import awatch + from chainlit.auth import create_jwt, get_configuration, get_current_user from chainlit.config import ( APP_ROOT, @@ -37,26 +57,6 @@ UpdateFeedbackRequest, ) from chainlit.user import PersistedUser, User -from fastapi import ( - APIRouter, - Depends, - FastAPI, - File, - Form, - HTTPException, - Query, - Request, - Response, - UploadFile, - status, -) -from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, RedirectResponse -from fastapi.security import OAuth2PasswordRequestForm -from fastapi.staticfiles import StaticFiles -from starlette.datastructures import URL -from starlette.middleware.cors import CORSMiddleware -from typing_extensions import Annotated -from watchfiles import awatch from ._utils import is_path_inside @@ -248,6 +248,7 @@ async def slack_endpoint(req: Request): if os.environ.get("TEAMS_APP_ID") and os.environ.get("TEAMS_APP_PASSWORD"): from botbuilder.schema import Activity + from chainlit.teams.app import adapter, bot @router.post("/teams/events") @@ -316,7 +317,7 @@ def get_html_template(): index_html_file_path = os.path.join(build_dir, "index.html") - with open(index_html_file_path, "r", encoding="utf-8") as f: + with open(index_html_file_path, encoding="utf-8") as f: content = f.read() content = content.replace(PLACEHOLDER, tags) if js: @@ -895,7 +896,7 @@ async def get_file( detail="Unauthorized", ) - #TODO: Causes 401 error. See https://github.com/Chainlit/chainlit/issues/1472 + # TODO: Causes 401 error. See https://github.com/Chainlit/chainlit/issues/1472 # if current_user: # if not session.user or session.user.identifier != current_user.identifier: # raise HTTPException( diff --git a/backend/chainlit/session.py b/backend/chainlit/session.py index 2d675ac6e4..404713ec92 100644 --- a/backend/chainlit/session.py +++ b/backend/chainlit/session.py @@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Any, Callable, Deque, Dict, Literal, Optional, Union import aiofiles + from chainlit.logger import logger from chainlit.types import FileReference @@ -17,9 +18,9 @@ class JSONEncoderIgnoreNonSerializable(json.JSONEncoder): - def default(self, obj): + def default(self, o): try: - return super(JSONEncoderIgnoreNonSerializable, self).default(obj) + return super().default(o) except TypeError: return None @@ -112,9 +113,10 @@ async def persist_file( if path: # Copy the file from the given path - async with aiofiles.open(path, "rb") as src, aiofiles.open( - file_path, "wb" - ) as dst: + async with ( + aiofiles.open(path, "rb") as src, + aiofiles.open(file_path, "wb") as dst, + ): await dst.write(await src.read()) elif content: # Write the provided content to the file diff --git a/backend/chainlit/slack/app.py b/backend/chainlit/slack/app.py index 747d0af9dd..631e8c4b5e 100644 --- a/backend/chainlit/slack/app.py +++ b/backend/chainlit/slack/app.py @@ -7,6 +7,9 @@ from typing import Dict, List, Optional, Union import httpx +from slack_bolt.adapter.fastapi.async_handler import AsyncSlackRequestHandler +from slack_bolt.async_app import AsyncApp + from chainlit.config import config from chainlit.context import ChainlitContext, HTTPSession, context, context_var from chainlit.data import get_data_layer @@ -18,8 +21,6 @@ from chainlit.types import Feedback from chainlit.user import PersistedUser, User from chainlit.user_session import user_session -from slack_bolt.adapter.fastapi.async_handler import AsyncSlackRequestHandler -from slack_bolt.async_app import AsyncApp class SlackEmitter(BaseChainlitEmitter): diff --git a/backend/chainlit/socket.py b/backend/chainlit/socket.py index 064c4c2189..d79c76c16e 100644 --- a/backend/chainlit/socket.py +++ b/backend/chainlit/socket.py @@ -11,7 +11,6 @@ from chainlit.config import config from chainlit.context import init_ws_context from chainlit.data import get_data_layer -from chainlit.element import Element from chainlit.logger import logger from chainlit.message import ErrorMessage, Message from chainlit.server import sio diff --git a/backend/chainlit/step.py b/backend/chainlit/step.py index 0baa1fe196..4e7942c94a 100644 --- a/backend/chainlit/step.py +++ b/backend/chainlit/step.py @@ -7,6 +7,10 @@ from functools import wraps from typing import Callable, Dict, List, Optional, TypedDict, Union +from literalai import BaseGeneration +from literalai.helper import utc_now +from literalai.observability.step import StepType, TrueStepType + from chainlit.config import config from chainlit.context import CL_RUN_NAMES, context, local_steps from chainlit.data import get_data_layer @@ -14,9 +18,6 @@ from chainlit.logger import logger from chainlit.telemetry import trace_event from chainlit.types import FeedbackDict -from literalai import BaseGeneration -from literalai.helper import utc_now -from literalai.observability.step import StepType, TrueStepType def check_add_step_in_cot(step: "Step"): @@ -107,8 +108,8 @@ async def async_wrapper(*args, **kwargs): ) as step: try: step.input = flatten_args_kwargs(func, args, kwargs) - except: - pass + except Exception as e: + logger.exception(e) result = await func(*args, **kwargs) try: if result and not step.output: @@ -134,8 +135,8 @@ def sync_wrapper(*args, **kwargs): ) as step: try: step.input = flatten_args_kwargs(func, args, kwargs) - except: - pass + except Exception as e: + logger.exception(e) result = func(*args, **kwargs) try: if result and not step.output: @@ -317,7 +318,7 @@ async def update(self): except Exception as e: if self.fail_on_persist_error: raise e - logger.error(f"Failed to persist step update: {str(e)}") + logger.error(f"Failed to persist step update: {e!s}") tasks = [el.send(for_id=self.id) for el in self.elements] await asyncio.gather(*tasks) @@ -344,7 +345,7 @@ async def remove(self): except Exception as e: if self.fail_on_persist_error: raise e - logger.error(f"Failed to persist step deletion: {str(e)}") + logger.error(f"Failed to persist step deletion: {e!s}") await context.emitter.delete_step(step_dict) @@ -371,7 +372,7 @@ async def send(self): except Exception as e: if self.fail_on_persist_error: raise e - logger.error(f"Failed to persist step creation: {str(e)}") + logger.error(f"Failed to persist step creation: {e!s}") tasks = [el.send(for_id=self.id) for el in self.elements] await asyncio.gather(*tasks) diff --git a/backend/chainlit/sync.py b/backend/chainlit/sync.py index 66761bcbff..09d4ee72de 100644 --- a/backend/chainlit/sync.py +++ b/backend/chainlit/sync.py @@ -10,9 +10,10 @@ import threading from asyncer import asyncify -from chainlit.context import context_var from syncer import sync +from chainlit.context import context_var + make_async = asyncify T_Retval = TypeVar("T_Retval") diff --git a/backend/chainlit/teams/app.py b/backend/chainlit/teams/app.py index b0f66445a2..ecfac32487 100644 --- a/backend/chainlit/teams/app.py +++ b/backend/chainlit/teams/app.py @@ -28,6 +28,7 @@ ChannelAccount, HeroCard, ) + from chainlit.config import config from chainlit.context import ChainlitContext, HTTPSession, context, context_var from chainlit.data import get_data_layer diff --git a/backend/chainlit/types.py b/backend/chainlit/types.py index b094716f93..2721e9eb85 100644 --- a/backend/chainlit/types.py +++ b/backend/chainlit/types.py @@ -79,7 +79,7 @@ def from_dict(cls, page_info_dict: Dict) -> "PageInfo": class HasFromDict(Protocol[T]): @classmethod def from_dict(cls, obj_dict: Any) -> T: - raise NotImplementedError() + raise NotImplementedError @dataclass @@ -168,11 +168,13 @@ class InputAudioChunk: elapsedTime: float data: bytes + class OutputAudioChunk(TypedDict): track: str mimeType: str data: bytes + @dataclass class AskFileResponse: id: str diff --git a/backend/chainlit/utils.py b/backend/chainlit/utils.py index 79049c4308..ad93906ad3 100644 --- a/backend/chainlit/utils.py +++ b/backend/chainlit/utils.py @@ -6,12 +6,13 @@ from typing import Callable import click +from fastapi import FastAPI +from packaging import version + from chainlit.auth import ensure_jwt_secret from chainlit.context import context from chainlit.logger import logger from chainlit.message import ErrorMessage -from fastapi import FastAPI -from packaging import version def wrap_user_function(user_function: Callable, with_task=False) -> Callable: diff --git a/backend/poetry.lock b/backend/poetry.lock index 53d6e2ce4f..5ccb1972ae 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -4440,29 +4440,29 @@ files = [ [[package]] name = "ruff" -version = "0.7.1" +version = "0.7.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.7.1-py3-none-linux_armv6l.whl", hash = "sha256:cb1bc5ed9403daa7da05475d615739cc0212e861b7306f314379d958592aaa89"}, - {file = "ruff-0.7.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:27c1c52a8d199a257ff1e5582d078eab7145129aa02721815ca8fa4f9612dc35"}, - {file = "ruff-0.7.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:588a34e1ef2ea55b4ddfec26bbe76bc866e92523d8c6cdec5e8aceefeff02d99"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94fc32f9cdf72dc75c451e5f072758b118ab8100727168a3df58502b43a599ca"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:985818742b833bffa543a84d1cc11b5e6871de1b4e0ac3060a59a2bae3969250"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32f1e8a192e261366c702c5fb2ece9f68d26625f198a25c408861c16dc2dea9c"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:699085bf05819588551b11751eff33e9ca58b1b86a6843e1b082a7de40da1565"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:344cc2b0814047dc8c3a8ff2cd1f3d808bb23c6658db830d25147339d9bf9ea7"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4316bbf69d5a859cc937890c7ac7a6551252b6a01b1d2c97e8fc96e45a7c8b4a"}, - {file = "ruff-0.7.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79d3af9dca4c56043e738a4d6dd1e9444b6d6c10598ac52d146e331eb155a8ad"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c5c121b46abde94a505175524e51891f829414e093cd8326d6e741ecfc0a9112"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8422104078324ea250886954e48f1373a8fe7de59283d747c3a7eca050b4e378"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:56aad830af8a9db644e80098fe4984a948e2b6fc2e73891538f43bbe478461b8"}, - {file = "ruff-0.7.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:658304f02f68d3a83c998ad8bf91f9b4f53e93e5412b8f2388359d55869727fd"}, - {file = "ruff-0.7.1-py3-none-win32.whl", hash = "sha256:b517a2011333eb7ce2d402652ecaa0ac1a30c114fbbd55c6b8ee466a7f600ee9"}, - {file = "ruff-0.7.1-py3-none-win_amd64.whl", hash = "sha256:f38c41fcde1728736b4eb2b18850f6d1e3eedd9678c914dede554a70d5241307"}, - {file = "ruff-0.7.1-py3-none-win_arm64.whl", hash = "sha256:19aa200ec824c0f36d0c9114c8ec0087082021732979a359d6f3c390a6ff2a37"}, - {file = "ruff-0.7.1.tar.gz", hash = "sha256:9d8a41d4aa2dad1575adb98a82870cf5db5f76b2938cf2206c22c940034a36f4"}, + {file = "ruff-0.7.4-py3-none-linux_armv6l.whl", hash = "sha256:a4919925e7684a3f18e18243cd6bea7cfb8e968a6eaa8437971f681b7ec51478"}, + {file = "ruff-0.7.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cfb365c135b830778dda8c04fb7d4280ed0b984e1aec27f574445231e20d6c63"}, + {file = "ruff-0.7.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:63a569b36bc66fbadec5beaa539dd81e0527cb258b94e29e0531ce41bacc1f20"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d06218747d361d06fd2fdac734e7fa92df36df93035db3dc2ad7aa9852cb109"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e0cea28d0944f74ebc33e9f934238f15c758841f9f5edd180b5315c203293452"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:80094ecd4793c68b2571b128f91754d60f692d64bc0d7272ec9197fdd09bf9ea"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:997512325c6620d1c4c2b15db49ef59543ef9cd0f4aa8065ec2ae5103cedc7e7"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00b4cf3a6b5fad6d1a66e7574d78956bbd09abfd6c8a997798f01f5da3d46a05"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7dbdc7d8274e1422722933d1edddfdc65b4336abf0b16dfcb9dedd6e6a517d06"}, + {file = "ruff-0.7.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e92dfb5f00eaedb1501b2f906ccabfd67b2355bdf117fea9719fc99ac2145bc"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3bd726099f277d735dc38900b6a8d6cf070f80828877941983a57bca1cd92172"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2e32829c429dd081ee5ba39aef436603e5b22335c3d3fff013cd585806a6486a"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:662a63b4971807623f6f90c1fb664613f67cc182dc4d991471c23c541fee62dd"}, + {file = "ruff-0.7.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:876f5e09eaae3eb76814c1d3b68879891d6fde4824c015d48e7a7da4cf066a3a"}, + {file = "ruff-0.7.4-py3-none-win32.whl", hash = "sha256:75c53f54904be42dd52a548728a5b572344b50d9b2873d13a3f8c5e3b91f5cac"}, + {file = "ruff-0.7.4-py3-none-win_amd64.whl", hash = "sha256:745775c7b39f914238ed1f1b0bebed0b9155a17cd8bc0b08d3c87e4703b990d6"}, + {file = "ruff-0.7.4-py3-none-win_arm64.whl", hash = "sha256:11bff065102c3ae9d3ea4dc9ecdfe5a5171349cdd0787c1fc64761212fc9cf1f"}, + {file = "ruff-0.7.4.tar.gz", hash = "sha256:cd12e35031f5af6b9b93715d8c4f40360070b2041f81273d0527683d5708fce2"}, ] [[package]] diff --git a/backend/pyproject.toml b/backend/pyproject.toml index ed25c3828c..b1b76589ad 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -102,7 +102,6 @@ pandas-stubs = { version = "^2.2.2", python = ">=3.9" } [tool.mypy] python_version = "3.9" - [[tool.mypy.overrides]] module = [ "boto3.dynamodb.types", @@ -122,10 +121,6 @@ ignore_missing_imports = true - - - - [tool.poetry.group.custom-data] optional = true @@ -136,7 +131,6 @@ boto3 = "^1.34.73" azure-identity = "^1.14.1" azure-storage-file-datalake = "^12.14.0" - [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" @@ -146,9 +140,12 @@ build-backend = "poetry.core.masonry.api" testpaths = ["tests"] asyncio_mode = "auto" +[tool.ruff] +target-version = "py39" [tool.ruff.lint] -select = ["I"] +select = ["E", "F", "I", "LOG", "UP", "T10", "ISC", "ICN", "LOG", "G", "PIE", "PT", "Q", "RSE", "FURB", "RUF"] +ignore = ["E712", "E501", "UP006", "UP035","PIE790", "PT004", "RUF005", "RUF006", "RUF012", "ISC001"] [tool.ruff.lint.isort] combine-as-imports = true diff --git a/backend/tests/data/conftest.py b/backend/tests/data/conftest.py index e7a98d9081..84276df670 100644 --- a/backend/tests/data/conftest.py +++ b/backend/tests/data/conftest.py @@ -1,6 +1,7 @@ from unittest.mock import AsyncMock import pytest + from chainlit.data.storage_clients.base import BaseStorageClient from chainlit.user import User diff --git a/backend/tests/data/storage_clients/test_s3.py b/backend/tests/data/storage_clients/test_s3.py index 38804f8c67..6dc238583e 100644 --- a/backend/tests/data/storage_clients/test_s3.py +++ b/backend/tests/data/storage_clients/test_s3.py @@ -2,9 +2,10 @@ import boto3 # type: ignore import pytest -from chainlit.data.storage_clients.s3 import S3StorageClient from moto import mock_aws +from chainlit.data.storage_clients.s3 import S3StorageClient + # Fixtures for setting up the DynamoDB table @pytest.fixture diff --git a/backend/tests/data/test_literalai.py b/backend/tests/data/test_literalai.py index ae9a2ee93b..ffbe74c5d8 100644 --- a/backend/tests/data/test_literalai.py +++ b/backend/tests/data/test_literalai.py @@ -40,7 +40,7 @@ async def mock_literal_client(monkeypatch: pytest.MonkeyPatch): client = Mock(spec=AsyncLiteralClient) client.api = AsyncMock(spec=AsyncLiteralAPI) monkeypatch.setattr("literalai.AsyncLiteralClient", client) - yield client + return client @pytest.fixture diff --git a/backend/tests/data/test_sql_alchemy.py b/backend/tests/data/test_sql_alchemy.py index 8597b6ce40..decd5e34c5 100644 --- a/backend/tests/data/test_sql_alchemy.py +++ b/backend/tests/data/test_sql_alchemy.py @@ -2,13 +2,13 @@ from pathlib import Path import pytest -from chainlit.data.sql_alchemy import SQLAlchemyDataLayer -from chainlit.data.storage_clients.base import BaseStorageClient -from chainlit.element import Text from sqlalchemy import text from sqlalchemy.ext.asyncio import create_async_engine from chainlit import User +from chainlit.data.sql_alchemy import SQLAlchemyDataLayer +from chainlit.data.storage_clients.base import BaseStorageClient +from chainlit.element import Text @pytest.fixture @@ -120,7 +120,7 @@ async def data_layer(mock_storage_client: BaseStorageClient, tmp_path: Path): # Create SQLAlchemyDataLayer instance data_layer = SQLAlchemyDataLayer(conninfo, storage_provider=mock_storage_client) - yield data_layer + return data_layer async def test_create_and_get_element( diff --git a/backend/tests/llama_index/test_callbacks.py b/backend/tests/llama_index/test_callbacks.py index edf8ec4cf4..8c89cf51cf 100644 --- a/backend/tests/llama_index/test_callbacks.py +++ b/backend/tests/llama_index/test_callbacks.py @@ -1,10 +1,11 @@ from unittest.mock import patch -from chainlit.llama_index.callbacks import LlamaIndexCallbackHandler -from chainlit.step import Step from llama_index.core.callbacks.schema import CBEventType, EventPayload from llama_index.core.tools.types import ToolMetadata +from chainlit.llama_index.callbacks import LlamaIndexCallbackHandler +from chainlit.step import Step + async def test_on_event_start_for_function_calls(mock_chainlit_context): TEST_EVENT_ID = "test_event_id" diff --git a/backend/tests/test_callbacks.py b/backend/tests/test_callbacks.py index c00674ba9b..ec9c1ea342 100644 --- a/backend/tests/test_callbacks.py +++ b/backend/tests/test_callbacks.py @@ -2,11 +2,8 @@ from unittest.mock import AsyncMock, Mock -import pytest - from chainlit import config -from chainlit.callbacks import data_layer, password_auth_callback -from chainlit.data import get_data_layer +from chainlit.callbacks import password_auth_callback from chainlit.data.base import BaseDataLayer from chainlit.user import User @@ -66,7 +63,6 @@ async def test_oauth_callback(test_config: config.ChainlitConfig): from unittest.mock import patch from chainlit.callbacks import oauth_callback - from chainlit.config import config from chainlit.user import User # Mock the get_configured_oauth_providers function @@ -135,7 +131,6 @@ async def handle_message(message: Message): async def test_on_stop(mock_chainlit_context, test_config: config.ChainlitConfig): from chainlit.callbacks import on_stop - from chainlit.config import config async with mock_chainlit_context: stop_called = False @@ -160,7 +155,6 @@ async def test_action_callback( ): from chainlit.action import Action from chainlit.callbacks import action_callback - from chainlit.config import config async with mock_chainlit_context: action_handled = False @@ -186,7 +180,6 @@ async def test_on_settings_update( mock_chainlit_context, test_config: config.ChainlitConfig ): from chainlit.callbacks import on_settings_update - from chainlit.config import config async with mock_chainlit_context: settings_updated = False @@ -209,7 +202,6 @@ async def handle_settings_update(settings: dict): async def test_author_rename(test_config: config.ChainlitConfig): from chainlit.callbacks import author_rename - from chainlit.config import config @author_rename async def rename_author(author: str) -> str: @@ -240,7 +232,6 @@ async def rename_author(author: str) -> str: async def test_on_chat_start(mock_chainlit_context, test_config: config.ChainlitConfig): from chainlit.callbacks import on_chat_start - from chainlit.config import config async with mock_chainlit_context as context: chat_started = False @@ -267,7 +258,6 @@ async def test_on_chat_resume( mock_chainlit_context, test_config: config.ChainlitConfig ): from chainlit.callbacks import on_chat_resume - from chainlit.config import config from chainlit.types import ThreadDict async with mock_chainlit_context: @@ -305,7 +295,6 @@ async def test_set_chat_profiles( mock_chainlit_context, test_config: config.ChainlitConfig ): from chainlit.callbacks import set_chat_profiles - from chainlit.config import config from chainlit.types import ChatProfile async with mock_chainlit_context: @@ -333,7 +322,6 @@ async def get_chat_profiles(user): async def test_set_starters(mock_chainlit_context, test_config: config.ChainlitConfig): from chainlit.callbacks import set_starters - from chainlit.config import config from chainlit.types import Starter async with mock_chainlit_context: @@ -364,7 +352,6 @@ async def get_starters(user): async def test_on_chat_end(mock_chainlit_context, test_config: config.ChainlitConfig): from chainlit.callbacks import on_chat_end - from chainlit.config import config async with mock_chainlit_context as context: chat_ended = False diff --git a/backend/tests/test_context.py b/backend/tests/test_context.py index c5449c9e91..6ffb12cc0e 100644 --- a/backend/tests/test_context.py +++ b/backend/tests/test_context.py @@ -1,6 +1,7 @@ from unittest.mock import Mock import pytest + from chainlit.context import ( ChainlitContext, ChainlitContextException, diff --git a/backend/tests/test_emitter.py b/backend/tests/test_emitter.py index 48c6df017d..e831baa568 100644 --- a/backend/tests/test_emitter.py +++ b/backend/tests/test_emitter.py @@ -1,6 +1,7 @@ from unittest.mock import MagicMock import pytest + from chainlit.element import ElementDict from chainlit.emitter import ChainlitEmitter from chainlit.step import StepDict diff --git a/backend/tests/test_server.py b/backend/tests/test_server.py index c61827c8a3..6bc607d46a 100644 --- a/backend/tests/test_server.py +++ b/backend/tests/test_server.py @@ -1,7 +1,6 @@ import datetime # Added import for datetime import os import pathlib -import tempfile from pathlib import Path from typing import Callable from unittest.mock import AsyncMock, Mock, create_autospec, mock_open @@ -10,10 +9,8 @@ from fastapi.testclient import TestClient from chainlit.auth import get_current_user -from chainlit.config import APP_ROOT, ChainlitConfig, load_config +from chainlit.config import APP_ROOT, ChainlitConfig from chainlit.server import app -from chainlit.session import WebsocketSession -from chainlit.types import FileReference from chainlit.user import PersistedUser # Added import for PersistedUser @@ -322,7 +319,7 @@ def test_get_file_non_existing_session( # Attempt to access the file without authentication by providing an invalid session_id response = test_client.get( - f"/project/file/nonexistent?session_id=unauthenticated_session_id" + "/project/file/nonexistent?session_id=unauthenticated_session_id" ) # Verify the response diff --git a/cypress/e2e/elements/main.py b/cypress/e2e/elements/main.py index 15f9def917..d7a412231d 100644 --- a/cypress/e2e/elements/main.py +++ b/cypress/e2e/elements/main.py @@ -3,13 +3,11 @@ @cl.step(type="tool") async def gen_img(): - return cl.Image(path="./cat.jpeg", name="image1", display="inline") @cl.on_chat_start async def start(): - img = await gen_img() # Element should not be inlined or referenced diff --git a/lint-staged.config.js b/lint-staged.config.js index 8befb50e38..36ebdd95eb 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -3,8 +3,8 @@ module.exports = { '**/*.{js,jsx,ts,tsx}': ['npx prettier --write', 'npx eslint --fix'], '**/*.{ts,tsx}': [() => 'tsc --skipLibCheck --noEmit'], '**/*.py': [ - 'cd backend && poetry run ruff check --fix', - 'cd backend && poetry run ruff format', + 'poetry run -C backend ruff check --fix', + 'poetry run -C backend ruff format', () => 'pnpm run lintPython' ], '.github/{workflows,actions}/**': ['actionlint']