Using environmental variables with R reticulate - python

I have a Python package that I want to use in R via reticulate. However, that Python function doesn't appear to see the environmental variables from the R environment. How can I successfully set an environmental variable for the Python function to see?
So if I had a python function like:
import os
def: toy_function():
return os.environ['ENVVAR']
I would like to be able to do:
library(reticulate)
source_python("toy_function.py")
sys.setenv("ENVVAR"="HELLO")
print(toy_function())
And see "HELLO". Currently I am getting an error that "ENVVAR" cannot be found.
Thank you!

Oh, it turns out there is a strange workaround for this, where you just need to call the environmental variable setting directly in Python from R:
py_run_string("import os")
py_run_string("os.environ['ENNVAR'] = 'HELLO'")

Related

Setting environment variable in python has no effect on cfgrib

I am using xarray with cfgrib to load grib files in Python. I have custom grib definitions, which I am providing to eccodes (backend for cfgrib) via the environment variable GRIB_DEFINITION_PATH.
This setup works well, as long as I run the Python script in an environment where the variable was already set.
Now I want to be more flexible with my setup and provide the environment variable from within Python using os.environ (see the example below).
But somehow when setting up the environment like this, the variable gets ignored and I don't understand why.
Can anyone provide me some insight into this mystery? Thanks in advance!
Here an "MRE" of the setting.
import xarray as xr
import os
grib_definitions_path = "/paths/to/definitions:/split/like/this"
os.environ["GRIB_DEFINITION_PATH"] = grib_definitions_path
grib_file = '/path/to/grib/file'
backend_args = {
"filter_by_keys": {"shortName": "P"}
}
array = xr.open_dataset(grib_file, engine="cfgrib", encode_cf=("geography", "vertical"), backend_kwargs=backend_args)["P"]
print(array.dims)
Executing the above code in a terminal fails for me with KeyError: 'P'. If I however first run
export GRIB_DEFINITION_PATH="/paths/to/definitions:/split/like/this"
the dimensions of array are being printed as expected.

Using Jenkins variables/parameters in Python Script with os.path.join

I'm trying to learn how to use variables from Jenkins in Python scripts. I've already learned that I need to call the variables, but I'm not sure how to implement them in the case of using os.path.join().
I'm not a developer; I'm a technical writer. This code was written by somebody else. I'm just trying to adapt the Jenkins scripts so they are parameterized so we don't have to modify the Python scripts for every release.
I'm using inline Jenkins python scripts inside a Jenkins job. The Jenkins string parameters are "BranchID" and "BranchIDShort". I've looked through many questions that talk about how you have to establish the variables in the Python script, but with the case of os.path.join(),I'm not sure what to do.
Here is the original code. I added the part where we establish the variables from the Jenkins parameters, but I don't know how to use them in the os.path.join() function.
# Delete previous builds.
import os
import shutil
BranchID = os.getenv("BranchID")
BranchIDshort = os.getenv("BranchIDshort")
print "Delete any output from a previous build."
if os.path.exists(os.path.join("C:\\Doc192CS", "Output")):
shutil.rmtree(os.path.join("C:\\Doc192CS", "Output"))
I expect output like: c:\Doc192CS\Output
I am afraid that if I do the following code:
if os.path.exists(os.path.join("C:\\Doc",BranchIDshort,"CS", "Output")):
shutil.rmtree(os.path.join("C:\\Doc",BranchIDshort,"CS", "Output"))
I'll get: c:\Doc\192\CS\Output.
Is there a way to use the BranchIDshort variable in this context to get the output c:\Doc192CS\Output?
User #Adonis gave the correct solution as a comment. Here is what he said:
Indeed you're right. What you would want to do is rather:
os.path.exists(os.path.join("C:\\","Doc{}CS".format(BranchIDshort),"Output"))
(in short use a format string for the 2nd argument)
So the complete corrected code is:
import os
import shutil
BranchID = os.getenv("BranchID")
BranchIDshort = os.getenv("BranchIDshort")
print "Delete any output from a previous build."
if os.path.exists(os.path.join("C:\\Doc{}CS".format(BranchIDshort), "Output")):
shutil.rmtree(os.path.join("C:\\Doc{}CS".format(BranchIDshort), "Output"))
Thank you, #Adonis!

