Rulga commited on
Commit
5193d26
·
1 Parent(s): 3baaca6

del streamlit

Browse files
Files changed (2) hide show
  1. app.py +103 -195
  2. requirements.txt +0 -6
app.py CHANGED
@@ -1,6 +1,5 @@
1
  import os
2
  import time
3
- import streamlit as st
4
  from dotenv import load_dotenv
5
  from langchain_groq import ChatGroq
6
  from langchain_huggingface import HuggingFaceEmbeddings
@@ -12,54 +11,17 @@ from langchain_core.output_parsers import StrOutputParser
12
  from datetime import datetime
13
  import json
14
  import traceback
 
 
15
 
16
  # Initialize environment variables
17
  load_dotenv()
18
 
19
- # --------------- Session State Initialization ---------------
20
- def init_session_state():
21
- """Initialize all required session state variables"""
22
- defaults = {
23
- 'kb_info': {
24
- 'build_time': None,
25
- 'size': None,
26
- 'version': '1.1'
27
- },
28
- 'messages': [],
29
- 'vector_store': None,
30
- 'models_initialized': False
31
- }
32
-
33
- for key, value in defaults.items():
34
- if key not in st.session_state:
35
- st.session_state[key] = value
36
-
37
- # --------------- Enhanced Logging ---------------
38
- def log_interaction(user_input: str, bot_response: str, context: str):
39
- """Log interactions with error handling"""
40
- try:
41
- log_entry = {
42
- "timestamp": datetime.now().isoformat(),
43
- "user_input": user_input,
44
- "bot_response": bot_response,
45
- "context": context[:500], # Store first 500 chars of context
46
- "kb_version": st.session_state.kb_info['version']
47
- }
48
-
49
- os.makedirs("chat_history", exist_ok=True)
50
- log_path = os.path.join("chat_history", "chat_logs.json")
51
-
52
- with open(log_path, "a", encoding="utf-8") as f:
53
- f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")
54
-
55
- except Exception as e:
56
- st.error(f"Logging error: {str(e)}")
57
- print(traceback.format_exc())
58
 
59
  # --------------- Model Initialization ---------------
60
- @st.cache_resource
61
  def init_models():
62
- """Initialize AI models with caching"""
63
  try:
