File size: 9,262 Bytes
e5b884f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
import uuid
from typing import Dict, Optional
from datetime  import datetime, timedelta
from app.services.RAG_service import RAGService
from app.database.database import SessionDatabase
from app.schemas.request_models import DocumentTypeSchema

class Session:
    def __init__(self, session_id:str):
        self.session_id = session_id 
        self.created_at = datetime.now()
        self.last_activity = datetime.now()
        self.rag_service : Optional[RAGService] = None
        self.document_uploaded = False
        self.vector_store_created = False
        self.document_info = {}
        self.username = None

    def update_activity(self):
        self.last_activity = datetime.now()

    def is_expired(self, timeout_minutes: int = 60) -> bool:
        return datetime.now() - self.last_activity > timedelta(minutes=timeout_minutes)

class SessionManager:
    def __init__(self):
        self.sessions: Dict[str, Session] = {}
        self.db = SessionDatabase()

    def create_session(self, username: str = "anonymous") -> str:
        session_id  = str(uuid.uuid4())
        session = Session(session_id)
        session.username = username
        self.sessions[session_id] = session
        
        # Save to database
        self.db.create_session(session_id, username)
        return session_id
    
    def get_session(self, session_id: str) -> Optional[Session]:
        # First check in-memory sessions
        if session_id in self.sessions:
            session = self.sessions[session_id]
            if not session.is_expired():
                session.update_activity()
                return session
            else:
                del self.sessions[session_id]
        
        # If not in memory, try to restore from database
        db_session = self.db.get_session(session_id)
        if db_session and db_session['is_active']:
            # Restore session to memory
            session = Session(session_id)
            session.username = db_session['username']
            session.document_uploaded = db_session['chunks_count'] > 0
            session.vector_store_created = db_session['pinecone_index'] is not None
            session.document_info = {
                'filename': db_session['document_name'],
                'type': db_session['document_type'],
                'chunks_count': db_session['chunks_count']
            }
            
            # Initialize RAG service if document exists (same as restore_session)
            if session.vector_store_created:
                print(f"[SessionManager] Restoring RAG service for session {session_id}")
                session.rag_service = RAGService()
                
                # Set the basic attributes
                session.rag_service.index = db_session['pinecone_index']
                session.rag_service.namespace = db_session['pinecone_namespace']
                session.rag_service.Document_path = db_session['document_path']
                session.rag_service.url = db_session['document_url']
                
                # Create a mock splitter with the keywords file path for restored sessions
                from app.ingestion.text_splitter import splitting_text
                from app.utils.metadata_utils import MetadataService
                
                # Recreate the document type information
                metadataservice = MetadataService()
                mock_scheme = DocumentTypeSchema(document_types="Insurance")  # Default for restored sessions
                document_type = metadataservice.Return_document_model(mock_scheme)
                session.rag_service.DocumentTypeScheme = mock_scheme
                session.rag_service.Document_Type = document_type
                
                # Create splitter instance to maintain the keywords file path
                session.rag_service.splitter = splitting_text(documentTypeSchema=document_type, llm=session.rag_service.llm)
                
                # Generate the expected keywords file path based on document name
                import os
                document_name = db_session['document_name'] or 'unknown'
                keywords_filename = document_name.replace(".", "").replace("\\", "").replace("/", "") + ".json"
                session.rag_service.splitter.Keywordsfile_path = os.path.join("app/data/", keywords_filename)
                
                print(f"[SessionManager] RAG service restored with index: {session.rag_service.index}")
            
            self.sessions[session_id] = session
            return session
        
        return None
    
    def update_session_document(self, session_id: str, document_name: str, 
                               document_type: str, chunks_count: int,
                               pinecone_index: str = None, pinecone_namespace: str = None,
                               document_path: str = None, document_url: str = None):
        """Update session with document information"""
        self.db.update_session(
            session_id,
            document_name=document_name,
            document_type=document_type,
            chunks_count=chunks_count,
            pinecone_index=pinecone_index,
            pinecone_namespace=pinecone_namespace,
            document_path=document_path,
            document_url=document_url
        )
        
        # Update in-memory session if exists
        if session_id in self.sessions:
            session = self.sessions[session_id]
            session.document_uploaded = True
            session.vector_store_created = pinecone_index is not None
            session.document_info = {
                'filename': document_name,
                'type': document_type,
                'chunks_count': chunks_count
            }
    
    def get_user_sessions(self, username: str):
        """Get all sessions for a user"""
        return self.db.get_user_sessions(username)
    
    def restore_session(self, session_id: str) -> bool:
        """Restore a session from database"""
        db_session = self.db.get_session(session_id)
        if db_session and db_session['is_active']:
            session = Session(session_id)
            session.username = db_session['username']
            session.document_uploaded = db_session['chunks_count'] > 0
            session.vector_store_created = db_session['pinecone_index'] is not None
            session.document_info = {
                'filename': db_session['document_name'],
                'type': db_session['document_type'],
                'chunks_count': db_session['chunks_count']
            }
            
            # Initialize RAG service if document exists
            if session.vector_store_created:
                print(f"[SessionManager] Restoring RAG service for session {session_id}")
                session.rag_service = RAGService()
                
                # Set the basic attributes
                session.rag_service.index = db_session['pinecone_index']
                session.rag_service.namespace = db_session['pinecone_namespace']
                session.rag_service.Document_path = db_session['document_path']
                session.rag_service.url = db_session['document_url']
                
                # Create a mock splitter with the keywords file path for restored sessions
                from app.ingestion.text_splitter import splitting_text
                from app.utils.metadata_utils import MetadataService
                
                # Recreate the document type information
                metadataservice = MetadataService()
                mock_scheme = DocumentTypeSchema(document_types="Insurance")  # Default for restored sessions
                document_type = metadataservice.Return_document_model(mock_scheme)
                session.rag_service.DocumentTypeScheme = mock_scheme
                session.rag_service.Document_Type = document_type
                
                # Create splitter instance to maintain the keywords file path
                session.rag_service.splitter = splitting_text(documentTypeSchema=document_type, llm=session.rag_service.llm)
                
                # Generate the expected keywords file path based on document name
                import os
                document_name = db_session['document_name'] or 'unknown'
                keywords_filename = document_name.replace(".", "").replace("\\", "").replace("/", "") + ".json"
                session.rag_service.splitter.Keywordsfile_path = os.path.join("app/data/", keywords_filename)
                
                print(f"[SessionManager] RAG service restored with index: {session.rag_service.index}")
            
            self.sessions[session_id] = session
            return True
        return False
    
    def delete_session(self, session_id:str): 
        if session_id in self.sessions:
            del self.sessions[session_id]
        self.db.deactivate_session(session_id)
    
    def cleanup_expired_sessions(self): 
        expired_sessions = [
            sid for sid, session in self.sessions.items()
            if session.is_expired()
        ]
        for sid in expired_sessions:
            del self.sessions[sid]

session_manager = SessionManager()