#python #pandas #email #ssl #smtplib
#python #панды #Адрес электронной почты #ssl #smtplib
Вопрос:
Итак, я создал эту простую программу, которая каждый час проверяет мои исследовательские данные на nan. Это работает нормально, но я хочу улучшить электронное письмо, которое оно отправляет мне, когда находит nan. На данный момент я могу заставить его отправлять мне по электронной почте только то, что я помещаю в три речевых знака, например
message = """Missing data, yo."""
Я хочу, чтобы он отправил мне по электронной почте дату, время и имя файла, когда у него есть nan. Я пробовал следующее, но это не работает:
message = f"Hello, Cairan. {full_name} has missing data."
и я пробовал это, но это не сработало:
message = """Missing data """ full_name
Я не знаю, что я здесь делаю не так — пожалуйста, помогите. Я также был бы признателен за любые советы о том, как изменить заголовок темы для электронного письма.
Спасибо!
# -*- coding: utf-8 -*-
"""
This Python script was written for use on an Amazon EC2 server, with the Eltek GPRS Server running.
This code has a 60 minute loop, which:
1. Copies the data from its original location to a temporary 'checking' directory.
2. Imports the listed CSV files
3. Converts all 'No Data' into nans
4. Looks at the last 12 observations and checks if there is any nans - if there are any it will email an email address about the nans.
5. Loops over all files
6. Loops every hour
"""
# Import packages
import os #os
import fnmatch #fn match
import pandas as pd #pandas
import numpy as np #numpy
import sched #scheduler
import time # time
import smtplib #for email
import ssl #for email
from datetime import datetime #datetime
from termcolor import colored #for colouring text
from shutil import copyfile
# Scheduler
s = sched.scheduler(time.time, time.sleep)
# Email
user = '####@gmail.com' #email username (gmail tested and working)
sender = '####@gmail.com' #sendee email address
password = '####' #email password
port = 465 #port - 465 standard
recieve = '####'
context = ssl.create_default_context()
directory = "C:/EltekGateway/"
individual_files = "K01817-12158.csv", "K01830-12197.csv", "K01830-12200.csv"
files = "C:/EltekGateway/checking/K01817-12158.csv", "C:/EltekGateway/checking/K01830-12197.csv", "C:/EltekGateway/checking/K01830-12200.csv"
for full_name in individual_files:
checking_dir = directory "checking/" full_name
original_dir = directory full_name
copyfile(original_dir, checking_dir)
print(original_dir, checking_dir)
def do_something(sc):
now = datetime.now()
print('<---------------------------------------------------------------------------------->')
print('Checking:' , len(files), 'datafiles.', 'Time now =', now)
for full_name in files:
df_tmp= pd.read_csv(full_name, skiprows = 5) # read csv to df_tmp
df_tmp.rename({'TX Channel': 'date'}, axis=1, inplace=True) # rename cols
df_tmp['date'] = pd.to_datetime(df_tmp['date'], errors='raise', dayfirst=True) # create datetime col
df_tmp = df_tmp.replace('No Data', np.nan) # Eltek 'No Data' to nan
df_check = df_tmp[-12:]
df_check = df_check.isnull().values.any()
# df_check = df_check.isna() # Check last observation to see if there is a nan
df_check_time = df_tmp.date.iloc[-1] # Store datetime for last obs
now = datetime.now()
date_string = df_check_time.strftime("%Y/%m/%d, %H:%M:%S")
# print(df_check) #checking loop
if df_check.any() == 0: # Check
print(date_string, full_name colored(' - There is NO missing data','green'))
# print()
else:
print(date_string, full_name colored(' - There IS missing data', 'red'))
message = """Missing data, yo."""
# message = f"Hello, Cairan. {full_name} has missing data."
with smtplib.SMTP_SSL("smtp.gmail.com", port, context=context) as server:
server.login(sender, password)
server.sendmail(sender, recieve, message)
# print(df_tmp) #checking loop
# print(full_name) #checking loop
# print(df_check_time) #checking loop
print('<---------------------------------------------------------------------------------->')
s.enter(3600, 1, do_something, (sc,))
def main():
s.enter(3600, 1, do_something, (s,))
s.run()
if __name__ == "__main__":
main()
Комментарии:
1. попробуйте это ` msg.as_string()`
2. уже пробовал .as_string() — не сработало
3. Какое сообщение об ошибке возвращается
server.sendmail
?4. «но это не работает» не помогает. Вы получили сообщение об ошибке? Если это так, опубликуйте полную обратную трассировку. Если вы не получили сообщение об ошибке, то как вы могли сказать, что оно «не работает»? Что произошло и чем это отличается от того, чего вы хотели.
5. Итак, когда я использовал .as_string(), код зависает, и цикл не завершается — ошибки нет
Ответ №1:
Ваше сообщение искажено.
Вы должны написать его с правильным заголовком и тому подобное, вот так:
message = """
From: Robot <noreply@domain.com>
To: Persoon <persoon@gmail.com>
Subject: Something Fancy Happened!
Hi Persoon,
Your Thing caused Something Fancy!
Yours,
Robot.
"""
Если вы не хотите создавать сообщение вручную, взгляните на https://docs.python.org/3/library/email.html
Комментарии:
1. Я собирался написать это, то есть заголовки.. ты меня опередил
2. Я реализовал заголовок, как вы предлагаете, который отлично работает, когда он находится вне цикла, но я хочу, чтобы он был внутри цикла, чтобы я мог включить
full_name
его в электронное письмо. Но когда я помещаю весь код, который вы предлагаете, внутрь цикла — заменяяmessage = """Missing data, yo."""
в моем предыдущем коде, электронное письмо проходит, но в получаемом мной электронном письме все содержимое содержится в части From: в электронном письме, в теме или теле которого ничего нет3. @CairanVanRooyen можете ли вы отредактировать свой вопрос и добавить к своему вопросу фрагмент блока, который начинается с
if df_check.any() == 0: # Check
того, что вы отредактировали?