# Script function execution context

**URL:** <https://forum.inductiveautomation.com/t/script-function-execution-context/16537>\
**Category:** General Discussion\
**Tags:** ignition79, scripting\
**Created:** [January 10, 2018, 8:54am UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537 "2018-01-10T08:54:12Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![pgmo](https://avatars.discourse-cdn.com/v4/letter/p/d07c76/32.png) [@pgmo](https://forum.inductiveautomation.com/u/pgmo)\
**Post date:** [January 10, 2018, 8:54am UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/1 "2018-01-10T08:54:12Z")

</div>

Hi all,  
is there a way to know which is the execution context of a python script function? Say I have a function in a shared script library:

```auto
def foo():
  pass

```

That function will be called in my project by:

1. a gateway tag event
2. a button click  
As far as I understand, in case (1) the running context will be the gateway; in case (2) it will be the client. Well: is there a way inside `foo()` to know where the function is running? I cannot find any scripting function that does it.

Thanks in advance

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 10, 2018, 12:58pm UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/2 "2018-01-10T12:58:09Z")

</div>

Try using [system.util.getSystemFlags()](https://docs.inductiveautomation.com/display/DOC79/system.util.getSystemFlags). Or you can check for the existence of functions that are scope-specific:

```auto
# invokeLater doesn't exist in gateway scopes
if hasattr(system.util, 'invokeLater'):
    # Do Client stuff
    pass
else:
    # Do Gateway stuff
    pass

```

---

<div class="post-metadata">

**Author:** ![pgmo](https://avatars.discourse-cdn.com/v4/letter/p/d07c76/32.png) [@pgmo](https://forum.inductiveautomation.com/u/pgmo)\
**Post date:** [January 10, 2018, 2:54pm UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/3 "2018-01-10T14:54:52Z")

</div>

Thanks pturmel, I will go for the second option, since, after some tests, `system.util.getSystemFlags()` just works on the Client.

---

<div class="post-metadata">

**Author:** ![pgmo](https://avatars.discourse-cdn.com/v4/letter/p/d07c76/32.png) [@pgmo](https://forum.inductiveautomation.com/u/pgmo)\
**Post date:** [January 10, 2018, 4:20pm UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/4 "2018-01-10T16:20:18Z")

</div>

Hi pturmel, after some more palying around, I got stuck on another problem: now my function looks similar to

```auto
def foo():
  if not isClientScope():
    #force clients to open a specific popup by sending a message
    system.util.sendMessage(....)
  else:
    #open a specific popup directly, because this is Client scope
    system.nav.openWindow(......)

```

where isClientScope() implements the code you suggested to find if the function is running in the client or in the gateway scope.  
When this function is run from a button click event, no problem. Whereas if it gets executed on a tag value changed event I get the following error:  
`AttributeError: 'com.inductiveautomation.ignition.common.script.Imm' object has no attribute 'gui'.`  
As of my understading, Ignition is trying to load a module that is not defined in the Gateway scope: is there no way to tell Ignition not to consider the `else` branch?  
Thanks in advance

**SOLUTION**  
First off I found that the error message was due to another module that is loaded when executing `foo()`. In that module I placed the following instruction in the global space:  
`confirmBox=system.gui.confirm`  
to have a shortcut to the `system.gui.confirm` function. That was not good for Ignition. Moreover I had to place the call to `system.nav.openWindow` in a separate function, which I call from the `else` branch.  
Now it’s working pretty good.  
Could you please confirm that this is a good practice, or do you have anything better to suggest me from your valuable experience?  
Thanks, regards

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [January 10, 2018, 5:54pm UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/5 "2018-01-10T17:54:20Z")

</div>

I try to break up my script modules so that truly generic functions that I want to use from any scope are separate from functions that need any gui or nav or similar client/designer-only features. That also means `import` never blows up.

---

<div class="post-metadata">

**Author:** ![Kyle\_Chase](https://avatars.discourse-cdn.com/v4/letter/k/9de0a6/32.png) [@Kyle\_Chase](https://forum.inductiveautomation.com/u/Kyle_Chase)\
**Post date:** [January 11, 2018, 4:45am UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/6 "2018-01-11T04:45:14Z")

</div>

If you want an easier way to detect scope (system.util.getSystemFlags() does not give you a way to know for sure that you are running on the gateway. What if there is a new scope in the future?), give this a whirl.

```auto
from com.inductiveautomation.ignition.common.model import ApplicationScope
scope = ApplicationScope.getGlobalScope()
if ApplicationScope.isClient(scope):
	print "c"

if ApplicationScope.isDesigner(scope):
	print "d"

if ApplicationScope.isGateway(scope):
	print "g"

```

---

<div class="post-metadata">

**Author:** ![pgmo](https://avatars.discourse-cdn.com/v4/letter/p/d07c76/32.png) [@pgmo](https://forum.inductiveautomation.com/u/pgmo)\
**Post date:** [January 11, 2018, 10:02am UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/7 "2018-01-11T10:02:17Z")

</div>

I will give it a try. Thanks!

---

<div class="post-metadata">

**Author:** ![pgmo](https://avatars.discourse-cdn.com/v4/letter/p/d07c76/32.png) [@pgmo](https://forum.inductiveautomation.com/u/pgmo)\
**Post date:** [January 11, 2018, 10:07am UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/8 "2018-01-11T10:07:22Z")

</div>

> [@pturmel](#):
>
> I try to break up my script modules so that truly generic functions that I want to use from any scope are separate from functions that need any gui or nav or similar client/designer-only features. That also means `import` never blows up.

You are right pturmel. Unfortunately this time it is not so easy to structure the application as I would like: I'm porting a Citect SCADA software to Ignition and scripting files there were a big mix of anything came to the mind of the programmer! Particularly there are some scripting files with more then 100 case in a `select ... case` construct, each of them doing something different, from handling a tag event to handling a UI button click! So sad is it this time!!

---

<div class="post-metadata">

**Author:** ![Kyle\_Chase](https://avatars.discourse-cdn.com/v4/letter/k/9de0a6/32.png) [@Kyle\_Chase](https://forum.inductiveautomation.com/u/Kyle_Chase)\
**Post date:** [January 11, 2018, 10:18am UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/9 "2018-01-11T10:18:21Z")

</div>

That sounds like a terrible idea. Why not fix the code and build it properly?

---

<div class="post-metadata">

**Author:** ![pgmo](https://avatars.discourse-cdn.com/v4/letter/p/d07c76/32.png) [@pgmo](https://forum.inductiveautomation.com/u/pgmo)\
**Post date:** [January 11, 2018, 11:25am UTC](https://forum.inductiveautomation.com/t/script-function-execution-context/16537/10 "2018-01-11T11:25:26Z")

</div>

You are so right, Kyle\_Chase! Short answer: very short of time. Short answer nr 2: no one has the big picture of the old software in mind - it was developed over almost 10 years, adding features as requested, more then 1 developer involved, someone no more there … I’ll try to do my best!
