Rsnarsna commited on
Commit
23d33cf
1 Parent(s): aa2b899

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +238 -0
app.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import threading
3
+ from email.header import decode_header
4
+ import mysql.connector
5
+ from transformers import pipeline # Assuming you'll use Hugging Face pipeline
6
+ import email, imaplib, json, time
7
+ import logging
8
+
9
+ # Configure logging
10
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
11
+ logger = logging.getLogger(__name__)
12
+
13
+ # Email and database configuration
14
+ IMAP_SERVER = 'imap.gmail.com'
15
+ EMAIL_ADDRESS = '[email protected]'
16
+ PASSWORD = 'gclc wsnx kywt uvqy' # Store this securely in production
17
+ DB_CONFIG = {
18
+ 'host': '0.tcp.in.ngrok.io',
19
+ 'port': 11329,
20
+ 'user': 'root',
21
+ 'password': '', # Add the correct password
22
+ 'database': 'shipment_details'
23
+ }
24
+
25
+ # JSON format for extracted shipment details
26
+ output_format = {
27
+ "origin": "",
28
+ "destination": "",
29
+ "expected_shipment_datetime": "",
30
+ "types_of_service": "",
31
+ "warehouse": "",
32
+ "description": "",
33
+ "quantities": "",
34
+ "carrier_details": ""
35
+ }
36
+
37
+ # Prompt for LLM to process shipment-related emails
38
+ prompt = """
39
+ System prompt: You will be provided with an email containing shipment details. Your task is to extract specific information based on the given instructions.
40
+ Instructions:
41
+ 1. Focus only on extracting details about future shipments, ignore irrelevant information.
42
+ 2. Output should be in JSON format. Missing information should be marked as null.
43
+ 3. Extract the following:
44
+ - origin
45
+ - destination
46
+ - expected_shipment_datetime (format: yyyy-mm-dd hh:mm:ss)
47
+ - types_of_service (AIR, LCL, FCL)
48
+ - warehouse
49
+ - description (max 100 words)
50
+ - quantities
51
+ - carrier_details
52
+ 4. The output should be formatted as follows:
53
+ {
54
+ "origin": "",
55
+ "destination": "",
56
+ "expected_shipment_datetime": "",
57
+ "types_of_service": "",
58
+ "warehouse": "",
59
+ "description": "",
60
+ "quantities": "",
61
+ "carrier_details": ""
62
+ }
63
+ """
64
+
65
+ # Function to insert extracted shipment details into MySQL database
66
+ def insert_data(extracted_details):
67
+ try:
68
+ # Initialize MySQL database connection
69
+ mydb = mysql.connector.connect(**DB_CONFIG)
70
+ cursor = mydb.cursor()
71
+
72
+ # Skip insertion if all required fields are empty
73
+ required_fields = [
74
+ 'origin', 'destination', 'expected_shipment_datetime',
75
+ 'types_of_service', 'warehouse', 'description',
76
+ 'quantities', 'carrier_details'
77
+ ]
78
+ if all(extracted_details.get(field) in ["", None] for field in required_fields):
79
+ logger.info("Skipping insertion: All extracted values are empty.")
80
+ return
81
+
82
+ # Insert data into database
83
+ sql = """
84
+ INSERT INTO shipment_details (
85
+ origin, destination, expected_shipment_datetime, types_of_service,
86
+ warehouse, description, quantities, carrier_details,
87
+ sender, receiver, cc, bcc, subject
88
+ ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
89
+ """
90
+ values = (
91
+ extracted_details.get('origin'),
92
+ extracted_details.get('destination'),
93
+ extracted_details.get('expected_shipment_datetime'),
94
+ extracted_details.get('types_of_service'),
95
+ extracted_details.get('warehouse'),
96
+ extracted_details.get('description'),
97
+ extracted_details.get('quantities'),
98
+ extracted_details.get('carrier_details'),
99
+ extracted_details.get('sender'),
100
+ extracted_details.get('receiver'),
101
+ extracted_details.get('cc'),
102
+ extracted_details.get('bcc'),
103
+ extracted_details.get('subject')
104
+ )
105
+ cursor.execute(sql, values)
106
+ mydb.commit()
107
+ logger.info("Data inserted successfully.")
108
+
109
+ except mysql.connector.Error as db_err:
110
+ logger.error(f"Database error: {db_err}")
111
+ except Exception as ex:
112
+ logger.error(f"Error inserting data: {ex}")
113
+
114
+ # Function to extract shipment details using an LLM
115
+ def get_details(mail):
116
+ try:
117
+ # Initialize LLM model and tokenizer
118
+ # Uncomment below if using Hugging Face models, or load your specific model accordingly
119
+ # pipe = pipeline("text-generation", model=model, tokenizer=tokenizer)
120
+ # output = pipe(f"{prompt}\n{mail}", max_new_tokens=200)
121
+
122
+ # Assuming Llama model for completion (example)
123
+ response = { # Placeholder response for testing purposes
124
+ "origin": "New York",
125
+ "destination": "Los Angeles",
126
+ "expected_shipment_datetime": "2024-10-20 12:00:00",
127
+ "types_of_service": "AIR",
128
+ "warehouse": "Warehouse 1",
129
+ "description": "Electronics shipment",
130
+ "quantities": "10",
131
+ "carrier_details": "Carrier XYZ"
132
+ }
133
+ return json.dumps(response) # Returning mock response for testing
134
+
135
+ except Exception as ex:
136
+ logger.error(f"Error generating details from LLM: {ex}")
137
+ return None
138
+
139
+ # Function to read and process unread emails
140
+ def read_email():
141
+ logging.info('Ready to read email...')
142
+ try:
143
+ logging.info('Connecting to IMAP server...')
144
+ mail = imaplib.IMAP4_SSL(IMAP_SERVER)
145
+ mail.login(EMAIL_ADDRESS, PASSWORD)
146
+ mail.select('inbox')
147
+ logging.info('Selected inbox')
148
+ status, messages = mail.search(None, 'UNSEEN')
149
+ message_ids = messages[0].split()
150
+ logging.info(f"Total unread emails: {len(message_ids)}")
151
+
152
+ for message_id in message_ids:
153
+ try:
154
+ status, data = mail.fetch(message_id, '(RFC822)')
155
+ raw_email = data[0][1]
156
+ email_message = email.message_from_bytes(raw_email)
157
+
158
+ # Extract metadata
159
+ sender = email_message['From']
160
+ receiver = email_message['To']
161
+ cc = email_message.get('Cc', '')
162
+ bcc = email_message.get('Bcc', '')
163
+ subject = email_message['Subject']
164
+
165
+ # Extract email body
166
+ if email_message.is_multipart():
167
+ for part in email_message.walk():
168
+ if part.get_content_type() == 'text/plain':
169
+ email_body = part.get_payload(decode=True).decode('utf-8')
170
+ break
171
+ else:
172
+ email_body = email_message.get_payload(decode=True).decode('utf-8')
173
+
174
+ # Extract and store details
175
+ extracted_details_str = get_details(email_body)
176
+ extracted_details = json.loads(extracted_details_str)
177
+ meta_data = {
178
+ 'sender': sender, 'receiver': receiver, 'cc': cc, 'bcc': bcc, 'subject': subject
179
+ }
180
+ extracted_details.update(meta_data)
181
+ insert_data(extracted_details)
182
+
183
+ except Exception as e:
184
+ logger.error(f"Error processing email {message_id}: {e}")
185
+
186
+ mail.close()
187
+ mail.logout()
188
+
189
+ except Exception as e:
190
+ logger.error(f"Error reading emails: {e}")
191
+
192
+ # Email processing loop
193
+ running = False
194
+ loop_thread = None
195
+
196
+ def email_processing_loop():
197
+ global running
198
+ logger.info("Starting email processing loop...")
199
+ while running:
200
+ read_email()
201
+ time.sleep(10) # Check for new emails every 10 seconds
202
+
203
+ def start_processing():
204
+ global running, loop_thread
205
+ if not running:
206
+ running = True
207
+ loop_thread = threading.Thread(target=email_processing_loop, daemon=True)
208
+ loop_thread.start()
209
+ return "Running"
210
+
211
+ def stop_processing():
212
+ global running
213
+ if running:
214
+ running = False
215
+ return "Stopped"
216
+
217
+ def update_status():
218
+ return "Running" if running else "Stopped"
219
+
220
+ # Create Gradio interface
221
+ with gr.Blocks() as demo:
222
+ gr.Markdown("# Email Processing")
223
+
224
+ status_display = gr.Textbox(label="Email Processing Status", interactive=False)
225
+ status_display.update(value=update_status()) # Initial status display
226
+
227
+ start_button = gr.Button("Start Processing")
228
+ stop_button = gr.Button("Stop Processing")
229
+
230
+ start_button.click(start_processing, outputs=status_display)
231
+ stop_button.click(stop_processing, outputs=status_display)
232
+
233
+ # Automatically update status every 2 seconds
234
+ gr.Timer(update_status, outputs=status_display, interval=2)
235
+
236
+ if __name__ == "__main__":
237
+ logging.info('Starting project...')
238
+ demo.launch()