Your browser was unable to load all of the resources. They may have been blocked by your firewall, proxy or browser configuration.
Press Ctrl+F5 or Ctrl+Shift+R to have your browser try again.

using a python script returned value in quickbuild #2291

varlib86 ·
Hi ,

I have a python script that fetches some values from the rest api and returns it , this script runs as a step in my quickbuild configuration.. i want to use these values for embedding them in the notification template ...by saving it in the form of a variable

Something like this :
value => value returned by the python script

$vars.getValue("value")

Is it possible ?
  • replies 16
  • views 7514
  • stars 0
robinshen ADMIN ·
Yes, this can be done by writing value of the variable like below:
${groovy:"python /path/to/your/python/script".execute().text}
varlib86 ·
this is what I am trying to do :

${groovy: "python.exe ${configuration.getWorkspaceDir().getAbsolutePath()}/qbstuff/grabbigSM.py}".execute().text}


but it is giving me an error saying failed to evaluate this expression any ideas ?
robinshen ADMIN ·
Please do not embed ${...} recursively. I changed the script as below:
${groovy: "python.exe " + configuration.getWorkspaceDir().getAbsolutePath() + "/qbstuff/grabbigSM.py".execute().text}
varlib86 ·
Hi..

Yes .. I corrected it .. I am using it that way only but nothing gets stored in the variable i created even if i run this ..

this is how my python script is :
def main()

--
--
return value

if __name__ == "__main__":
main()


so if i execute it by using ${groovy: "python.exe " + configuration.getWorkspaceDir().getAbsolutePath() + "/qbstuff/grabbigSM.py".execute().text} and store it in a variable
the variable is blank .. ?any ideas why ?
robinshen ADMIN ·
Please rewrite the variable value like below to print the executed command in server log and then run this command directly in command line to see if it writes to standard output correctly (you may append the command with > output.txt, and then check the output.txt to verify).
${groovy: 
def cmd = "python.exe " + configuration.getWorkspaceDir().getAbsolutePath() + "/qbstuff/grabbigSM.py";
logger.info(cmd);
return cmd.execute().text;
}
varlib86 ·
is it possible to do this as a part of thepost execution action of the script:

Actually the main thing is ;

is it possible to assign the value of the variable i created in the Post execution action ->Execute script in the Advanced features section of the step that goes and executes the python script ?

lets say that the variable i created in quickbuild is : var1

and if i do this $var1.setValue in the post execution action that sets its value to the value got by the concerned script ..so that it automatically stores the value after running the script ..
robinshen ADMIN ·
I guess this will have the same problem as it seems that the problem is with the python command itself. I've tested executing another command with first approach and it works.
varlib86 ·
the easiest thing i was thinking to do was use util.execute(cmd) but the problem is I am unable to change the working directory ... i want to change the working directory as my python is stored at some working directory ..

although in the same step where i have my post execution step that executes and stores the value in a variable ... it has the working directory specified ..but somehow it is not referencing it..

how quickbuild allows us to change working directory for util.execute()
varlib86 ·
another imp thing is :

now this works.. but the thing is if i assign the value of the script being returned to a variable here .. it comes out to be 0

groovy:
def value = "python.exe " + configuration.getWorkspaceDir().getAbsolutePath() + "/qbstuff/grabbigSM.py"
logger.info(value);
File path1 = new File("D:/Python27");
def ret_code = util.execute(value, path1);
variable= vars.get("returned_value")
logger.info(ret_code.toString());
variable.setValue(ret_code);


any ideas how to fix this as the util.execute command returns an int ..
robinshen ADMIN ·
The odd thing is that this still works at my side. So I wonder where you are defining the script, and where are you accessing variable value? Preferrably, can you please create a test database demonstrating your issue and send to [robin AT pmease DOT com]?
HealingQuickly ·

Hello Robin

I'm also trying to set a variable value through groovy scripts. However, I noticed I can't just return a value like so

variable.setValue(${groovy:
return "new_value"})

My question is, why this returns null instead of the string? While

return cmd.execute().text

works, I don't understand they are both String type, but only one of them actually sets the variable value.

Another question is, how can I return multiple values and put them in the variable as multi-line values, so that I can use them one by one later?

Much thanks!

robinshen ADMIN ·

Since while you are calling variable.setValue(), it is already in a groovy script, and you no longer need to wrap another groovy script ${return "new_value"}, instead just call:
variable.setValue("new_value");

The variable should be able to store multi-line value, as long as your script pass multi-line value.

HealingQuickly ·

Hello Robin

I've encountered this problem when I use groovy to call a python script, then use the return value of python script.
The problem is that the groovy script (cmd.execute().text) always gets nothing (null).

In my python script (execute_cmd.py), I've tried print() or return() the value I want, the groovy script still gets nothing.

This is my groovy script in a Batch/shell build step:

${groovy:
def cmd = "python.exe " + configuration.getWorkspaceDir().getAbsolutePath() + "\\execute_cmd.py " + params.get("component");
logger.info("This is the cmd: " + cmd);
def result = cmd.execute().text;
logger.info("This is result: " + result)
return result
}

And if I go into the QB workspace and call a groovy script in the same directory, to call the python script, it will get the print() result from python.
The groovy script only has this hard coded statement:

def cmd = "python.exe execute_cmd.py My_component";
def result = cmd.execute().text
println result;
// result will be the return (print) value from execute_cmd.py

Can you tell me how this is?

Thank you!

robinshen ADMIN ·

Please print value of the evaluated cmd, and run exactly the same command from groovy (like you've done from workspace now) to see if it works.

HealingQuickly ·

I did try print, I've tried print as well as return, it doesn't catch the printed value. cmd.execute().text is still null.

The weird thing is, I can retrieve the value if I execute a groovy script on agent directly (without using QB). I just go to the agent where the workspace is, and create the simple groovy script I pasted above, and run it on a cmd window, it will get the print value from python (stored in the groovy def result).

Not sure what happened here Robin.

Update:
What's the recommended way to publish build log of a certain step as artifact (not the whole config run)? If I could get access to the entire build log conveniently, I can just use that instead of using groovy to catch the stdout.

Thanks!

robinshen ADMIN ·

I mean to run exactly the same command (printed out via logger.info("This is the cmd: " + cmd)) from agent console via groovy to see if it works. You are testing "python.exe execute_cmd.py My_component", but not the same command used by QB.

As to publish build log of specific step, it is not supported by QB.