# Template node and python

**URL:** <https://discourse.nodered.org/t/template-node-and-python/81146>\
**Category:** General\
**Tags:** python\
**Created:** [8 September 2023 14:23 UTC](https://discourse.nodered.org/t/template-node-and-python/81146 "2023-09-08T14:23:51Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 14:23 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/1 "2023-09-08T14:23:52Z")

</div>

Hi, I need to use python to run a script, and I'm scrambling to solve this two issues. I need to have the script within node-red for several reasons. Actually, I wrote the python script within the template node, then via a write node I write it in a defined directory so that I can run it with the exec node.  
At the moment everything works as expected since I hard coded the variables within the script.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/2/a2aefe9f0d0edfbbf6c22f08e6fbfc27f172024d.png)  
Now I have this global context

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/2/82adf2e07ec654083ef66b9ea2b464cbf3305d9d.png)

```auto
global.set("test",{"Path":{"A": "FolderA","B": "FolderB","length":[350,500],"test1": 70389,"test2": 13546},"testing":{"Refresh": "default","Errors": 5}})

```

And this is what I would like to achieve:  
**1) Directly use the global context**.  
Using the suggested syntax, this script print what expected

```auto
#!/usr/bin/env
test = {{{global.test.Path.test2}}}
print (test)
exit()

```

but this one returns an error

```auto
#!/usr/bin/env
test = {{{global.test.testing.Refresh}}}
print (test)
exit()

```

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/a/ca66208175f5507ca9a19e9f7486762f96e48cf9.png)  
Anyway, what I would like to have is a variabile within the python script so that I can directly use all its properties. Something like:

```auto
test = {{{global.test}}}
var1= Path.test2
var2= testing.Refresh
etc

```

**2) To be able to directly pass the script to the exec node without write it on a file**.  
I followsd this topic, but it doesn't seem to work anymore

