问题
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
smtplibis 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
reticulatepackages installed on same R version, residing in different library locations, each calling a different Python version. Check with the matrix:installed.package(), locating thereticulaterow. Explicitly calllibrary(reticulate, lib.loc="/path/to/specific/library").
来源:https://stackoverflow.com/questions/55599096/use-reticulate-to-call-python-script-and-send-email