Skip to content

Commit

Permalink
Merge pull request #17 from it-at-m/renovate/quart-0.x
Browse files Browse the repository at this point in the history
Update dependency quart to v0.19.6 and werkzeug 3.0.3, fixed tests and cleaned up some code
  • Loading branch information
pilitz authored Jun 28, 2024
2 parents 8218476 + e690577 commit e9d3c1f
Show file tree
Hide file tree
Showing 31 changed files with 159 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/python-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 8 additions & 6 deletions app/backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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')

Expand All @@ -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")
Expand All @@ -44,7 +46,7 @@ async def favicon():

@bp.route("/assets/<path:path>")
async def assets(path):
cfg = get_config_and_authentificate()
get_config_and_authentificate()
return await send_from_directory("static/assets", path)


Expand Down
16 changes: 8 additions & 8 deletions app/backend/brainstorm/brainstorm.py
Original file line number Diff line number Diff line change
@@ -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.
"""
Expand Down
25 changes: 13 additions & 12 deletions app/backend/chat/chat.py
Original file line number Diff line number Diff line change
@@ -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.
"""

Expand Down
1 change: 1 addition & 0 deletions app/backend/chat/chatresult.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import TypedDict


class ChatResult(TypedDict):
content: str
4 changes: 3 additions & 1 deletion app/backend/core/authentification.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 4 additions & 3 deletions app/backend/core/confighelper.py
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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)
15 changes: 7 additions & 8 deletions app/backend/core/datahelper.py
Original file line number Diff line number Diff line change
@@ -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()

Expand All @@ -25,7 +23,8 @@ class Requestinfo(Base):
updated_on = Column(DateTime(), default=datetime.now, onupdate=datetime.now)

def __repr__(self):
return '<ID %r, Department %r, Tokencount %r, Method %r, Messagecount %r> ' % (self.id, self.department, self.tokencount, self.method, self.messagecount)
return f'<ID {self.id!r}, Department {self.department!r}, Tokencount {self.tokencount!r}, Method {self.method!r}, Messagecount {self.messagecount!r}>'




Expand Down
4 changes: 3 additions & 1 deletion app/backend/core/helper.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
6 changes: 4 additions & 2 deletions app/backend/core/llmhelper.py
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
2 changes: 1 addition & 1 deletion app/backend/core/modelhelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions app/backend/core/textsplit.py
Original file line number Diff line number Diff line change
@@ -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]:
Expand Down
12 changes: 7 additions & 5 deletions app/backend/core/types/AppConfig.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
3 changes: 2 additions & 1 deletion app/backend/core/types/AzureChatGPTConfig.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 3 additions & 1 deletion app/backend/core/types/Chunk.py
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
4 changes: 3 additions & 1 deletion app/backend/core/types/LlmConfigs.py
Original file line number Diff line number Diff line change
@@ -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):
Expand Down
1 change: 1 addition & 0 deletions app/backend/core/types/countresult.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import TypedDict


class CountResult(TypedDict):
count: int
17 changes: 10 additions & 7 deletions app/backend/init_app.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
4 changes: 2 additions & 2 deletions app/backend/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
azure-identity==1.15.0
quart==0.19.3
quart==0.19.6
langchain==0.1.20
langchain_openai
tiktoken
Expand All @@ -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
Expand Down
18 changes: 9 additions & 9 deletions app/backend/summarize/summarize.py
Original file line number Diff line number Diff line change
@@ -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 = """
Expand Down
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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]
}
Expand Down
Loading

0 comments on commit e9d3c1f

Please sign in to comment.