Gaykar commited on
Commit
d9012b6
·
1 Parent(s): 44c6641
Files changed (3) hide show
  1. app/database/connection.py +0 -7
  2. app/graph.py +5 -0
  3. app/main.py +37 -23
app/database/connection.py CHANGED
@@ -29,11 +29,4 @@ SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)
29
  def get_session() -> Session:
30
  return SessionLocal()
31
 
32
- DB_URL_FOR_CHECKPOINTER_STORE=settings.DB_URL_FOR_CHECKPOINTER_STORE
33
 
34
- pool = ConnectionPool(
35
- conninfo=DB_URL_FOR_CHECKPOINTER_STORE,
36
- min_size=1,
37
- max_size=10,
38
- kwargs={"autocommit": True,"row_factory": dict}
39
- )
 
29
  def get_session() -> Session:
30
  return SessionLocal()
31
 
 
32
 
 
 
 
 
 
 
app/graph.py CHANGED
@@ -19,6 +19,10 @@ from app.tools.email_writing_agent_tools import email_writing_agent_tools
19
  from IPython.display import Image, display
20
  from app.persistance.memory_store_checkpointer_config import memory_store, checkpointer
21
  from langchain_google_community import GmailToolkit
 
 
 
 
22
 
23
  # Define a standard retry policy for database-heavy nodes
24
  db_retry_policy = RetryPolicy(
@@ -136,6 +140,7 @@ builder.add_edge("archive_node", END)
136
  toolkit = GmailToolkit()
137
 
138
 
 
139
  graph=builder.compile(checkpointer=checkpointer, store=memory_store)
140
 
141
 
 
19
  from IPython.display import Image, display
20
  from app.persistance.memory_store_checkpointer_config import memory_store, checkpointer
21
  from langchain_google_community import GmailToolkit
22
+ from app.database.connection import pool
23
+ from app.utils.embeddings import remote_embeddings
24
+ from langgraph.checkpoint.postgres import PostgresSaver
25
+ from langgraph.store.postgres import PostgresStore
26
 
27
  # Define a standard retry policy for database-heavy nodes
28
  db_retry_policy = RetryPolicy(
 
140
  toolkit = GmailToolkit()
141
 
142
 
143
+
144
  graph=builder.compile(checkpointer=checkpointer, store=memory_store)
145
 
146
 
app/main.py CHANGED
@@ -1,33 +1,47 @@
1
- from app.graph import graph
2
- from app.state.state import EmailAgentState
3
  import time
4
  from psycopg import OperationalError
 
 
 
5
 
6
- # Define your thread configuration
7
- config = {"configurable": {"thread_id": "user_abc_123"}}
8
 
 
9
 
10
  input_data: EmailAgentState = {
11
- "user_email_id": "gaykaratharva7@gmail.com",
12
- "user_id": 1,
13
- "user_name": "Atharva",
14
- "sender_email_id": "atharvagaykar36@gmail.com",
15
  "sender_subject": "URGENT: Validation of Hybrid Phishing Detection Model & XGBoost Integration",
16
- "sender_email_body": """Dear Atharva,\r\n\r\nI have completed the integration of the *AI-Driven Email Threat Detection*\r\npipeline. We are currently utilizing the fine-tuned DistilBERT model to\r\ngenerate semantic embeddings for incoming messages.\r\n\r\nTo ensure the system is correctly identifying malicious intent, I've\r\nprocessed a suspicious sample using our custom structural tokens: [SSUB],\r\n[SBODY], [LINK], and [PHONE]. This preserves the email's structural context\r\nwhile protecting sensitive data.\r\n[MODEL EVALUATION DATA]\r\n\r\n*1. Semantic Context:* The fine-tuned DistilBERT has mapped the input to a\r\nhigh-dimensional vector space. Initial checks suggest strong clustering\r\nwith known phishing signatures.\r\n\r\n*2. URL Feature Engineering:* Our hybrid pipeline extracted numerical\r\nindicators from the embedded links.\r\n\r\n -\r\n\r\n Subdomain count: 4\r\n -\r\n\r\n Suspicious keywords: 2\r\n -\r\n\r\n Special characters: @, -, .\r\n -\r\n\r\n Redirection detected: True\r\n\r\n*3. XGBoost Classification:* The combined feature set (DistilBERT\r\nembeddings + numerical URL features) has been passed to the XGBoost\r\nclassifier.\r\n\r\n -\r\n\r\n *Current Test Accuracy:* 99.35%\r\n\r\nFinal Confirmation Needed:\r\n\r\n 1.\r\n\r\n Should we deploy the current XGBoost weights to the:\r\n https://huggingface.co/spaces/Gaykar/ClassifyEmail\r\n 2.\r\n\r\n Do you want to review the Hybrid_model_preparation.ipynb logic before we\r\n push to the:\r\n https://github.com/Atharva-Gaykar/AI-Driven-Email-Threat-Detection\r\n 3.\r\n\r\n Are the [LINK] and [PHONE] placeholders correctly masking the PII\r\n (Personally Identifiable Information) according to the project spec?\r\n\r\nPlease provide your approval to proceed with the Docker deployment.\r\n\r\nBest regards,\r\n\r\nVinit Security AI Engineer\r\n"""
17
  }
18
 
19
-
20
-
21
-
22
- for i in range(3): # Try 3 times to account for Neon wake-up
23
  try:
24
- result = graph.invoke(input_data, config=config)
25
- break
26
- except OperationalError:
27
- print("Waiting for Neon to wake up...")
28
- time.sleep(5)
29
-
30
-
31
- print(result)
32
-
33
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import time
2
  from psycopg import OperationalError
3
+ from app.graph import graph
4
+ from app.state.state import EmailAgentState
5
+ from app.database.connection import pool
6
 
 
 
7
 
8
+ config = {"configurable": {"thread_id": "user_abc_123"}}
9
 
10
  input_data: EmailAgentState = {
11
+ "user_email_id": "gaykaratharva7@gmail.com",
12
+ "user_id": 1,
13
+ "user_name": "Atharva",
14
+ "sender_email_id": "atharvagaykar36@gmail.com",
15
  "sender_subject": "URGENT: Validation of Hybrid Phishing Detection Model & XGBoost Integration",
16
+ "sender_email_body": """Dear Atharva,\r\n\r\nI have completed the integration of the AI-Driven Email Threat Detection pipeline... [truncated for brevity]"""
17
  }
18
 
19
+ if __name__ == "__main__":
20
+ result = None
 
 
21
  try:
22
+ # 3. Retry loop for Neon wake-up/stability
23
+ for i in range(3):
24
+ try:
25
+ print(f"Attempt {i+1}: Invoking graph...")
26
+ result = graph.invoke(input_data, config=config)
27
+ break # Success! Exit the loop.
28
+ except OperationalError as e:
29
+ if i < 2:
30
+ print("Waiting for Neon database to wake up...")
31
+ time.sleep(10) # Increased sleep slightly for Neon cold starts
32
+ else:
33
+ print("Max retries reached. Database connection failed.")
34
+ raise e
35
+
36
+ # 4. Output the result
37
+ if result:
38
+ print("\n--- Graph Execution Result ---")
39
+ print(result)
40
+
41
+ except Exception as e:
42
+ print(f"An error occurred during execution: {e}")
43
+
44
+ finally:
45
+ # 5. CRITICAL: Close the pool to prevent "cannot join current thread" error
46
+ print("Closing connection pool...")
47
+ pool.close()