> [@Simple counter with python context.get('count')](https://discourse.nodered.org/t/simple-counter-with-python-context-get-count/75709/12):
>
> I've never used the python script node so don't know what it provides. The exec node lets you call an external script, regardless of it's language. It is possible to pass arguments (which can include context variables) to the script. But you may well prefer to keep the script code within Node-red rather than in an external file. It is possible to do this using the template and exec nodes; I put together an example python script. It's clunky but it does work. [{…

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [8 September 2023 14:44 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/2 "2023-09-08T14:44:29Z")

</div>

As global.test.testing.refresh is a string should it not have quotes around it?

```auto
#!/usr/bin/env
test = "{{{global.test.testing.Refresh}}}"
print (test)
exit()

```

global.test.Path.test2 is a number so not required.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 14:46 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/3 "2023-09-08T14:46:18Z")

</div>

but without quote I get an error when define it as global context

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [8 September 2023 14:47 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/4 "2023-09-08T14:47:54Z")

</div>

The quotes would be in the template. As shown above.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 14:49 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/5 "2023-09-08T14:49:39Z")

</div>

Oh yes, I got it. I see what you mean, yes thanks. But how can I have all the global context's properties in a variable?

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [8 September 2023 14:56 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/6 "2023-09-08T14:56:28Z")

</div>

> [@Lupin\_III](#):
>
> I followsd this topic, but it doesn't seem to work anymore

I just redownloaded that example and tried it; it seems to work for me, I'm on a Raspberry Pi with the latest version of RPiOS (so python is v3 only)  
Can you show me what problem you get with it?

I do have a slightly updated version of that flow but if you have spotted a bug I need to test it.

**ps** It never occurred to me to pass an entire javascript object to python as a single parameter.  
It does seem to pass _something_ but you'd have to parse it within python, which seems less simple than passing individual values from Node-red.

**pps** What is your #! /usr/bin/env at the top of your two scripts intended to do? I suspect it does nothing.

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [8 September 2023 15:10 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/7 "2023-09-08T15:10:44Z")

</div>

Add quote mustache either side and prior to template set msg.quotes depending if global is a string.  
e.g.

```auto
[{"id":"3ca9710f86c46a79","type":"inject","z":"b9860b4b9de8c8da","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":560,"y":520,"wires":[["99639618049b79b1"]]},{"id":"99639618049b79b1","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"test","pt":"global","to":"{\"Path\":{\"A\": \"FolderA\",\"B\": \"FolderB\",\"length\":[350,500],\"test1\": 70389,\"test2\": 13546},\"testing\":{\"Refresh\": \"default\",\"Errors\": 5}}","tot":"json"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":580,"wires":[["07b2e786018c81df","45a4da5325d30a72"]]},{"id":"07b2e786018c81df","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"quotes","pt":"msg","to":"$type($globalContext(\"test.testing.Refresh\")) = \"string\" ? '\"' : ''","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":720,"y":560,"wires":[["813a7d96abfecabf"]]},{"id":"45a4da5325d30a72","type":"change","z":"b9860b4b9de8c8da","name":"","rules":[{"t":"set","p":"quotes","pt":"msg","to":"$type($globalContext(\"global.test.Path.test2\")) = \"string\" ? '\"' : ''","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":700,"y":620,"wires":[["9006aee5fa9b7656"]]},{"id":"813a7d96abfecabf","type":"template","z":"b9860b4b9de8c8da","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"#!/usr/bin/env\ntest = {{{quotes}}}{{{global.test.testing.Refresh}}}{{{quotes}}}\nprint (test)\nexit()\n","output":"str","x":880,"y":560,"wires":[["fd1f321c74387065"]]},{"id":"9006aee5fa9b7656","type":"template","z":"b9860b4b9de8c8da","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"#!/usr/bin/env\ntest = {{{quotes}}}{{{global.test.Path.test2}}}{{{quotes}}}\nprint (test)\nexit()\n","output":"str","x":860,"y":620,"wires":[["540728c240447648"]]},{"id":"fd1f321c74387065","type":"debug","z":"b9860b4b9de8c8da","name":"debug 332","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1090,"y":540,"wires":[]},{"id":"540728c240447648","type":"debug","z":"b9860b4b9de8c8da","name":"debug 333","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1070,"y":600,"wires":[]}]

```

Probably easier to get option 2 working though.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 15:26 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/8 "2023-09-08T15:26:57Z")

</div>

> [@jbudd](#):
>
> Can you show me what problem you get with it?

yes on raspberry it's ok. On windows 11 and python 3.10.5 I get this

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/7/e751b0368cfa24bf0c425d9a715cff0b00f02b68.png)

> [@jbudd](#):
>
> **ps** It never occurred to me to pass an entire javascript object to python as a single parameter.  
> It does seem to pass _something_ but you'd have to parse it within python, which seems less simple than passing individual values from Node-red.

I imagine. I have even trying with json library but without success till now

> [@jbudd](#):
>
> **pps** What is your #! /usr/bin/env at the top of your two scripts intended to do? I suspect it does nothing.

it's just because at the moment I write the script in a file and then call it from the exec node.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 15:35 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/9 "2023-09-08T15:35:17Z")

</div>

Yes thanks. Now the problem is how to read all the properties since I need several of them

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [8 September 2023 15:46 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/10 "2023-09-08T15:46:38Z")

</div>

> [@Lupin\_III](#):
>
> > [@jbudd](#):
> >
> > **pps** What is your #! /usr/bin/env at the top of your two scripts intended to do? I suspect it does nothing.
> 
> it's just because at the moment I write the script in a file and then call it from the exec node.

Hmm Windows.  
On Linux the #! line specifies which interpreter (eg python, awk, bash etc) should be used to process the file - provided that a) the file is executable (ie ls -l filename shows an x in the relevant place[s]) and b) it is executed by being called by name `myscriptname` not `python myscriptname`  
The #! should be followed text which evaluates as the name of an existing interpreter (eg #! /binbash or #! /usr/bin/env python)  
I don't know what a #! line does on Windows.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 15:50 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/11 "2023-09-08T15:50:54Z")

</div>

Sorry, you're right. What I post for help is based on debian (raspberry) that's why you see this line.  
But I even tried your code on windows, and here I get this error, not on the pi

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [8 September 2023 15:56 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/12 "2023-09-08T15:56:32Z")

</div>

> [@Lupin\_III](#):
>
> On windows 11 and python 3.10.5 I get this
> 
> ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/7/e751b0368cfa24bf0c425d9a715cff0b00f02b68.png)

I am afraid I neither run Node-red nor python on WIndows so I can't reproduce the problem.  
It does look as it is offended by the script arriving as a multi-line string.  
As a test it might be worth:  
Removing all comments from the script.  
Put a caret symbol ^ before each newline in the script.

Is there any way to for exec to insist on powershell rather than command shell? Or even **gasp** , a Linux shell?

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 16:01 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/13 "2023-09-08T16:01:10Z")

</div>

it's ok, it just because I came across it. On raspberry it's ok.  
If someone could help with the full global context. I'm trying to solve it using json.load, but nothing

---

<div class="post-metadata">

**Author:** ![jbudd](https://avatars.discourse-cdn.com/v4/letter/j/5f8ce5/32.png) [@jbudd](https://discourse.nodered.org/u/jbudd)\
**Post date:** [8 September 2023 16:47 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/14 "2023-09-08T16:47:04Z")

</div>

Please post an export of your flow, using an inject node to set the Json to be passed to the script.

---

<div class="post-metadata">

**Author:** ![Lupin\_III](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/lupin_iii/32/67650_2.png) [@Lupin\_III](https://discourse.nodered.org/u/Lupin_III)\
**Post date:** [8 September 2023 17:47 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/15 "2023-09-08T17:47:48Z")

</div>

I just solved it passing the global context to the template node as

> msg.globaltest = JSON.stringify(global.get("test"))

and calling it from within the script as

> import json  
> test = json.loads('{{{globaltest }}}')  
> print (test['Path']['test2'])  
> print (test['testing']['Refresh'])  
> exit()

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [22 September 2023 17:48 UTC](https://discourse.nodered.org/t/template-node-and-python/81146/16 "2023-09-22T17:48:18Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
