使用 reticulate 调用 Python 脚本并发送电子邮件

Use reticulate to call Python script and send email

我每天多次使用 Windows Task Scheduler 运行 R 脚本。该脚本转换一些新数据并将其添加到现有数据文件中。

我想使用 reticulate 调用 Python 脚本,该脚本会向我发送一封电子邮件,列出添加了多少行数据,以及是否发生任何错误。当我从 RStudio 中逐行 运行 它时,这可以正常工作。问题是当脚本 运行 按计划运行时它不起作用。我收到以下错误:

Error in py_run_file_impl(file, local, convert) : 
  Unable to open file 'setup_smtp.py' (does it exist?)
Error in py_get_attr_impl(x, name, silent) : 
  AttributeError: module '__main__' has no attribute 'message'
Calls: paste0 ... py_get_attr_or_item -> py_get_attr -> py_get_attr_impl
Execution halted

这个 github 回答 https://github.com/rstudio/reticulate/issues/232) 听起来 reticulate 只能在 RStudio 中使用 - 至少对于我正在尝试做的事情。有人有建议吗?

示例 R 脚本:

library(tidyverse)
library(reticulate)
library(lubridate)

n_rows <- 10
time_raw <- now()

result <- paste0("\nAdded ", n_rows, 
                 " rows to data file at ", time_raw, ".")

try(source_python("setup_smtp.py"))

message_final <- paste0(py$message, result)

try(smtpObj$sendmail(my_email, my_email, message_final))
try(smtpObj$quit())

Python脚本("setup_smtp.py")是这样的:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Call from reticulate to log in to email
"""

import smtplib

my_email = '...'
my_password = '...'

smtpObj = smtplib.SMTP('smtp.office365.com', 587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.login(my_email, my_password)

message = """From: My Name <email address>
To: My Name <email address>
Subject: Test successful!
"""

这个执行问题

This works correctly when I run it line by line from within RStudio. The problem is that it doesn't work when the script runs on schedule

可能源于多种原因:

  1. 您有多个 Python 版本,其中一个版本(例如 Python 2.7 或 Python 3.6)安装了 smtplib,而另一个没有安装。检查在命令行 Rscript -e "print(Sys.which("python"))" 和 RStudio Sys.which("python") 中使用了哪个 Python。用网状的 use_python("/path/to/python").

    显式定义 Python.exe 到 运行

  1. 您有多个 R 版本,其中 Rscript 使用的版本与 RStudio 不同。检查 R.home() 两个变量:Rscript -e "print(R.home())" 并在 RStudio 中调用 R.home()。在适当的 R 版本 bin 文件夹中显式调用所需的 Rscript:/path/to/R #.#/bin/Rscript "/path/to/code.R".


  1. 您在同一个 R 版本上安装了多个 reticulate 包,它们位于不同的库位置,每个调用不同的 Python 版本。检查矩阵:installed.package(),找到 reticulate 行。显式调用 library(reticulate, lib.loc="/path/to/specific/library").