问题
I use Windows Task Scheduler to run an R Script several times a day. The script transforms some new data and adds it to an existing data file.
I want to use reticulate
to call a Python script that will send me an email listing how many rows of data were added, and if any errors occurred. 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. I get the following errors:
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
This github answer https://github.com/rstudio/reticulate/issues/232) makes it sound like reticulate
can only be used within RStudio - at least for what I'm trying to do. Does anyone have suggestions?
Sample R script:
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())
The Python script ("setup_smtp.py") is like this:
#!/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!
"""
回答1:
This execution problem
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
can stem from multiple reasons:
-
You have multiple Python versions where
smtplib
is installed on one version (e.g., Python 2.7 or Python 3.6) and not the other. Check which Python is being used at command line,Rscript -e "print(Sys.which("python"))"
and RStudio,Sys.which("python")
. Explicitly define which Python.exe to run with reticulate'suse_python("/path/to/python")
.
-
You have multiple R versions where Rscript uses a different version than RStudio. Check
R.home()
variable in both:Rscript -e "print(R.home())"
and callR.home()
in RStudio. Explicitly call the required Rscript in appropriate R version bin folder:/path/to/R #.#/bin/Rscript "/path/to/code.R"
.
-
You have multiple
reticulate
packages installed on same R version, residing in different library locations, each calling a different Python version. Check with the matrix:installed.package()
, locating thereticulate
row. Explicitly calllibrary(reticulate, lib.loc="/path/to/specific/library")
.
来源:https://stackoverflow.com/questions/55599096/use-reticulate-to-call-python-script-and-send-email