mirror of
https://github.com/StanGirard/quivr.git
synced 2024-12-23 19:32:30 +03:00
fix: 🐛 tests (#2095)
backend test fixed # Description Please include a summary of the changes and the related issue. Please also include relevant motivation and context. ## Checklist before requesting a review Please delete options that are not relevant. - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented hard-to-understand areas - [ ] I have ideally added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged ## Screenshots (if appropriate):
This commit is contained in:
parent
2baa405991
commit
43d4f9155f
1
.gitignore
vendored
1
.gitignore
vendored
@ -75,3 +75,4 @@ volumes/storage/stub/stub/quivr/*
|
|||||||
supabase/migrations/20240103191539_private.sql
|
supabase/migrations/20240103191539_private.sql
|
||||||
supabase/20240103191539_private.sql
|
supabase/20240103191539_private.sql
|
||||||
paulgraham.py
|
paulgraham.py
|
||||||
|
.env_test
|
||||||
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -12,7 +12,7 @@
|
|||||||
],
|
],
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"[python]": {
|
"[python]": {
|
||||||
"editor.defaultFormatter": "ms-python.black-formatter",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.organizeImports": "explicit",
|
"source.organizeImports": "explicit",
|
||||||
@ -54,4 +54,5 @@
|
|||||||
],
|
],
|
||||||
"python.testing.unittestEnabled": false,
|
"python.testing.unittestEnabled": false,
|
||||||
"python.testing.pytestEnabled": true,
|
"python.testing.pytestEnabled": true,
|
||||||
|
"python.envFile": "${workspaceFolder}/.env_test",
|
||||||
}
|
}
|
50
Pipfile
Normal file
50
Pipfile
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
[[source]]
|
||||||
|
url = "https://pypi.org/simple"
|
||||||
|
verify_ssl = true
|
||||||
|
name = "pypi"
|
||||||
|
|
||||||
|
[packages]
|
||||||
|
langchain = "==0.0.341"
|
||||||
|
litellm = "==1.7.7"
|
||||||
|
openai = "==1.1.1"
|
||||||
|
gitpython = "==3.1.36"
|
||||||
|
pdf2image = "==1.16.3"
|
||||||
|
nest-asyncio = "==1.5.6"
|
||||||
|
pypdf = "==3.9.0"
|
||||||
|
supabase = "==1.1.0"
|
||||||
|
tiktoken = "==0.4.0"
|
||||||
|
unstructured = "==0.6.7"
|
||||||
|
fastapi = "==0.95.2"
|
||||||
|
python-multipart = "==0.0.6"
|
||||||
|
uvicorn = "==0.22.0"
|
||||||
|
pypandoc = "==1.11"
|
||||||
|
docx2txt = "==0.8"
|
||||||
|
python-jose = "==3.3.0"
|
||||||
|
asyncpg = "==0.27.0"
|
||||||
|
flake8 = "==6.0.0"
|
||||||
|
flake8-black = "==0.3.6"
|
||||||
|
sentry-sdk = {extras = ["fastapi"], version = "==1.37.1"}
|
||||||
|
pyright = "==1.1.316"
|
||||||
|
resend = "==0.5.1"
|
||||||
|
html5lib = "==1.1"
|
||||||
|
beautifulsoup4 = "*"
|
||||||
|
newspaper3k = "*"
|
||||||
|
xlrd = "==1.0.0"
|
||||||
|
redis = "==4.5.4"
|
||||||
|
flower = "*"
|
||||||
|
boto3 = "==1.33.7"
|
||||||
|
botocore = "==1.33.7"
|
||||||
|
celery = {extras = ["sqs"], version = "*"}
|
||||||
|
python-dotenv = "*"
|
||||||
|
pytest-mock = "*"
|
||||||
|
pytest-celery = "*"
|
||||||
|
pytesseract = "==0.3.10"
|
||||||
|
async-generator = "*"
|
||||||
|
posthog = "==3.1.0"
|
||||||
|
jq = "==1.6.0"
|
||||||
|
pytest = "*"
|
||||||
|
|
||||||
|
[dev-packages]
|
||||||
|
|
||||||
|
[requires]
|
||||||
|
python_version = "3.11"
|
2713
Pipfile.lock
generated
Normal file
2713
Pipfile.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import socket
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
@ -7,8 +8,18 @@ from fastapi.testclient import TestClient
|
|||||||
|
|
||||||
@pytest.fixture(scope="session", autouse=True)
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
def load_env():
|
def load_env():
|
||||||
load_dotenv()
|
load_dotenv(".env_test", verbose=True, override=True)
|
||||||
print("SUPABASE_URL:", os.getenv("SUPABASE_URL")) # For debugging
|
|
||||||
|
# Testing socket connection
|
||||||
|
host, port = "localhost", 54321
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
try:
|
||||||
|
s.connect((host, port))
|
||||||
|
print(f"Connection to {host} on port {port} succeeded.")
|
||||||
|
except socket.error as e:
|
||||||
|
print(f"Connection to {host} on port {port} failed: {e}")
|
||||||
|
|
||||||
|
print("Loaded SUPABASE_URL:", os.getenv("SUPABASE_URL"))
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session", autouse=True)
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
@ -27,14 +38,16 @@ def verify_env_variables():
|
|||||||
pytest.fail(f"Required environment variables are missing: {missing_vars_str}")
|
pytest.fail(f"Required environment variables are missing: {missing_vars_str}")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="session")
|
||||||
def client():
|
def client():
|
||||||
from main import app
|
from main import app
|
||||||
|
|
||||||
|
print("CLIENT_SUPABASE_URL:", os.getenv("SUPABASE_URL")) # For debugging
|
||||||
|
|
||||||
return TestClient(app)
|
return TestClient(app)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
@pytest.fixture(scope="session")
|
||||||
def api_key():
|
def api_key():
|
||||||
API_KEY = os.getenv("CI_TEST_API_KEY")
|
API_KEY = os.getenv("CI_TEST_API_KEY")
|
||||||
if not API_KEY:
|
if not API_KEY:
|
||||||
|
@ -59,10 +59,10 @@ def test_api_key_model():
|
|||||||
assert api_key.api_key == "1234567890"
|
assert api_key.api_key == "1234567890"
|
||||||
assert api_key.key_id == "abcd1234"
|
assert api_key.key_id == "abcd1234"
|
||||||
assert api_key.days == 7
|
assert api_key.days == 7
|
||||||
assert api_key.only_chat == False
|
assert api_key.only_chat is False
|
||||||
assert api_key.name == "Test API Key"
|
assert api_key.name == "Test API Key"
|
||||||
assert api_key.creation_time == "2022-01-01T00:00:00Z"
|
assert api_key.creation_time == "2022-01-01T00:00:00Z"
|
||||||
assert api_key.is_active == True
|
assert api_key.is_active is True
|
||||||
|
|
||||||
|
|
||||||
def test_get_user_from_api_key(client, api_key):
|
def test_get_user_from_api_key(client, api_key):
|
||||||
|
@ -33,7 +33,7 @@ def test_create_brain(client, api_key):
|
|||||||
"status": "public",
|
"status": "public",
|
||||||
"model": "gpt-3.5-turbo-1106",
|
"model": "gpt-3.5-turbo-1106",
|
||||||
"temperature": 0,
|
"temperature": 0,
|
||||||
"max_tokens": 256,
|
"max_tokens": 2000,
|
||||||
"brain_type": "doc",
|
"brain_type": "doc",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,43 +79,6 @@ def test_create_chat_and_talk(client, api_key):
|
|||||||
assert delete_response.status_code == 200
|
assert delete_response.status_code == 200
|
||||||
|
|
||||||
|
|
||||||
def test_create_chat_and_talk_with_no_brain(client, api_key):
|
|
||||||
# Make a POST request to chat with no brain id and a random chat name
|
|
||||||
random_chat_name = "".join(
|
|
||||||
random.choices(string.ascii_letters + string.digits, k=10)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Create a chat
|
|
||||||
response = client.post(
|
|
||||||
"/chat",
|
|
||||||
json={"name": random_chat_name},
|
|
||||||
headers={"Authorization": "Bearer " + api_key},
|
|
||||||
)
|
|
||||||
assert response.status_code == 200
|
|
||||||
|
|
||||||
# now talk to the chat with a question
|
|
||||||
response_data = response.json()
|
|
||||||
print(response_data)
|
|
||||||
chat_id = response_data["chat_id"]
|
|
||||||
response = client.post(
|
|
||||||
f"/chat/{chat_id}/question?brain_id=",
|
|
||||||
json={
|
|
||||||
"model": "gpt-3.5-turbo-1106",
|
|
||||||
"question": "Hello, how are you?",
|
|
||||||
"temperature": "0",
|
|
||||||
"max_tokens": "256",
|
|
||||||
},
|
|
||||||
headers={"Authorization": "Bearer " + api_key},
|
|
||||||
)
|
|
||||||
assert response.status_code == 200
|
|
||||||
|
|
||||||
# Now, let's delete the chat
|
|
||||||
delete_response = client.delete(
|
|
||||||
"/chat/" + chat_id, headers={"Authorization": "Bearer " + api_key}
|
|
||||||
)
|
|
||||||
assert delete_response.status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
# Test delete all chats for a user
|
# Test delete all chats for a user
|
||||||
def test_delete_all_chats(client, api_key):
|
def test_delete_all_chats(client, api_key):
|
||||||
chats = client.get("/chat", headers={"Authorization": "Bearer " + api_key})
|
chats = client.get("/chat", headers={"Authorization": "Bearer " + api_key})
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
TELEGRAM_BOT_TOKEN=XXXX
|
|
||||||
QUIVR_TOKEN=XXXX
|
|
||||||
QUIVR_CHAT_ID=1XXXX
|
|
||||||
QUIVR_BRAIN_ID=XXXX
|
|
||||||
QUIVR_URL=XXXX
|
|
@ -1,73 +0,0 @@
|
|||||||
import logging
|
|
||||||
import os
|
|
||||||
|
|
||||||
import requests
|
|
||||||
from dotenv import load_dotenv
|
|
||||||
from telegram import Update
|
|
||||||
from telegram.ext import (
|
|
||||||
ApplicationBuilder,
|
|
||||||
CommandHandler,
|
|
||||||
ContextTypes,
|
|
||||||
MessageHandler,
|
|
||||||
filters,
|
|
||||||
)
|
|
||||||
|
|
||||||
load_dotenv() # Load variables from .env file
|
|
||||||
|
|
||||||
logging.basicConfig(
|
|
||||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
|
|
||||||
)
|
|
||||||
|
|
||||||
telegram_bot_token = os.getenv("TELEGRAM_BOT_TOKEN", "")
|
|
||||||
quivr_token = os.getenv("QUIVR_TOKEN", "")
|
|
||||||
quivr_chat_id = os.getenv("QUIVR_CHAT_ID", "")
|
|
||||||
quivr_brain_id = os.getenv("QUIVR_BRAIN_ID", "")
|
|
||||||
quivr_url = (
|
|
||||||
os.getenv("QUIVR_URL", "https://api.quivr.app")
|
|
||||||
+ f"/chat/{quivr_chat_id}/question?brain_id={quivr_brain_id}"
|
|
||||||
)
|
|
||||||
|
|
||||||
headers = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Authorization": "Bearer " + quivr_token,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
||||||
await context.bot.send_message(
|
|
||||||
chat_id=update.effective_chat.id,
|
|
||||||
text="I'm Quiv's bot and can answer any question. Please ask your question.",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
|
||||||
user_message = update.message.text
|
|
||||||
response = requests.post(
|
|
||||||
quivr_url, headers=headers, json={"question": user_message}
|
|
||||||
)
|
|
||||||
if response.status_code == 200:
|
|
||||||
quivr_response = response.json().get(
|
|
||||||
"assistant", "Sorry, I couldn't understand that."
|
|
||||||
)
|
|
||||||
await context.bot.send_message(
|
|
||||||
chat_id=update.effective_chat.id, text=quivr_response
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# Log or print the response for debugging
|
|
||||||
print(f"Error: {response.status_code}, {response.text}")
|
|
||||||
await context.bot.send_message(
|
|
||||||
chat_id=update.effective_chat.id,
|
|
||||||
text=f"Sorry, there was an error processing your request. {response.text}",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
application = ApplicationBuilder().token(telegram_bot_token).build()
|
|
||||||
|
|
||||||
start_handler = CommandHandler("start", start)
|
|
||||||
message_handler = MessageHandler(filters.TEXT & (~filters.COMMAND), handle_message)
|
|
||||||
|
|
||||||
application.add_handler(start_handler)
|
|
||||||
application.add_handler(message_handler)
|
|
||||||
|
|
||||||
application.run_polling()
|
|
Loading…
Reference in New Issue
Block a user