Setting up the chat client functionality using SocketIO - Start
This commit is contained in:
@@ -5,6 +5,7 @@ from flask_security import Security
|
||||
from flask_mailman import Mail
|
||||
from flask_login import LoginManager
|
||||
from flask_cors import CORS
|
||||
from flask_socketio import SocketIO
|
||||
|
||||
|
||||
# Create extensions
|
||||
@@ -15,3 +16,4 @@ security = Security()
|
||||
mail = Mail()
|
||||
login_manager = LoginManager()
|
||||
cors = CORS()
|
||||
socketio = SocketIO()
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
from ..extensions import db
|
||||
from .user import User, Tenant
|
||||
|
||||
|
||||
class ChatSession(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('public.user.id'), nullable=True)
|
||||
session_start = db.Column(db.DateTime, nullable=False)
|
||||
session_end = db.Column(db.DateTime, nullable=True)
|
||||
|
||||
# Relations
|
||||
chat_interactions = db.relationship('Interaction', backref='chat_session', lazy=True)
|
||||
user = db.relationship('User', backref='chat_sessions', lazy=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<ChatSession {self.id} by {self.user_id}>"
|
||||
|
||||
|
||||
class Interaction(db.Model):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
chat_session_id = db.Column(db.Integer, db.ForeignKey('public.chat_session.id'), nullable=False)
|
||||
question = db.Column(db.Text, nullable=False)
|
||||
answer = db.Column(db.Text, nullable=True)
|
||||
language = db.Column(db.String(2), nullable=False)
|
||||
appreciation = db.Column(db.Integer, nullable=True, default=100)
|
||||
|
||||
# Timing information
|
||||
question_at = db.Column(db.DateTime, nullable=False)
|
||||
answer_at = db.Column(db.DateTime, nullable=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<Interaction {self.id}>"
|
||||
|
||||
|
||||
class InteractionEmbedding(db.Model):
|
||||
interaction_id = db.Column(db.Integer, db.ForeignKey('interaction.id', ondelete='CASCADE'), primary_key=True)
|
||||
embedding_id = db.Column(db.Integer, db.ForeignKey('embedding.id', ondelete='CASCADE'), primary_key=True)
|
||||
|
||||
@@ -63,6 +63,9 @@ class Config(object):
|
||||
Text is delimited between triple backquotes.
|
||||
```{text}```"""
|
||||
|
||||
# SocketIO settings
|
||||
SOCKETIO_ASYNC_MODE = 'gevent'
|
||||
|
||||
|
||||
class DevConfig(Config):
|
||||
DEVELOPMENT = True
|
||||
@@ -92,6 +95,17 @@ class DevConfig(Config):
|
||||
UNSTRUCTURED_BASE_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io'
|
||||
UNSTRUCTURED_FULL_URL = 'https://flowitbv-16c4us0m.api.unstructuredapp.io/general/v0/general'
|
||||
|
||||
# SocketIO settings
|
||||
SOCKETIO_MESSAGE_QUEUE = 'redis://localhost:6379/1'
|
||||
SOCKETIO_CORS_ALLOWED_ORIGINS = '*'
|
||||
SOCKETIO_LOGGER = True
|
||||
SOCKETIO_ENGINEIO_LOGGER = True
|
||||
|
||||
# Google Cloud settings
|
||||
GC_PROJECT_NAME = 'EveAI'
|
||||
GC_KEY_RING = 'eveai-chat'
|
||||
GC_CRYPTO_KEY = 'envelope-encryption-key'
|
||||
|
||||
|
||||
class ProdConfig(Config):
|
||||
DEVELOPMENT = False
|
||||
|
||||
@@ -18,6 +18,14 @@ LOGGING = {
|
||||
'backupCount': 10,
|
||||
'formatter': 'standard',
|
||||
},
|
||||
'file_chat': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.handlers.RotatingFileHandler',
|
||||
'filename': 'logs/eveai_chat.log',
|
||||
'maxBytes': 1024*1024*5, # 5MB
|
||||
'backupCount': 10,
|
||||
'formatter': 'standard',
|
||||
},
|
||||
'console': {
|
||||
'class': 'logging.StreamHandler',
|
||||
'level': 'DEBUG',
|
||||
@@ -40,6 +48,11 @@ LOGGING = {
|
||||
'level': 'DEBUG',
|
||||
'propagate': False
|
||||
},
|
||||
'eveai_chat': { # logger for the eveai_chat
|
||||
'handlers': ['file_chat', 'console'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False
|
||||
},
|
||||
'': { # root logger
|
||||
'handlers': ['console'],
|
||||
'level': 'WARNING', # Set higher level for root to minimize noise
|
||||
|
||||
@@ -7,7 +7,7 @@ from werkzeug.middleware.proxy_fix import ProxyFix
|
||||
import logging.config
|
||||
|
||||
from common.extensions import db, migrate, bootstrap, security, mail, login_manager, cors
|
||||
from common.models.user import User, Role
|
||||
from common.models.user import User, Role, Tenant, TenantDomain
|
||||
from config.logging_config import LOGGING
|
||||
from common.utils.security import set_tenant_session_data
|
||||
from .errors import register_error_handlers
|
||||
|
||||
33
eveai_chat/__init__.py
Normal file
33
eveai_chat/__init__.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import logging
|
||||
import logging.config
|
||||
from flask import Flask
|
||||
from flask_socketio import emit
|
||||
|
||||
from common.extensions import db, socketio
|
||||
from config.logging_config import LOGGING
|
||||
|
||||
|
||||
def create_app(config_file=None):
|
||||
app = Flask(__name__)
|
||||
|
||||
if config_file is None:
|
||||
app.config.from_object('config.config.DevConfig')
|
||||
else:
|
||||
app.config.from_object(config_file)
|
||||
|
||||
logging.config.dictConfig(LOGGING)
|
||||
register_extensions(app)
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def register_extensions(app):
|
||||
db.init_app(app)
|
||||
socketio.init_app(app,
|
||||
message_queue=app.config.get('SOCKETIO_MESSAGE_QUEUE'),
|
||||
cors_allowed_origins=app.config.get('SOCKETIO_CORS_ALLOWED_ORIGINS'),
|
||||
async_mode=app.config.get('SOCKETIO_ASYNC_MODE'),
|
||||
logger=app.config.get('SOCKETIO_LOGGER'),
|
||||
engineio_logger=app.config.get('SOCKETIO_ENGINEIO_LOGGER'),
|
||||
)
|
||||
|
||||
34
eveai_chat/views/chat_views.py
Normal file
34
eveai_chat/views/chat_views.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# from . import user_bp
|
||||
import uuid
|
||||
from datetime import datetime as dt, timezone as tz
|
||||
from flask import request, redirect, url_for, flash, render_template, Blueprint, session, current_app
|
||||
from flask_security import hash_password, roles_required, roles_accepted
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from common.models.user import User, Tenant
|
||||
from common.models.interaction import ChatSession, Interaction, InteractionEmbedding
|
||||
from common.models.document import Embedding
|
||||
from common.extensions import db, socketio
|
||||
from common.utils.database import Database
|
||||
|
||||
chat_bp = Blueprint('chat_bp', __name__, url_prefix='/chat')
|
||||
|
||||
|
||||
@chat_bp.route('/', methods=['GET', 'POST'])
|
||||
def chat():
|
||||
return render_template('chat.html')
|
||||
|
||||
|
||||
@chat.record_once
|
||||
def on_register(state):
|
||||
# TODO: write initialisation code when the blueprint is registered (only once)
|
||||
# socketio.init_app(state.app)
|
||||
pass
|
||||
|
||||
|
||||
@socketio.on('message', namespace='/chat')
|
||||
def handle_message(message):
|
||||
# TODO: write message handling code to actually realise chat
|
||||
# print('Received message:', message)
|
||||
# socketio.emit('response', {'data': message}, namespace='/chat')
|
||||
pass
|
||||
@@ -9,4 +9,5 @@ celery~=5.4.0
|
||||
kombu~=5.3.7
|
||||
langchain~=0.1.17
|
||||
requests~=2.31.0
|
||||
beautifulsoup4~=4.12.3
|
||||
beautifulsoup4~=4.12.3
|
||||
google~=3.0.0
|
||||
14
scripts/run_eveai_chat.py
Normal file
14
scripts/run_eveai_chat.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from eveai_chat import create_app
|
||||
from gevent.pywsgi import WSGIServer
|
||||
from geventwebsocket.handler import WebSocketHandler
|
||||
|
||||
|
||||
app = create_app()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print("Server starting on port 5001")
|
||||
http_server = WSGIServer(('0.0.0.0', 5001), app, handler_class=WebSocketHandler)
|
||||
http_server.serve_forever() # Continuously listens for incoming requests
|
||||
|
||||
|
||||
|
||||
15
scripts/start_eveai_chat.sh
Executable file
15
scripts/start_eveai_chat.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
cd "/Volumes/OWC4M2_1/Dropbox/Josako's Dev/Josako/EveAI/Development/eveAI/" || exit 1
|
||||
source "/Volumes/OWC4M2_1/Dropbox/Josako's Dev/Josako/EveAI/Development/eveAI/.venv/bin/activate"
|
||||
|
||||
export PYTHONPATH="$PYTHONPATH:/Volumes/OWC4M2_1/Dropbox/Josako's Dev/Josako/EveAI/Development/eveAI/"
|
||||
|
||||
# Set flask environment variables
|
||||
export FLASK_ENV=development # Use 'production' as appropriate
|
||||
export FLASK_DEBUG=1 # Use 0 for production
|
||||
|
||||
# Start Flask app
|
||||
python scripts/run_eveai_chat.py
|
||||
|
||||
deactivate
|
||||
Reference in New Issue
Block a user