%USERPROFILE% env variable for python

I am writing a script in Python 2.7.
It needs to be able to go whoever the current users profile in Windows.
This is the variable and function I currently have:
import os
desired_paths = os.path.expanduser('HOME'\"My Documents")
I do have doubts that this expanduser will work though. I tried looking for Windows Env Variables to in Python to hopefully find a list and know what to convert it to. Either such tool doesn't exist or I am just not using the right search terms since I am still pretty new and learning.
You can access environment variables via the os.environ mapping:
import os
print(os.environ['USERPROFILE'])
This will work in Windows. For another OS, you'd need the appropriate environment variable.
Also, the way to concatenate strings in Python is with + signs, so this:
os.path.expanduser('HOME'\"My Documents")
^^^^^^^^^^^^^^^^^^^^^
should probably be something else. But to concatenate paths you should be more careful, and probably want to use something like:
os.sep.join(<your path parts>)
# or
os.path.join(<your path parts>)
(There is a slight distinction between the two)
If you want the My Documents directory of the current user, you might try something like:
docs = os.path.join(os.environ['USERPROFILE'], "My Documents")
Alternatively, using expanduser:
docs = os.path.expanduser(os.sep.join(["~","My Documents"]))
Lastly, to see what environment variables are set, you can do something like:
print(os.environ.keys())
(In reference to finding a list of what environment vars are set)
Going by os.path.expanduser , using a ~ would seem more reliable than using 'HOME'.

"Undefined variable "py" or class" when trying to load Python from MATLAB R2014b?

def c1(a1,b1):
a1=2
b1=3
cc=a1+b1
return cc
I have saved this function in test.py. When I use this function in MATLAB I encountered this problem:
import py.test.* c1(2,3)
Undefined function 'c1' for input arguments
of type 'double'.
py.test.c1(2,3)
Undefined variable "py" or class
"py.test.c1".
How can I use .py function in MATLAB R2014b?
If you get the error message below, a failure has occurred.
Undefined variable "py" or class
There are a lot of things that might be wrong here, and Mathworks have actually set up a whole tutorial for how to troubleshoot this problem. (The title of the page is actually: Undefined variable "py" or function "py.command", so it should contain most of what you need)
Check out the following:
Python Not Installed
64-bit/32-bit Versions of Python on Windows Platforms
MATLAB Cannot Find Python
Error in User-Defined Python Module
Python Module Not on Python Search Path
Module Name Conflicts
Python Tries to Execute command in Wrong Module
Starting from Matlab 2014b Python functions can be called directly - using prefix py, then module name, and finally function name like so:
result = py.module_name.function_name(parameter1);
However, one has to make sure to add the script to the Python search path when calling from Matlab (especially if the first time Python is called the current working directory is different than that of the Python script.
See more details here.

Enthought Canopy python - name ' ' not defined

I'm very new to using canopy and programming in general.
I'm trying to define a function in Python in the canopy editor. This used to work for me but has suddenly stopped and I have no idea why.
As a basic example, in the editor I wrote;
def funct(x):
return x
When write funct(1) in the shell I get the error message
NameError: name 'funct' is not defined
Any ideas?
Thanks
You need to "run" your script (in the editor) before its results actually exist (and are visible in) the Python shell. In this case the results of your script are to define your function. Just writing the function in the editor doesn't actually create it in Python until you run the script.
As Ali correctly said, another (deeper) approach is to import the script (in this case known as a module), but I think running is probably more what you have in mind.
I've never used Canopy before, but in general you would save the file where your function is defined somewhere in your working directory (e.g. as myfunct.py), then import it into the shell namespace:
In [1]: import myfunct
In [2]: myfunct.funct(1)
Out [2]: 1

Categories

Resources