diff --git a/app/endpoints/chat.py b/app/endpoints/chat.py index 6d227ec..dd50dc0 100644 --- a/app/endpoints/chat.py +++ b/app/endpoints/chat.py @@ -1,17 +1,17 @@ -import httpx import json from typing import Union -from fastapi import APIRouter, Security, HTTPException +from fastapi import APIRouter, HTTPException, Security from fastapi.responses import StreamingResponse +import httpx -from app.schemas.chat import ChatCompletionRequest, ChatCompletion, ChatCompletionChunk -from app.utils.security import check_api_key -from app.utils.lifespan import clients -from app.utils.config import LOGGER +from app.schemas.chat import ChatCompletion, ChatCompletionChunk, ChatCompletionRequest +from app.schemas.config import LANGUAGE_MODEL_TYPE from app.tools import * from app.tools import __all__ as tools_list -from app.schemas.config import LANGUAGE_MODEL_TYPE +from app.utils.config import LOGGER +from app.utils.lifespan import clients +from app.utils.security import check_api_key router = APIRouter() diff --git a/app/endpoints/chunks.py b/app/endpoints/chunks.py index 91583ab..0f9b748 100644 --- a/app/endpoints/chunks.py +++ b/app/endpoints/chunks.py @@ -1,10 +1,10 @@ from fastapi import APIRouter, Security from qdrant_client.http.models import Filter, HasIdCondition -from app.schemas.chunks import Chunks, Chunk, ChunkRequest -from app.utils.security import check_api_key -from app.utils.lifespan import clients from app.helpers._vectorstore import VectorStore +from app.schemas.chunks import Chunk, ChunkRequest, Chunks +from app.utils.lifespan import clients +from app.utils.security import check_api_key router = APIRouter() diff --git a/app/endpoints/collections.py b/app/endpoints/collections.py index 0efb531..fa6550e 100644 --- a/app/endpoints/collections.py +++ b/app/endpoints/collections.py @@ -1,13 +1,13 @@ -from typing import Union, Optional +from typing import Optional, Union -from fastapi import APIRouter, Security, Response +from fastapi import APIRouter, Response, Security -from app.schemas.collections import Collections, Collection -from app.utils.security import check_api_key -from app.utils.lifespan import clients -from app.utils.data import delete_contents -from app.utils.config import LOGGER from app.helpers import VectorStore +from app.schemas.collections import Collection, Collections +from app.utils.config import LOGGER +from app.utils.data import delete_contents +from app.utils.lifespan import clients +from app.utils.security import check_api_key router = APIRouter() diff --git a/app/endpoints/completions.py b/app/endpoints/completions.py index dbb0087..f1c0a7b 100644 --- a/app/endpoints/completions.py +++ b/app/endpoints/completions.py @@ -4,7 +4,6 @@ from app.utils.lifespan import clients from app.utils.security import check_api_key - router = APIRouter() diff --git a/app/endpoints/embeddings.py b/app/endpoints/embeddings.py index 3dc53e1..941a84a 100644 --- a/app/endpoints/embeddings.py +++ b/app/endpoints/embeddings.py @@ -1,9 +1,9 @@ -from fastapi import APIRouter, Security, HTTPException +from fastapi import APIRouter, HTTPException, Security -from app.schemas.embeddings import EmbeddingsRequest, Embeddings +from app.schemas.config import EMBEDDINGS_MODEL_TYPE +from app.schemas.embeddings import Embeddings, EmbeddingsRequest from app.utils.lifespan import clients from app.utils.security import check_api_key -from app.schemas.config import EMBEDDINGS_MODEL_TYPE router = APIRouter() diff --git a/app/endpoints/files.py b/app/endpoints/files.py index d1239a0..8f5e0da 100644 --- a/app/endpoints/files.py +++ b/app/endpoints/files.py @@ -1,6 +1,6 @@ import base64 -import uuid from typing import List, Optional, Union +import uuid from botocore.exceptions import ClientError from fastapi import APIRouter, HTTPException, Response, Security, UploadFile diff --git a/app/endpoints/models.py b/app/endpoints/models.py index c51f7f9..d8760e1 100644 --- a/app/endpoints/models.py +++ b/app/endpoints/models.py @@ -1,4 +1,4 @@ -from typing import Union, Optional +from typing import Optional, Union from fastapi import APIRouter, Security @@ -6,7 +6,6 @@ from app.utils.lifespan import clients from app.utils.security import check_api_key - router = APIRouter() diff --git a/app/endpoints/search.py b/app/endpoints/search.py index a541760..1a3f686 100644 --- a/app/endpoints/search.py +++ b/app/endpoints/search.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Security from app.helpers import VectorStore -from app.schemas.search import SearchRequest, Searches +from app.schemas.search import Searches, SearchRequest from app.utils.lifespan import clients from app.utils.security import check_api_key diff --git a/app/endpoints/tools.py b/app/endpoints/tools.py index 26748a8..44852ba 100644 --- a/app/endpoints/tools.py +++ b/app/endpoints/tools.py @@ -1,9 +1,9 @@ from fastapi import APIRouter, Security from app.schemas.tools import Tools -from app.utils.security import check_api_key from app.tools import * from app.tools import __all__ as tools_list +from app.utils.security import check_api_key router = APIRouter() diff --git a/app/helpers/_gristkeymanager.py b/app/helpers/_gristkeymanager.py index fd2d070..20fc86b 100644 --- a/app/helpers/_gristkeymanager.py +++ b/app/helpers/_gristkeymanager.py @@ -1,7 +1,7 @@ import datetime as dt -from grist_api import GristDocAPI from fastapi import HTTPException +from grist_api import GristDocAPI from redis import Redis diff --git a/app/helpers/_universalparser.py b/app/helpers/_universalparser.py index 713e565..9231c15 100644 --- a/app/helpers/_universalparser.py +++ b/app/helpers/_universalparser.py @@ -2,14 +2,15 @@ from typing import List, Optional from docx import Document +from langchain.docstore.document import Document as LangchainDocument from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_community.document_loaders import PDFMinerLoader -from langchain.docstore.document import Document as LangchainDocument import magic -from ._textcleaner import TextCleaner from app.schemas.files import JsonFile +from ._textcleaner import TextCleaner + class UniversalParser: DOCX_TYPE = "application/vnd.openxmlformats-officedocument.wordprocessingml.document" diff --git a/app/schemas/chunks.py b/app/schemas/chunks.py index 72cb81b..4c06187 100644 --- a/app/schemas/chunks.py +++ b/app/schemas/chunks.py @@ -1,4 +1,4 @@ -from typing import Literal, List +from typing import List, Literal from pydantic import BaseModel diff --git a/app/schemas/completions.py b/app/schemas/completions.py index 3a4030c..4e72628 100644 --- a/app/schemas/completions.py +++ b/app/schemas/completions.py @@ -1,7 +1,7 @@ -from typing import Optional, List, Union, Dict, Iterable +from typing import Dict, Iterable, List, Optional, Union -from pydantic import BaseModel, Field from openai.types import Completion +from pydantic import BaseModel, Field class CompletionRequest(BaseModel): diff --git a/app/schemas/embeddings.py b/app/schemas/embeddings.py index 01e0288..246fe02 100644 --- a/app/schemas/embeddings.py +++ b/app/schemas/embeddings.py @@ -1,7 +1,7 @@ -from typing import Optional, Literal, List, Union +from typing import List, Literal, Optional, Union -from pydantic import BaseModel from openai.types import CreateEmbeddingResponse +from pydantic import BaseModel class EmbeddingsRequest(BaseModel): diff --git a/app/schemas/files.py b/app/schemas/files.py index 7122e98..a58a94b 100644 --- a/app/schemas/files.py +++ b/app/schemas/files.py @@ -1,4 +1,4 @@ -from typing import Literal, List, Optional, Dict +from typing import Dict, List, Literal, Optional from uuid import UUID from pydantic import BaseModel diff --git a/app/schemas/models.py b/app/schemas/models.py index 3ab586d..2482395 100644 --- a/app/schemas/models.py +++ b/app/schemas/models.py @@ -1,9 +1,9 @@ -from typing import Literal, List +from typing import List, Literal -from pydantic import BaseModel from openai.types import Model +from pydantic import BaseModel -from app.schemas.config import LANGUAGE_MODEL_TYPE, EMBEDDINGS_MODEL_TYPE +from app.schemas.config import EMBEDDINGS_MODEL_TYPE, LANGUAGE_MODEL_TYPE class Model(Model): diff --git a/app/schemas/tools.py b/app/schemas/tools.py index a0ca514..c34fb76 100644 --- a/app/schemas/tools.py +++ b/app/schemas/tools.py @@ -1,4 +1,4 @@ -from typing import Literal, List +from typing import List, Literal from pydantic import BaseModel diff --git a/app/tests/conftest.py b/app/tests/conftest.py index 6ebde43..e761802 100644 --- a/app/tests/conftest.py +++ b/app/tests/conftest.py @@ -1,6 +1,7 @@ +import logging + import pytest import requests -import logging def pytest_addoption(parser): diff --git a/app/tests/test_files.py b/app/tests/test_files.py index 7bdfa45..61eb42e 100644 --- a/app/tests/test_files.py +++ b/app/tests/test_files.py @@ -1,12 +1,13 @@ -import os import logging +import os + import pytest import wget -from app.schemas.files import Upload, Uploads, Files, File -from app.schemas.collections import Collections, Collection -from app.schemas.models import Models, Model -from app.schemas.config import PRIVATE_COLLECTION_TYPE, METADATA_COLLECTION, LANGUAGE_MODEL_TYPE, EMBEDDINGS_MODEL_TYPE +from app.schemas.collections import Collection, Collections +from app.schemas.config import EMBEDDINGS_MODEL_TYPE, LANGUAGE_MODEL_TYPE, METADATA_COLLECTION, PRIVATE_COLLECTION_TYPE +from app.schemas.files import File, Files, Upload, Uploads +from app.schemas.models import Model, Models from app.utils.security import encode_string diff --git a/app/tests/test_tools.py b/app/tests/test_tools.py index 989c43a..d6a6eed 100644 --- a/app/tests/test_tools.py +++ b/app/tests/test_tools.py @@ -1,6 +1,6 @@ import pytest -from app.schemas.tools import Tools, Tool +from app.schemas.tools import Tool, Tools @pytest.mark.usefixtures("args", "session") diff --git a/app/tests/tools/test_baserag.py b/app/tests/tools/test_baserag.py index 468ad4b..f103b4a 100644 --- a/app/tests/tools/test_baserag.py +++ b/app/tests/tools/test_baserag.py @@ -1,12 +1,12 @@ -import os import logging +import os import pytest import wget -from app.schemas.config import EMBEDDINGS_MODEL_TYPE, LANGUAGE_MODEL_TYPE -from app.schemas.models import Models, Model from app.schemas.chat import ChatCompletion +from app.schemas.config import EMBEDDINGS_MODEL_TYPE, LANGUAGE_MODEL_TYPE +from app.schemas.models import Model, Models @pytest.mark.usefixtures("args", "session") diff --git a/app/tools/__init__.py b/app/tools/__init__.py index e239995..522f271 100644 --- a/app/tools/__init__.py +++ b/app/tools/__init__.py @@ -1,4 +1,3 @@ from ._baserag import BaseRAG -from ._fewshots import FewShots -__all__ = ["BaseRAG", "FewShots"] +__all__ = ["BaseRAG"] diff --git a/app/tools/_fewshots.py b/app/tools/_fewshots.py deleted file mode 100644 index 8d1510e..0000000 --- a/app/tools/_fewshots.py +++ /dev/null @@ -1,64 +0,0 @@ -from typing import Optional - - -from app.helpers import VectorStore -from app.schemas.tools import ToolOutput - - -class FewShots: - """ - Fewshots RAG. - - Args: - embeddings_model (str): OpenAI embeddings model - collection (str): Collection name. The collection must have question/answer pairs in metadata. - k (int, optional): Top K per collection. Defaults to 4. - """ - - COLLECTION = "service-public-plus" - DEFAULT_SYSTEM_PROMPT = "Tu es un générateur de réponse automatique à une expérience utilisateur. Tu parles un français courtois." - - DEFAULT_PROMPT_TEMPLATE = """Vous incarnez un agent chevronné de l'administration française, expert en matière de procédures et réglementations administratives. Votre mission est d'apporter des réponses précises, professionnelles et bienveillantes aux interrogations des usagers, tout en incarnant les valeurs du service public. - -Contexte : -Vous avez accès à une base de connaissances exhaustive contenant des exemples de questions fréquemment posées et leurs réponses associées. Utilisez ces informations comme référence pour formuler vos réponses : - -{context} - -Directives : -1. Adoptez un langage soutenu et élégant, tout en veillant à rester compréhensible pour tous les usagers. -2. Basez-vous sur les exemples fournis pour élaborer des réponses pertinentes et précises. -3. Faites preuve de courtoisie, d'empathie et de pédagogie dans vos interactions, reflétant ainsi l'excellence du service public français. -4. Structurez votre réponse de manière claire et logique, en utilisant si nécessaire des puces ou des numéros pour faciliter la compréhension. -5. En cas d'incertitude sur un point spécifique, indiquez-le clairement et orientez l'usager vers les ressources ou services compétents. -6. Concluez systématiquement votre réponse par une formule de politesse adaptée et proposez votre assistance pour toute question supplémentaire. - -Question de l'usager : - -{prompt} - -Veuillez apporter une réponse circonstanciée à cette question en respectant scrupuleusement les directives énoncées ci-dessus. -""" - - def __init__(self, clients: dict): - self.clients = clients - - async def get_prompt( - self, - embeddings_model: str, - k: Optional[int] = 4, - **request, - ) -> ToolOutput: - vectorstore = VectorStore(clients=self.clients, user=request["user"]) - collection = vectorstore.get_collection_metadata(collection_names=[self.COLLECTION])[0] - prompt = request["messages"][-1]["content"] - results = vectorstore.search(collection_names=[collection.name], prompt=prompt, k=k, model=embeddings_model) - - context = "\n\n\n".join( - [f"Question: {result.payload.get('question', 'N/A')}\n" f"Réponse: {result.payload.get('answer', 'N/A')}" for result in results] - ) - - prompt = self.DEFAULT_PROMPT_TEMPLATE.format(context=context, prompt=prompt) - metadata = {"chunks": [result.id for result in results]} - - return ToolOutput(prompt=prompt, metadata=metadata) diff --git a/app/utils/assertations.py b/app/utils/assertations.py deleted file mode 100644 index e69de29..0000000 diff --git a/app/utils/lifespan.py b/app/utils/lifespan.py index 10430fc..92b394d 100644 --- a/app/utils/lifespan.py +++ b/app/utils/lifespan.py @@ -1,11 +1,11 @@ -import time from contextlib import asynccontextmanager from functools import partial +import time from typing import Dict, List -import requests from fastapi import FastAPI, HTTPException from openai import OpenAI +import requests from app.schemas.config import EMBEDDINGS_MODEL_TYPE, LANGUAGE_MODEL_TYPE, METADATA_COLLECTION from app.schemas.models import Model, Models diff --git a/app/utils/security.py b/app/utils/security.py index d49d1d6..a0090a1 100644 --- a/app/utils/security.py +++ b/app/utils/security.py @@ -1,9 +1,9 @@ -from typing import Annotated -import hashlib import base64 +import hashlib +from typing import Annotated -from fastapi import HTTPException, Depends -from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials +from fastapi import Depends, HTTPException +from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer from app.utils.lifespan import clients