64
  llm = ChatGroq(
65
  model_name="llama-3.3-70b-versatile",
@@ -69,11 +31,9 @@ def init_models():
69
  embeddings = HuggingFaceEmbeddings(
70
  model_name="intfloat/multilingual-e5-large-instruct"
71
  )
72
- st.session_state.models_initialized = True
73
  return llm, embeddings
74
  except Exception as e:
75
- st.error(f"Model initialization failed: {str(e)}")
76
- st.stop()
77
 
78
  # --------------- Knowledge Base Management ---------------
79
  VECTOR_STORE_PATH = "vector_store"
@@ -99,168 +59,116 @@ def build_knowledge_base(_embeddings):
99
  start_time = time.time()
100
  documents = []
101
 
102
- with st.status("Building knowledge base..."):
103
- # Создаем папку заранее
104
- os.makedirs(VECTOR_STORE_PATH, exist_ok=True)
105
-
106
- # Загрузка документов
107
- for url in URLS:
108
- try:
109
- loader = WebBaseLoader(url)
110
- docs = loader.load()
111
- documents.extend(docs)
112
- st.write(f"✓ Loaded {url}")
113
- except Exception as e:
114
- st.error(f"Failed to load {url}: {str(e)}")
115
- continue # Продолжаем при ошибках загрузки
116
 
117
- if not documents:
118
- st.error("No documents loaded!")
119
- return None
120
 
121
- # Разделение на чанки
122
- text_splitter = RecursiveCharacterTextSplitter(
123
- chunk_size=500,
124
- chunk_overlap=100
125
- )
126
- chunks = text_splitter.split_documents(documents)
127
-
128
- # Явное сохранение
129
- vector_store = FAISS.from_documents(chunks, _embeddings)
130
- vector_store.save_local(
131
- folder_path=VECTOR_STORE_PATH,
132
- index_name="index"
133
- )
134
-
135
- # Проверка создания файлов
136
- if not os.path.exists(os.path.join(VECTOR_STORE_PATH, "index.faiss")):
137
- raise RuntimeError("FAISS index file not created!")
138
-
139
- # Обновление информации
140
- st.session_state.kb_info.update({
141
- 'build_time': time.time() - start_time,
142
- 'size': sum(
143
- os.path.getsize(os.path.join(VECTOR_STORE_PATH, f))
144
- for f in ["index.faiss", "index.pkl"]
145
- ) / (1024 ** 2),
146
- 'version': datetime.now().strftime("%Y%m%d-%H%M%S")
147
- })
148
 
149
- st.success("Knowledge base successfully created!")
150
- return vector_store
151
 
152
  except Exception as e:
153
- st.error(f"Knowledge base creation failed: {str(e)}")
154
- # Отладочная информация
155
- st.write("Debug info:")
156
- st.write(f"Documents loaded: {len(documents)}")
157
- st.write(f"Chunks created: {len(chunks) if 'chunks' in locals() else 0}")
158
- st.write(f"Vector store path exists: {os.path.exists(VECTOR_STORE_PATH)}")
159
- st.stop()
160
- # --------------- Main Application ---------------
161
- def main():
162
- # Initialize session state first
163
- init_session_state()
164
-
165
- # Page configuration
166
- st.set_page_config(
167
- page_title="Status Law Assistant",
168
- page_icon="⚖️",
169
- layout="wide"
170
- )
171
-
172
- # Display header
173
- st.markdown('''
174
- <h1 style="border-bottom: 2px solid #444; padding-bottom: 10px;">
175
- ⚖️ <a href="https://status.law/" style="text-decoration: none; color: #2B5876;">Status.Law</a> Legal Assistant
176
- </h1>
177
- ''', unsafe_allow_html=True)
178
 
179
- # Initialize models
180
- llm, embeddings = init_models()
181
-
182
- # Knowledge base initialization
183
- if not os.path.exists(VECTOR_STORE_PATH):
184
- st.warning("Knowledge base not initialized")
185
- if st.button("Create Knowledge Base"):
186
- st.session_state.vector_store = build_knowledge_base(embeddings)
187
- st.rerun()
188
- return
189
-
190
- if not st.session_state.vector_store:
191
- try:
192
- st.session_state.vector_store = FAISS.load_local(
193
  VECTOR_STORE_PATH,
194
  embeddings,
195
  allow_dangerous_deserialization=True
196
  )
197
- except Exception as e:
198
- st.error(f"Failed to load knowledge base: {str(e)}")
199
- st.stop()
200
-
201
- # Chat interface
202
- for message in st.session_state.messages:
203
- with st.chat_message(message["role"]):
204
- st.markdown(message["content"])
205
-
206
- if prompt := st.chat_input("Ask your legal question"):
207
- # Add user message to chat history
208
- st.session_state.messages.append({"role": "user", "content": prompt})
209
- with st.chat_message("user"):
210
- st.markdown(prompt)
211
-
212
- # Generate response
213
- with st.chat_message("assistant"):
214
- try:
215
- # Retrieve context
216
- context_docs = st.session_state.vector_store.similarity_search(prompt)
217
- context_text = "\n".join([d.page_content for d in context_docs])
218
-
219
- # Generate response
220
- prompt_template = PromptTemplate.from_template('''
221
- You are a helpful and polite legal assistant at Status Law.
222
- You answer in the language in which the question was asked.
223
- Answer the question based on the context provided.
224
- If you cannot answer based on the context, say so politely and offer to contact Status Law directly via the following channels:
225
- - For all users: +32465594521 (landline phone).
226
- - For English and Swedish speakers only: +46728495129 (available on WhatsApp, Telegram, Signal, IMO).
227
- - Provide a link to the contact form: [Contact Form](https://status.law/law-firm-contact-legal-protection/).
228
- If the user has questions about specific services and their costs, suggest they visit the page https://status.law/tariffs-for-services-of-protection-against-extradition-and-international-prosecution/ for detailed information.
229
-
230
- Ask the user additional questions to understand which service to recommend and provide an estimated cost. For example, clarify their situation and needs to suggest the most appropriate options.
231
 
232
- Also, offer free consultations if they are available and suitable for the user's request.
233
- Answer professionally but in a friendly manner.
 
 
 
 
 
 
 
234
 
235
- Example:
236
- Q: How can I challenge the sanctions?
237
- A: To challenge the sanctions, you should consult with our legal team, who specialize in this area. Please contact us directly for detailed advice. You can fill out our contact form here: [Contact Form](https://status.law/law-firm-contact-legal-protection/).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
 
239
- Context: {context}
240
- Question: {question}
241
-
242
- Response Guidelines:
243
- 1. Answer in the user's language
244
- 2. Cite sources when possible
245
- 3. Offer contact options if unsure
246
- ''')
247
-
248
- chain = prompt_template | llm | StrOutputParser()
249
- response = chain.invoke({
250
- "context": context_text,
251
- "question": prompt
252
- })
253
-
254
- # Display and log
255
- st.markdown(response)
256
- log_interaction(prompt, response, context_text)
257
- st.session_state.messages.append({"role": "assistant", "content": response})
258
-
259
- except Exception as e:
260
- error_msg = f"Error generating response: {str(e)}"
261
- st.error(error_msg)
262
- log_interaction(prompt, error_msg, "")
263
- print(traceback.format_exc())
264
 
265
  if __name__ == "__main__":
266
- main()
 
 
1
  import os
2
  import time
 
3
  from dotenv import load_dotenv
4
  from langchain_groq import ChatGroq
5
  from langchain_huggingface import HuggingFaceEmbeddings
 
11
  from datetime import datetime
12
  import json
13
  import traceback
14
+ from fastapi import FastAPI, HTTPException
15
+ from pydantic import BaseModel
16
 
17
  # Initialize environment variables
18
  load_dotenv()
19
 
20
+ app = FastAPI(title="Status Law Assistant API")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
  # --------------- Model Initialization ---------------
 
23
  def init_models():
24
+ """Initialize AI models"""
25
  try:
26
  llm = ChatGroq(
27
  model_name="llama-3.3-70b-versatile",
 
31
  embeddings = HuggingFaceEmbeddings(
32
  model_name="intfloat/multilingual-e5-large-instruct"
33
  )
 
34
  return llm, embeddings
35
  except Exception as e:
36
+ raise HTTPException(status_code=500, detail=f"Model initialization failed: {str(e)}")
 
37
 
38
  # --------------- Knowledge Base Management ---------------
39
  VECTOR_STORE_PATH = "vector_store"
 
59
  start_time = time.time()
60
  documents = []
61
 
62
+ os.makedirs(VECTOR_STORE_PATH, exist_ok=True)
63
+
64
+ for url in URLS:
65
+ try:
66
+ loader = WebBaseLoader(url)
67
+ docs = loader.load()
68
+ documents.extend(docs)
69
+ except Exception as e:
70
+ print(f"Failed to load {url}: {str(e)}")
71
+ continue
 
 
 
 
72
 
73
+ if not documents:
74
+ raise HTTPException(status_code=500, detail="No documents loaded")
 
75
 
76
+ text_splitter = RecursiveCharacterTextSplitter(
77
+ chunk_size=500,
78
+ chunk_overlap=100
79
+ )
80
+ chunks = text_splitter.split_documents(documents)
81
+
82
+ vector_store = FAISS.from_documents(chunks, _embeddings)
83
+ vector_store.save_local(
84
+ folder_path=VECTOR_STORE_PATH,
85
+ index_name="index"
86
+ )
87
+
88
+ if not os.path.exists(os.path.join(VECTOR_STORE_PATH, "index.faiss")):
89
+ raise HTTPException(status_code=500, detail="FAISS index file not created")
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
+ return vector_store
 
92
 
93
  except Exception as e:
94
+ raise HTTPException(status_code=500, detail=f"Knowledge base creation failed: {str(e)}")
95
+
96
+ # --------------- API Models ---------------
97
+ class ChatRequest(BaseModel):
98
+ message: str
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
+ class ChatResponse(BaseModel):
101
+ response: str
102
+
103
+ # --------------- API Routes ---------------
104
+ @app.post("/chat", response_model=ChatResponse)
105
+ async def chat_endpoint(request: ChatRequest):
106
+ try:
107
+ llm, embeddings = init_models()
108
+
109
+ if not os.path.exists(VECTOR_STORE_PATH):
110
+ vector_store = build_knowledge_base(embeddings)
111
+ else:
112
+ vector_store = FAISS.load_local(
 
113
  VECTOR_STORE_PATH,
114
  embeddings,
115
  allow_dangerous_deserialization=True
116
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
+ context_docs = vector_store.similarity_search(request.message)
119
+ context_text = "\n".join([d.page_content for d in context_docs])
120
+
121
+ prompt_template = PromptTemplate.from_template('''
122
+ You are a helpful and polite legal assistant at Status Law.
123
+ You answer in the language in which the question was asked.
124
+ Answer the question based on the context provided.
125
+
126
+ # ... остальной текст промпта ...
127
 
128
+ Context: {context}
129
+ Question: {question}
130
+
131
+ Response Guidelines:
132
+ 1. Answer in the user's language
133
+ 2. Cite sources when possible
134
+ 3. Offer contact options if unsure
135
+ ''')
136
+
137
+ chain = prompt_template | llm | StrOutputParser()
138
+ response = chain.invoke({
139
+ "context": context_text,
140
+ "question": request.message
141
+ })
142
+
143
+ # Log interaction
144
+ log_interaction(request.message, response, context_text)
145
+
146
+ return ChatResponse(response=response)
147
+
148
+ except Exception as e:
149
+ raise HTTPException(status_code=500, detail=str(e))
150
 
151
+ # --------------- Logging ---------------
152
+ def log_interaction(user_input: str, bot_response: str, context: str):
153
+ try:
154
+ log_entry = {
155
+ "timestamp": datetime.now().isoformat(),
156
+ "user_input": user_input,
157
+ "bot_response": bot_response,
158
+ "context": context[:500],
159
+ "kb_version": datetime.now().strftime("%Y%m%d-%H%M%S")
160
+ }
161
+
162
+ os.makedirs("chat_history", exist_ok=True)
163
+ log_path = os.path.join("chat_history", "chat_logs.json")
164
+
165
+ with open(log_path, "a", encoding="utf-8") as f:
166
+ f.write(json.dumps(log_entry, ensure_ascii=False) + "\n")
167
+
168
+ except Exception as e:
169
+ print(f"Logging error: {str(e)}")
170
+ print(traceback.format_exc())
 
 
 
 
 
171
 
172
  if __name__ == "__main__":
173
+ import uvicorn
174
+ uvicorn.run(app, host="0.0.0.0", port=8000)
requirements.txt CHANGED
@@ -1,4 +1,3 @@
1
- streamlit
2
  langchain-community
3
  langchain-core
4
  langchain-huggingface
@@ -16,8 +15,3 @@ python-multipart
16
  pandas
17
  langchain
18
  plotly
19
-
20
-
21
-
22
-
23
-
 
 
1
  langchain-community
2
  langchain-core
3
  langchain-huggingface
 
15
  pandas
16
  langchain
17
  plotly