From 5df6d1cc41c413d8b67ce5a0975276ce42240cfb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 11:48:32 +0000 Subject: [PATCH 1/8] Update dependency quart to v0.19.6 --- app/backend/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/backend/requirements.txt b/app/backend/requirements.txt index ecc53549..0ca99d28 100644 --- a/app/backend/requirements.txt +++ b/app/backend/requirements.txt @@ -1,5 +1,5 @@ azure-identity==1.15.0 -quart==0.19.3 +quart==0.19.6 langchain==0.1.20 langchain_openai tiktoken From b28644b7ec30ce897b68b7e59fd100bc5c4ac6b1 Mon Sep 17 00:00:00 2001 From: pilitz Date: Fri, 28 Jun 2024 08:33:34 +0200 Subject: [PATCH 2/8] fixed RollbackMessage --- app/backend/requirements.txt | 2 +- .../UserChatMessage/RollbackMessage.tsx | 3 ++- app/frontend/src/pages/chat/Chat.tsx | 7 +++++-- app/frontend/src/service/storage.ts | 20 +++++++++++++++++++ requirements-dev.txt | 1 - 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/backend/requirements.txt b/app/backend/requirements.txt index 0ca99d28..afa81d1b 100644 --- a/app/backend/requirements.txt +++ b/app/backend/requirements.txt @@ -9,7 +9,7 @@ azure-monitor-opentelemetry==1.0.0b15 opentelemetry-instrumentation-asgi==0.40b0 opentelemetry-instrumentation-requests==0.40b0 opentelemetry-instrumentation-aiohttp-client==0.40b0 -werkzeug==3.0.1 +werkzeug==3.0.3 joserfc requests sqlalchemy==2.0.19 diff --git a/app/frontend/src/components/UserChatMessage/RollbackMessage.tsx b/app/frontend/src/components/UserChatMessage/RollbackMessage.tsx index a30e6ab7..690e0888 100644 --- a/app/frontend/src/components/UserChatMessage/RollbackMessage.tsx +++ b/app/frontend/src/components/UserChatMessage/RollbackMessage.tsx @@ -1,6 +1,6 @@ import { Button, Tooltip } from "@fluentui/react-components" import { useTranslation } from "react-i18next"; -import { indexedDBStorage, popLastInDB } from "../../service/storage"; +import { deleteFromDB, indexedDBStorage, popLastInDB } from "../../service/storage"; import { DeleteArrowBackRegular } from "@fluentui/react-icons"; import styles from "./UserChatMessage.module.css" @@ -30,6 +30,7 @@ export const RollBackMessage = ({ message, setQuestion, answers, setAnswers, sto } if (answers.length == 0) { lastQuestionRef.current = "" + deleteFromDB(storage) } else { lastQuestionRef.current = last[1] } diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index 24449a13..e8d57b3f 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -68,8 +68,11 @@ const Chat = () => { setIsLoading(true); getStartDataFromDB(storage).then((stored) => { if (stored) { - setAnswers([...answers.concat(stored)]); - lastQuestionRef.current = stored[stored.length - 1][0]; + try { + setAnswers([...answers.concat(stored)]); + lastQuestionRef.current = stored[stored.length - 1][0]; + } + catch { } } }); setIsLoading(false); diff --git a/app/frontend/src/service/storage.ts b/app/frontend/src/service/storage.ts index 731d9005..239c6cb5 100644 --- a/app/frontend/src/service/storage.ts +++ b/app/frontend/src/service/storage.ts @@ -127,3 +127,23 @@ export function popLastInDB(storage: indexedDBStorage) { }; }; } + +export function deleteFromDB(storage: indexedDBStorage) { + let openRequest = indexedDB.open(storage.db_name, VERSION); + openRequest.onupgradeneeded = function () { + let db = openRequest.result; + if (!db.objectStoreNames.contains(storage.objectStore_name)) { + db.createObjectStore(storage.objectStore_name, { keyPath: "id" }); + } + }; + openRequest.onerror = function () { + console.error("Error", openRequest.error); + }; + openRequest.onsuccess = function () { + let chat = openRequest.result.transaction(storage.objectStore_name, "readwrite").objectStore(storage.objectStore_name); + let deleted = chat.delete(ID); + deleted.onerror = function () { + console.error("Error", deleted.error); + }; + }; +} diff --git a/requirements-dev.txt b/requirements-dev.txt index 385e3dd5..b3306675 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,5 +1,4 @@ -r app/backend/requirements.txt --r scripts/requirements.txt ruff black pytest From 8ce4dbb43e15d1c7cc8837dc45bce714c63a9a6e Mon Sep 17 00:00:00 2001 From: Paul Ilitz <102222789+pilitz@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:02:41 +0200 Subject: [PATCH 3/8] Update python-test.yaml removed deprecated `ruff ` and added `ruff check ` --- .github/workflows/python-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-test.yaml b/.github/workflows/python-test.yaml index dd966223..ea443575 100644 --- a/.github/workflows/python-test.yaml +++ b/.github/workflows/python-test.yaml @@ -36,6 +36,6 @@ jobs: python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Lint with ruff - run: ruff . + run: ruff check . - name: Run Python tests run: python3 -m pytest From ad4548ada4cf89471be0da8f8935299689464bee Mon Sep 17 00:00:00 2001 From: pilitz <102222789+pilitz@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:41:21 +0200 Subject: [PATCH 4/8] make ruff happy --- app/backend/app.py | 14 ++++++----- app/backend/brainstorm/brainstorm.py | 16 ++++++------- app/backend/chat/chat.py | 25 ++++++++++---------- app/backend/chat/chatresult.py | 1 + app/backend/core/authentification.py | 4 +++- app/backend/core/confighelper.py | 7 +++--- app/backend/core/datahelper.py | 15 ++++++------ app/backend/core/helper.py | 4 +++- app/backend/core/llmhelper.py | 6 +++-- app/backend/core/modelhelper.py | 2 +- app/backend/core/textsplit.py | 4 ++-- app/backend/core/types/AppConfig.py | 12 ++++++---- app/backend/core/types/AzureChatGPTConfig.py | 3 ++- app/backend/core/types/Chunk.py | 4 +++- app/backend/core/types/LlmConfigs.py | 4 +++- app/backend/core/types/countresult.py | 1 + app/backend/init_app.py | 17 +++++++------ app/backend/summarize/summarize.py | 18 +++++++------- tests/integration/test_app.py | 11 +++++---- tests/unit/test_confighelper.py | 2 +- tests/unit/test_datahelper.py | 2 +- tests/unit/test_helper.py | 2 ++ tests/unit/test_llmhelper.py | 2 +- tests/unit/test_textsplit.py | 4 +--- 24 files changed, 101 insertions(+), 79 deletions(-) diff --git a/app/backend/app.py b/app/backend/app.py index 05466c89..9d50ce57 100644 --- a/app/backend/app.py +++ b/app/backend/app.py @@ -3,6 +3,7 @@ import os import time from typing import cast + from azure.monitor.opentelemetry import configure_azure_monitor from opentelemetry.instrumentation.aiohttp_client import AioHttpClientInstrumentor from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware @@ -14,15 +15,16 @@ jsonify, make_response, request, + send_file, send_from_directory, - send_file ) -from init_app import initApp -from core.modelhelper import num_tokens_from_message + from core.authentification import AuthentificationHelper, AuthError +from core.helper import format_as_ndjson +from core.modelhelper import num_tokens_from_message from core.types.AppConfig import AppConfig from core.types.countresult import CountResult -from core.helper import format_as_ndjson +from init_app import initApp bp = Blueprint("routes", __name__, static_folder='static') @@ -35,7 +37,7 @@ async def handleAuthError(error: AuthError): @bp.route("/") async def index(): - cfg = get_config_and_authentificate() + get_config_and_authentificate() return await bp.send_static_file("index.html") @bp.route("/favicon.ico") @@ -44,7 +46,7 @@ async def favicon(): @bp.route("/assets/") async def assets(path): - cfg = get_config_and_authentificate() + get_config_and_authentificate() return await send_from_directory("static/assets", path) diff --git a/app/backend/brainstorm/brainstorm.py b/app/backend/brainstorm/brainstorm.py index 77fa2381..9a642516 100644 --- a/app/backend/brainstorm/brainstorm.py +++ b/app/backend/brainstorm/brainstorm.py @@ -1,18 +1,18 @@ -from typing import Any, Optional -from langchain.chains import LLMChain +from typing import Optional + +from langchain.chains import LLMChain, SequentialChain from langchain.prompts import PromptTemplate -from langchain.chains import SequentialChain from langchain_community.callbacks import get_openai_callback from langchain_core.runnables.base import RunnableSerializable from brainstorm.brainstormresult import BrainstormResult -from core.types.LlmConfigs import LlmConfigs -from core.datahelper import Repository -from core.types.Config import ApproachConfig +from core.datahelper import Repository, Requestinfo from core.types.AzureChatGPTConfig import AzureChatGPTConfig -from core.datahelper import Requestinfo +from core.types.Config import ApproachConfig +from core.types.LlmConfigs import LlmConfigs + -class Brainstorm(): +class Brainstorm: """ Simple brainstorm implementation. One shot generation of certain markdown files. Translates the result into a target language. """ diff --git a/app/backend/chat/chat.py b/app/backend/chat/chat.py index 038827cc..7e17fbc6 100644 --- a/app/backend/chat/chat.py +++ b/app/backend/chat/chat.py @@ -1,28 +1,29 @@ -from typing import Any, AsyncGenerator, Optional, Sequence, Tuple import asyncio +from typing import Any, AsyncGenerator, Optional, Sequence, Tuple + +from langchain.callbacks.streaming_aiter import AsyncIteratorCallbackHandler +from langchain.chains import LLMChain +from langchain.memory import ConversationBufferMemory from langchain.prompts import ( ChatPromptTemplate, - MessagesPlaceholder, HumanMessagePromptTemplate, - SystemMessagePromptTemplate + MessagesPlaceholder, + SystemMessagePromptTemplate, ) -from langchain.chains import LLMChain -from langchain.memory import ConversationBufferMemory -from langchain.callbacks.streaming_aiter import AsyncIteratorCallbackHandler -from langchain_core.messages import AIMessage from langchain_community.callbacks import get_openai_callback +from langchain_core.messages import AIMessage from langchain_core.runnables.base import RunnableSerializable from chat.chatresult import ChatResult -from core.datahelper import Requestinfo +from core.datahelper import Repository, Requestinfo from core.modelhelper import num_tokens_from_message, num_tokens_from_messages -from core.datahelper import Repository -from core.types.Config import ApproachConfig +from core.types.AzureChatGPTConfig import AzureChatGPTConfig from core.types.Chunk import Chunk, ChunkInfo +from core.types.Config import ApproachConfig from core.types.LlmConfigs import LlmConfigs -from core.types.AzureChatGPTConfig import AzureChatGPTConfig -class Chat(): + +class Chat: """Chat with a llm via multiple steps. """ diff --git a/app/backend/chat/chatresult.py b/app/backend/chat/chatresult.py index 56abfc68..babda81a 100644 --- a/app/backend/chat/chatresult.py +++ b/app/backend/chat/chatresult.py @@ -1,4 +1,5 @@ from typing import TypedDict + class ChatResult(TypedDict): content: str \ No newline at end of file diff --git a/app/backend/core/authentification.py b/app/backend/core/authentification.py index d2e1ac3b..b7ca89d6 100644 --- a/app/backend/core/authentification.py +++ b/app/backend/core/authentification.py @@ -1,8 +1,10 @@ import functools + import requests from joserfc import jwt from joserfc.jwk import KeySet + class AuthError(Exception): def __init__(self, error, status_code): self.error = error @@ -44,7 +46,7 @@ def authentificate(self, accesstoken): if self.role not in roles: raise AuthError("Sie haben noch keinen Zugang zu MUCGPT freigeschalten. Wie das geht, erfahren sie in im folgendem WILMA Artikel: https://wilma.muenchen.de/pages/it-steuerung-management/apps/wiki/kuenstliche-intelligenz/list/view/91f43afa-3315-478f-a9a4-7f50ae2a32f2.", status_code=401) - return claims; + return claims def decode(self, token): keyset = self.get_jwks_data(self.issuer) diff --git a/app/backend/core/confighelper.py b/app/backend/core/confighelper.py index 543bc140..80213cc5 100644 --- a/app/backend/core/confighelper.py +++ b/app/backend/core/confighelper.py @@ -1,6 +1,7 @@ import json -from core.types.Config import to_typed_config, Config +from core.types.Config import Config, to_typed_config + class ConfigHelper: """Loads an available configuration. @@ -10,9 +11,9 @@ def __init__(self, base_path: str, env: str, base_config_name: str = "base"): self.base_config_name = base_config_name self.env = env def loadData(self) -> Config: - with open(self.base_path + self.env + ".json", 'r') as f: + with open(self.base_path + self.env + ".json") as f: env_config = json.load(f) - with open(self.base_path + self.base_config_name + ".json", 'r') as f: + with open(self.base_path + self.base_config_name + ".json") as f: base_config = json.load(f) result_dict = dict(env_config,**base_config) return to_typed_config(result_dict) \ No newline at end of file diff --git a/app/backend/core/datahelper.py b/app/backend/core/datahelper.py index 4627c2db..b5538b46 100644 --- a/app/backend/core/datahelper.py +++ b/app/backend/core/datahelper.py @@ -1,13 +1,11 @@ -from sqlalchemy.orm import declarative_base -from sqlalchemy import Column, Integer, String, DateTime -from datetime import datetime -from sqlalchemy import create_engine -from sqlalchemy.engine import URL -from sqlalchemy.orm import Session -from sqlalchemy import func import csv import io +from datetime import datetime + +from sqlalchemy import Column, DateTime, Integer, String, create_engine, func +from sqlalchemy.engine import URL +from sqlalchemy.orm import Session, declarative_base Base = declarative_base() @@ -25,7 +23,8 @@ class Requestinfo(Base): updated_on = Column(DateTime(), default=datetime.now, onupdate=datetime.now) def __repr__(self): - return ' ' % (self.id, self.department, self.tokencount, self.method, self.messagecount) + return f'' + diff --git a/app/backend/core/helper.py b/app/backend/core/helper.py index c1d398a2..2f3cd235 100644 --- a/app/backend/core/helper.py +++ b/app/backend/core/helper.py @@ -1,9 +1,11 @@ -from typing import AsyncGenerator import json import logging +from typing import AsyncGenerator + from core.types.Chunk import Chunk + async def format_as_ndjson(r: AsyncGenerator[Chunk, None]) -> AsyncGenerator[str, None]: """Converts stream of Chunks into Stream of serialized JSON Objects diff --git a/app/backend/core/llmhelper.py b/app/backend/core/llmhelper.py index c06e7ca3..14378179 100644 --- a/app/backend/core/llmhelper.py +++ b/app/backend/core/llmhelper.py @@ -1,9 +1,11 @@ -from langchain_openai import AzureChatOpenAI +from langchain_community.llms.fake import FakeListLLM from langchain_core.runnables import ConfigurableField -from langchain_community.llms.fake import FakeListLLM from langchain_core.runnables.base import RunnableSerializable +from langchain_openai import AzureChatOpenAI + from core.types.SupportedModels import SupportedModels + def getModel(chatgpt_model: str, max_tokens: int, n: int, diff --git a/app/backend/core/modelhelper.py b/app/backend/core/modelhelper.py index d41ca76c..db268ee1 100644 --- a/app/backend/core/modelhelper.py +++ b/app/backend/core/modelhelper.py @@ -34,7 +34,7 @@ def get_token_limit(model_id: str) -> int: return MODELS_2_TOKEN_LIMITS[model_id] -def num_tokens_from_messages(messages: 'list[dict[str, str]]', model: str) -> int: +def num_tokens_from_messages(messages: list[dict[str, str]], model: str) -> int: """ Calculate the number of tokens required to encode a list of messages Args: diff --git a/app/backend/core/textsplit.py b/app/backend/core/textsplit.py index 08a408dc..719e3e4b 100644 --- a/app/backend/core/textsplit.py +++ b/app/backend/core/textsplit.py @@ -1,8 +1,8 @@ from typing import List -from langchain.text_splitter import TokenTextSplitter + import PyPDF2 from langchain.docstore.document import Document - +from langchain.text_splitter import TokenTextSplitter def textToDocs(text: str, chunk_size=2500, chunk_overlap=100) -> List[Document]: diff --git a/app/backend/core/types/AppConfig.py b/app/backend/core/types/AppConfig.py index 8c15d1c9..56c4090d 100644 --- a/app/backend/core/types/AppConfig.py +++ b/app/backend/core/types/AppConfig.py @@ -1,13 +1,15 @@ from typing import TypedDict + from azure.identity.aio import DefaultAzureCredential -from core.types.AzureChatGPTConfig import AzureChatGPTConfig -from summarize.summarize import Summarize -from chat.chat import Chat + from brainstorm.brainstorm import Brainstorm +from chat.chat import Chat from core.authentification import AuthentificationHelper -from core.types.Config import Config from core.datahelper import Repository -from core.types.Config import BackendConfig +from core.types.AzureChatGPTConfig import AzureChatGPTConfig +from core.types.Config import BackendConfig, Config +from summarize.summarize import Summarize + class AppConfig(TypedDict): """Config for the app, contains all clients and informations, that are needed diff --git a/app/backend/core/types/AzureChatGPTConfig.py b/app/backend/core/types/AzureChatGPTConfig.py index 83a6d9ff..ef378289 100644 --- a/app/backend/core/types/AzureChatGPTConfig.py +++ b/app/backend/core/types/AzureChatGPTConfig.py @@ -1,6 +1,7 @@ -from azure.core.credentials import AccessToken from typing import TypedDict +from azure.core.credentials import AccessToken + class AzureChatGPTConfig(TypedDict): """Contains all information, that describes an AzureOpenAI endpoint diff --git a/app/backend/core/types/Chunk.py b/app/backend/core/types/Chunk.py index 2001581d..cce40aa7 100644 --- a/app/backend/core/types/Chunk.py +++ b/app/backend/core/types/Chunk.py @@ -1,4 +1,6 @@ -from typing import TypedDict, Literal +from typing import Literal, TypedDict + + class Chunk(TypedDict): """Represents a chunk during streaming. Has 3 modes: E: Error, message contains the error message. diff --git a/app/backend/core/types/LlmConfigs.py b/app/backend/core/types/LlmConfigs.py index d4b331e2..9d23d498 100644 --- a/app/backend/core/types/LlmConfigs.py +++ b/app/backend/core/types/LlmConfigs.py @@ -1,4 +1,6 @@ -from typing_extensions import List, NotRequired, TypedDict +from typing import List + +from typing_extensions import NotRequired, TypedDict class LlmConfigs(TypedDict, total=False): diff --git a/app/backend/core/types/countresult.py b/app/backend/core/types/countresult.py index fbb0b83b..a6b77905 100644 --- a/app/backend/core/types/countresult.py +++ b/app/backend/core/types/countresult.py @@ -1,4 +1,5 @@ from typing import TypedDict + class CountResult(TypedDict): count: int \ No newline at end of file diff --git a/app/backend/init_app.py b/app/backend/init_app.py index 0980cb72..ca439183 100644 --- a/app/backend/init_app.py +++ b/app/backend/init_app.py @@ -1,16 +1,19 @@ import os from typing import Tuple -from core.types.AzureChatGPTConfig import AzureChatGPTConfig -from core.types.Config import BackendConfig -from core.llmhelper import getModel -from core.datahelper import Repository, Base + +from azure.identity.aio import DefaultAzureCredential + +from brainstorm.brainstorm import Brainstorm +from chat.chat import Chat from core.authentification import AuthentificationHelper from core.confighelper import ConfigHelper +from core.datahelper import Base, Repository +from core.llmhelper import getModel from core.types.AppConfig import AppConfig +from core.types.AzureChatGPTConfig import AzureChatGPTConfig +from core.types.Config import BackendConfig from summarize.summarize import Summarize -from chat.chat import Chat -from brainstorm.brainstorm import Brainstorm -from azure.identity.aio import DefaultAzureCredential + def read_env(): """reads configured values from env diff --git a/app/backend/summarize/summarize.py b/app/backend/summarize/summarize.py index a53c07ea..55ee35d7 100644 --- a/app/backend/summarize/summarize.py +++ b/app/backend/summarize/summarize.py @@ -1,22 +1,22 @@ -from concurrent.futures import ThreadPoolExecutor -from typing import Any, List, Optional, Tuple import json import re +from concurrent.futures import ThreadPoolExecutor +from typing import Any, List, Optional, Tuple + +from langchain.chains import LLMChain, SequentialChain from langchain.prompts import PromptTemplate -from langchain.chains import SequentialChain, LLMChain from langchain_community.callbacks import get_openai_callback from langchain_core.runnables.base import RunnableSerializable -from summarize.summarizeresult import SummarizeResult -from core.datahelper import Repository -from core.types.Config import ApproachConfig -from core.datahelper import Requestinfo -from core.textsplit import splitPDF, splitText +from core.datahelper import Repository, Requestinfo +from core.textsplit import splitPDF, splitText from core.types.AzureChatGPTConfig import AzureChatGPTConfig +from core.types.Config import ApproachConfig from core.types.LlmConfigs import LlmConfigs +from summarize.summarizeresult import SummarizeResult -class Summarize(): +class Summarize: """Summarizes text. Chunks long texts. Individual chunks where summarized with Chain of Density prompting: https://arxiv.org/abs/2309.04269. Afterwards the text is translated into the target language.""" user_sum_prompt = """ diff --git a/tests/integration/test_app.py b/tests/integration/test_app.py index 223c37f3..e4098cf8 100644 --- a/tests/integration/test_app.py +++ b/tests/integration/test_app.py @@ -1,19 +1,20 @@ +import json from io import BytesIO from unittest import mock + +import PyPDF2 import pytest import quart.testing.app from httpx import Request, Response from openai import BadRequestError from quart.datastructures import FileStorage -import json + import app -import PyPDF2 -from core.types.Chunk import Chunk from brainstorm.brainstormresult import BrainstormResult +from core.types.Chunk import Chunk from summarize.summarizeresult import SummarizeResult - def fake_response(http_code): return Response(http_code, request=Request(method="get", url="https://foo.bar/")) @@ -92,7 +93,7 @@ async def test_brainstorm_exception(client, monkeypatch,caplog): } response = await client.post('/brainstorm', json=data) assert response.status_code == 500 - result = await response.get_json() + await response.get_json() assert "Exception in /error: something bad happened" in caplog.text @pytest.mark.asyncio diff --git a/tests/unit/test_confighelper.py b/tests/unit/test_confighelper.py index b4da3ce6..89827938 100644 --- a/tests/unit/test_confighelper.py +++ b/tests/unit/test_confighelper.py @@ -1,9 +1,9 @@ +import os import unittest import pytest from core.confighelper import ConfigHelper -import os class Test_Confighelper(unittest.TestCase): diff --git a/tests/unit/test_datahelper.py b/tests/unit/test_datahelper.py index 7f7ea49f..243c3d8e 100644 --- a/tests/unit/test_datahelper.py +++ b/tests/unit/test_datahelper.py @@ -15,4 +15,4 @@ def test_requestinfo_creation(self): self.assertEqual(request.department, 'IT') self.assertEqual(request.messagecount, 50) self.assertEqual(request.method, 'GET') - self.assertEqual(str(request), ' ') \ No newline at end of file + self.assertEqual(str(request), '') \ No newline at end of file diff --git a/tests/unit/test_helper.py b/tests/unit/test_helper.py index d5a71afa..83c02ffd 100644 --- a/tests/unit/test_helper.py +++ b/tests/unit/test_helper.py @@ -1,5 +1,7 @@ import unittest + import pytest + from core.helper import format_as_ndjson diff --git a/tests/unit/test_llmhelper.py b/tests/unit/test_llmhelper.py index 4cd51807..937256af 100644 --- a/tests/unit/test_llmhelper.py +++ b/tests/unit/test_llmhelper.py @@ -1,9 +1,9 @@ import unittest import pytest +from langchain_core.runnables.base import RunnableSerializable from core.llmhelper import getModel -from langchain_core.runnables.base import RunnableSerializable class Test_LLMhelper(unittest.TestCase): diff --git a/tests/unit/test_textsplit.py b/tests/unit/test_textsplit.py index cc0ee6c3..9bcd88e2 100644 --- a/tests/unit/test_textsplit.py +++ b/tests/unit/test_textsplit.py @@ -2,9 +2,7 @@ import pytest -import PyPDF2 - -from core.textsplit import textToDocs, PDFtoDocs, splitText, splitPDF +from core.textsplit import PDFtoDocs, splitPDF, splitText, textToDocs class Test_Testsplit(unittest.TestCase): From bf6230096aa95319a03e87466975598dec1bee04 Mon Sep 17 00:00:00 2001 From: pilitz <102222789+pilitz@users.noreply.github.com> Date: Fri, 28 Jun 2024 09:54:37 +0200 Subject: [PATCH 5/8] fixed filepath in test --- tests/unit/test_textsplit.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_textsplit.py b/tests/unit/test_textsplit.py index 9bcd88e2..9abaf87f 100644 --- a/tests/unit/test_textsplit.py +++ b/tests/unit/test_textsplit.py @@ -1,3 +1,4 @@ +import os import unittest import pytest @@ -16,8 +17,10 @@ def test_textToDocs(self): @pytest.mark.asyncio @pytest.mark.unit def test_PDFtoDocs(self): - path= r"app\frontend\src\assets\mucgpt_cheatsheet.pdf" - self.assertEqual(len(PDFtoDocs(path)), 2) + file_path = os.path.join('app', 'frontend', 'src', 'assets', 'mucgpt_cheatsheet.pdf') + file_path = os.path.abspath(file_path) + assert os.path.exists(file_path), "File does not exist" + self.assertEqual(len(PDFtoDocs(file_path)), 2) @pytest.mark.asyncio @pytest.mark.unit @@ -28,5 +31,7 @@ def test_splitText(self): @pytest.mark.asyncio @pytest.mark.unit def test_splitPDF(self): - path= r"app\frontend\src\assets\mucgpt_cheatsheet.pdf" - self.assertEqual(len(splitPDF(path)), 2) \ No newline at end of file + file_path = os.path.join('app', 'frontend', 'src', 'assets', 'mucgpt_cheatsheet.pdf') + file_path = os.path.abspath(file_path) + assert os.path.exists(file_path), "File does not exist" + self.assertEqual(len(splitPDF(file_path)), 2) \ No newline at end of file From 763a218de8ae664794ad248b09a76398fc54efad Mon Sep 17 00:00:00 2001 From: pilitz <102222789+pilitz@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:03:24 +0200 Subject: [PATCH 6/8] fixed filepath in test --- tests/unit/test_confighelper.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_confighelper.py b/tests/unit/test_confighelper.py index 89827938..0218ef8c 100644 --- a/tests/unit/test_confighelper.py +++ b/tests/unit/test_confighelper.py @@ -10,7 +10,10 @@ class Test_Confighelper(unittest.TestCase): @pytest.mark.asyncio @pytest.mark.unit def test_confighelper_create(self): - path=r"app\\backend\\ressources\\" + path = os.path.join('app', 'backend', 'ressources', '') + path = os.path.abspath(path) + assert os.path.exists(path), "File does not exist" + path = path + "\\" env="dev" helper = ConfigHelper(path, env) self.assertEqual(helper.base_config_name, "base") @@ -25,7 +28,10 @@ def test_confighelper_create(self): @pytest.mark.asyncio @pytest.mark.unit def test_confighelper_loadData(self): - path=r"app\\backend\\ressources\\" + path = os.path.join('app', 'backend', 'ressources', '') + path = os.path.abspath(path) + assert os.path.exists(path), "File does not exist" + path = path + "\\" env="dev" helper = ConfigHelper(path, env) data = helper.loadData() @@ -36,7 +42,10 @@ def test_confighelper_loadData(self): @pytest.mark.asyncio @pytest.mark.unit def test_confighelper_loadData_fail(self): - path=r"app\\backend\\ressources\\" + path = os.path.join('app', 'backend', 'ressources', '') + path = os.path.abspath(path) + assert os.path.exists(path), "File does not exist" + path = path + "\\" env="super" filename = path + env + ".json" with open(filename, "w") as file: From d269cfd9f9926d176301f26a7013de551dc8ae22 Mon Sep 17 00:00:00 2001 From: pilitz <102222789+pilitz@users.noreply.github.com> Date: Fri, 28 Jun 2024 10:09:16 +0200 Subject: [PATCH 7/8] updated test --- tests/unit/test_confighelper.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/test_confighelper.py b/tests/unit/test_confighelper.py index 0218ef8c..4283e3df 100644 --- a/tests/unit/test_confighelper.py +++ b/tests/unit/test_confighelper.py @@ -13,7 +13,7 @@ def test_confighelper_create(self): path = os.path.join('app', 'backend', 'ressources', '') path = os.path.abspath(path) assert os.path.exists(path), "File does not exist" - path = path + "\\" + path = path + "/" env="dev" helper = ConfigHelper(path, env) self.assertEqual(helper.base_config_name, "base") @@ -31,7 +31,7 @@ def test_confighelper_loadData(self): path = os.path.join('app', 'backend', 'ressources', '') path = os.path.abspath(path) assert os.path.exists(path), "File does not exist" - path = path + "\\" + path = path + "/" env="dev" helper = ConfigHelper(path, env) data = helper.loadData() @@ -45,7 +45,7 @@ def test_confighelper_loadData_fail(self): path = os.path.join('app', 'backend', 'ressources', '') path = os.path.abspath(path) assert os.path.exists(path), "File does not exist" - path = path + "\\" + path = path + "/" env="super" filename = path + env + ".json" with open(filename, "w") as file: From e6905778fd268efb600a016e496f9a9d7fdde602 Mon Sep 17 00:00:00 2001 From: "michael.jaumann" Date: Fri, 28 Jun 2024 10:55:32 +0200 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=90=9E=20using=20mock=20credential?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/integration/conftest.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index e2b33198..57e86228 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -1,4 +1,5 @@ from collections import namedtuple +from unittest import mock import openai import pytest @@ -61,12 +62,12 @@ async def client(monkeypatch, mock_openai_chatcompletion): monkeypatch.setenv("DB_USER", "not used") - #with mock.patch("app.DefaultAzureCredential") as mock_default_azure_credential: - #mock_default_azure_credential.return_value = MockAzureCredential() - quart_app = app.create_app() + with mock.patch("init_app.DefaultAzureCredential") as mock_default_azure_credential: + mock_default_azure_credential.return_value = MockAzureCredential() + quart_app = app.create_app() - async with quart_app.test_app() as test_app: - quart_app.config.update({"TESTING": True}) + async with quart_app.test_app() as test_app: + quart_app.config.update({"TESTING": True}) - yield test_app.test_client() + yield test_app.test_client()