Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions backend/Notebook/test.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import os\n",
"from dotenv import load_dotenv\n",
"\n",
"load_dotenv()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import openai"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'https://api.openai.com/v1'"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"openai.api_base"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'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'"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"openai.api_key"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"In a magical forest, a brave little unicorn named Sparkle embarked on adventurous quests during the day and, as night fell, would sleep under a blanket of twinkling stars with her dreams filled with rainbows and shooting stars.\n"
]
}
],
"source": [
"import openai\n",
"\n",
"# openai.api_key = 'your-api-key'\n",
"\n",
"completion = openai.ChatCompletion.create(\n",
" model=\"gpt-4\", # Correct model name\n",
" messages=[\n",
" {\n",
" \"role\": \"user\",\n",
" \"content\": \"Write a one-sentence bedtime story about a unicorn.\"\n",
" }\n",
" ]\n",
")\n",
"\n",
"print(completion['choices'][0]['message']['content'])\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "dev",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.16"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
41 changes: 36 additions & 5 deletions backend/backend/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import os
from pathlib import Path

import pymysql
pymysql.install_as_MySQLdb()

from dotenv import load_dotenv

load_dotenv()
Expand All @@ -30,7 +33,7 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []
ALLOWED_HOSTS = ["*"]

# Application definition

Expand All @@ -47,6 +50,7 @@
"authentication",
"chat",
"gpt",
# "accounts",
]

MIDDLEWARE = [
Expand Down Expand Up @@ -84,10 +88,27 @@
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases

# "default": {
# "ENGINE": "django.db.backends.sqlite3",
# "NAME": BASE_DIR / "db.sqlite3",
# },
# "default": {
# "ENGINE": "django.db.backends.postgresql",
# "NAME": os.environ["POSTGRES_DB_NAME"],
# "USER": os.environ["POSTGRES_SQL_USER"],
# "PASSWORD": os.environ["POSTGRES_SQL_PASSWD"],
# "HOST": os.environ["POSTGRES_HOST"],
# "PORT": os.environ["POSTGRES_PORT"],
# },

DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
"ENGINE": "django.db.backends.mysql",
"NAME": os.environ["MYSQL_DB_NAME"],
"USER": os.environ["MYSQL_DB_USER"],
"PASSWORD": os.environ["MYSQL_DB_PASSWORD"],
"HOST": os.environ["MYSQL_DB_HOST"],
"PORT": os.environ["MYSQL_DB_PORT"],
}
}

Expand Down Expand Up @@ -138,14 +159,24 @@
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

CORS_ALLOWED_ORIGINS = [
FRONTEND_URL,
FRONTEND_URL, 'http://localhost:3000',
]
CORS_ALLOW_CREDENTIALS = True

CSRF_TRUSTED_ORIGINS = [
FRONTEND_URL,
FRONTEND_URL, 'http://localhost:3000',
]

SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = "None"

# Cron JOB
CRONJOBS = [
('0 0 * * *', 'django.core.management.call_command', 'cleanup_old_conversations'), # Run at midnight every day
]


#login url
# LOGIN_URL = '/admin/login/'

23 changes: 23 additions & 0 deletions backend/chat/management/commands/cleanup_old_conversations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.core.management.base import BaseCommand
from django.utils import timezone
from datetime import timedelta
from backend.chat.models import Conversation # Import your Conversation model

class Command(BaseCommand):
help = 'Clean up old conversations that haven\'t been modified in the last 6 months.'

def handle(self, *args, **kwargs):
# Define the cutoff date (6 months ago)
six_months_ago = timezone.now() - timedelta(days=6*30) # Approx 6 months

# Query conversations that haven't been modified since the cutoff date
old_conversations = Conversation.objects.filter(modified_at__lte=six_months_ago, deleted_at__isnull=True)

# If there are old conversations, delete them
if old_conversations.exists():
# You can choose to soft delete or hard delete. Here we are hard deleting.
old_conversations.delete()

self.stdout.write(self.style.SUCCESS(f'Successfully deleted {old_conversations.count()} old conversations.'))
else:
self.stdout.write(self.style.SUCCESS('No old conversations found to delete.'))
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.0.2 on 2025-03-13 11:10

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("chat", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="conversation",
name="is_pinned",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="conversation",
name="summary",
field=models.TextField(blank=True, default="", null=True),
),
]
16 changes: 16 additions & 0 deletions backend/chat/migrations/0003_remove_conversation_is_pinned.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 5.0.2 on 2025-03-13 12:00

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("chat", "0002_conversation_is_pinned_conversation_summary"),
]

operations = [
migrations.RemoveField(
model_name="conversation",
name="is_pinned",
),
]
4 changes: 4 additions & 0 deletions backend/chat/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ class Conversation(models.Model):
deleted_at = models.DateTimeField(null=True, blank=True)
user = models.ForeignKey(CustomUser, on_delete=models.CASCADE)


# New field for conversation summary
summary = models.TextField(null=True, blank=True, default="") # New summary field

def __str__(self):
return self.title

Expand Down
44 changes: 39 additions & 5 deletions backend/gpt/views.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,68 @@
from django.contrib.auth.decorators import login_required
# from django.contrib.auth.decorators import login_required
# from django.http import JsonResponse, StreamingHttpResponse
# from rest_framework.decorators import api_view

# from src.utils.gpt import get_conversation_answer, get_gpt_title, get_simple_answer


# @api_view(["GET"])
# def gpt_root_view(request):
# return JsonResponse({"message": "GPT endpoint works!"})


# @login_required
# @api_view(["POST"])
# def get_title(request):
# data = request.data
# title = get_gpt_title(data["user_question"], data["chatbot_response"])
# return JsonResponse({"content": title})


# @login_required
# @api_view(["POST"])
# def get_answer(request):
# data = request.data
# return StreamingHttpResponse(get_simple_answer(data["user_question"], stream=True), content_type="text/html")


# @login_required
# @api_view(["POST"])
# def get_conversation(request):
# data = request.data
# return StreamingHttpResponse(
# get_conversation_answer(data["conversation"], data["model"], stream=True), content_type="text/html"
# )



from django.http import JsonResponse, StreamingHttpResponse
from rest_framework.decorators import api_view

from src.utils.gpt import get_conversation_answer, get_gpt_title, get_simple_answer
from src.utils.gpt import get_conversation_answer, get_gpt_title, get_simple_answer, update_conversation_summary


@api_view(["GET"])
def gpt_root_view(request):
return JsonResponse({"message": "GPT endpoint works!"})


@login_required
@api_view(["POST"])
def get_title(request):
data = request.data
title = get_gpt_title(data["user_question"], data["chatbot_response"])
return JsonResponse({"content": title})


@login_required
@api_view(["POST"])
def get_answer(request):
data = request.data
return StreamingHttpResponse(get_simple_answer(data["user_question"], stream=True), content_type="text/html")


@login_required
@api_view(["POST"])
def get_conversation(request):
data = request.data
return StreamingHttpResponse(
get_conversation_answer(data["conversation"], data["model"], stream=True), content_type="text/html"
)

2 changes: 1 addition & 1 deletion backend/src/libs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@

openai.api_type = os.getenv("OPENAI_API_TYPE")
openai.api_base = os.getenv("OPENAI_API_BASE")
openai.api_version = os.getenv("OPENAI_API_VERSION")
openai.Model = os.getenv("OPENAI_API_MODEL")
openai.api_key = os.getenv("OPENAI_API_KEY")
Loading