# Access perspective theme folder in web dev python endpoint

**URL:** <https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759>\
**Category:** Ignition Early Access\
**Created:** [March 22, 2021, 5:36pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759 "2021-03-22T17:36:24Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![nader.chinichian](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nader.chinichian/32/9261_2.png) [@nader.chinichian](https://forum.inductiveautomation.com/u/nader.chinichian)\
**Post date:** [March 22, 2021, 5:36pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/1 "2021-03-22T17:36:24Z")

</div>

Hi

I want to get access to the theme folder of perspective web dev, in a python endpoint.  
What is the correct URL and syntax for that?  
For example, the [http://gatewayIP:8088/main/myfile.xxx](http://gatewayIP:8088/main/myfile.xxx) give me access to the ignition webserver folder but there is no doc for the theme folder.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 22, 2021, 5:45pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/2 "2021-03-22T17:45:46Z")

</div>

If you look around the forum for the `IgnitionGateway` method, you can use it to retrieve the `SystemManager`, which has a [`getDataDir()`](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/ignition/gateway/system/SystemManager.html#getDataDir()) method - that method will give you the start of a tree, which you could walk down to get to the themes directory.

---

<div class="post-metadata">

**Author:** ![nader.chinichian](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nader.chinichian/32/9261_2.png) [@nader.chinichian](https://forum.inductiveautomation.com/u/nader.chinichian)\
**Post date:** [March 22, 2021, 6:38pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/3 "2021-03-22T18:38:25Z")

</div>

Thanks Paul  
Could you please write a short snippet code for me. To show how to import and use it. I’m not java export.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [March 22, 2021, 6:58pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/4 "2021-03-22T18:58:06Z")

</div>

From:

> [@How to get Ignition install directory (OS agnostic)?](http://forum.inductiveautomation.com/t/how-to-get-ignition-install-directory-os-agnostic/40456/3):
>
> Thanks! from com.inductiveautomation.ignition.gateway import IgnitionGateway context = IgnitionGateway.get() projectParentFolder = str(context.systemManager.dataDir.absoluteFile).replace('\\','/') + '/projects/'

```auto
themes = context.systemManager.dataDir.toPath().resolve("modules").resolve("com.inductiveautomation.perspective").resolve("themes")

system.file.readFileAsString(themes.resolve("dark.css").toAbsolutePath())

```

---

<div class="post-metadata">

**Author:** ![nader.chinichian](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nader.chinichian/32/9261_2.png) [@nader.chinichian](https://forum.inductiveautomation.com/u/nader.chinichian)\
**Post date:** [March 24, 2021, 3:15pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/5 "2021-03-24T15:15:39Z")

</div>

> [@paul-griffith](#):
>
> themes = context.systemManager.dataDir.toPath().resolve("modules").resolve("com.inductiveautomation.perspective").resolve("themes") system.file.readFileAsString(themes.resolve("dark.css").toAbsolutePath())

Hi Paul,  
I get this error:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/8/a8b41de9de48a0e6aa66bf32320419fdc4930ad3.png)  
I cant get IgnitionGateway object.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [March 24, 2021, 3:26pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/6 "2021-03-24T15:26:46Z")

</div>

This would only be possible executing in gateway scope.

---

<div class="post-metadata">

**Author:** ![nader.chinichian](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/nader.chinichian/32/9261_2.png) [@nader.chinichian](https://forum.inductiveautomation.com/u/nader.chinichian)\
**Post date:** [March 24, 2021, 3:29pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/7 "2021-03-24T15:29:21Z")

</div>

Is console run code in gateway scope?  
By the way how about web dev scope? is it gateway scope or not?

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [March 24, 2021, 3:29pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/8 "2021-03-24T15:29:44Z")

</div>

WebDev is gateway scope. The console is not (it’s designer, which is like client, but a little different because it’s in the designer).

---

<div class="post-metadata">

**Author:** ![swolnisty](https://avatars.discourse-cdn.com/v4/letter/s/7bcc69/32.png) [@swolnisty](https://forum.inductiveautomation.com/u/swolnisty)\
**Post date:** [March 24, 2021, 4:11pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/9 "2021-03-24T16:11:27Z")

</div>

I am able to run this in a Perspective session scope to see the contents of the theme files:

```auto
from com.inductiveautomation.ignition.gateway import IgnitionGateway
context = IgnitionGateway.get()
filePath = str(context.systemManager.dataDir.absoluteFile).replace('\\','/') + '/modules/com.inductiveautomation.perspective/themes/dark.css'
return system.file.readFileAsString(filePath)

```

---

<div class="post-metadata">

**Author:** ![YF129701](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/yf129701/32/60498_2.png) [@YF129701](https://forum.inductiveautomation.com/u/YF129701)\
**Post date:** [May 4, 2023, 3:19pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/10 "2023-05-04T15:19:29Z")

</div>

Did something change since Mar 2021? I'm trying to access the themes directory using this script on a tag event change:

```python
	themes = context.systemManager.dataDir.toPath().resolve("modules").resolve("com.inductiveautomation.perspective").resolve("themes")
	themeFile = system.file.readFileAsString(themes.resolve("dark.css").toAbsolutePath())
	
	system.util.getLogger('ThemesLogger').info("The theme file contents: {}".format(themeFile))

```

and I get this error in the gateway logs:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/d/bd3326e8aac3d14aa412d308d3a6e92d44ae8d86.png)

I also tried the other method that should be able to be used from a designer script console, but I get an error `ImportError: cannot import name IgnitionGateway`.

```python
from com.inductiveautomation.ignition.gateway import IgnitionGateway
context = IgnitionGateway.get()
filePath = str(context.systemManager.dataDir.absoluteFile).replace('\\','/') + '/modules/com.inductiveautomation.perspective/themes/dark.css'

print system.file.readFileAsString(filePath)

```

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [May 4, 2023, 3:25pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/11 "2023-05-04T15:25:19Z")

</div>

No, nothing changed.

Your first script is complaining that `context` isn't defined.

Your second script would never work in the Designer script console, you can't reference gateway-scoped classes from there.

---

<div class="post-metadata">

**Author:** ![YF129701](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/yf129701/32/60498_2.png) [@YF129701](https://forum.inductiveautomation.com/u/YF129701)\
**Post date:** [May 4, 2023, 3:44pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/12 "2023-05-04T15:44:22Z")

</div>

Yeah, that's what the error is telling me... Do I need to instantiate or call `context` somehow? This is literally a snip from a post in this thread, so I'm not too familiar with the context the OP was working in...

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [May 4, 2023, 3:47pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/13 "2023-05-04T15:47:18Z")

</div>

It was probably this:

> [@swolnisty](#):
>
> ```auto
> from com.inductiveautomation.ignition.gateway import IgnitionGateway
> context = IgnitionGateway.get()
> 
> ```

it would work in a tag event script, but not in the Designer.

---

<div class="post-metadata">

**Author:** ![YF129701](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/yf129701/32/60498_2.png) [@YF129701](https://forum.inductiveautomation.com/u/YF129701)\
**Post date:** [May 4, 2023, 3:54pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/14 "2023-05-04T15:54:23Z")

</div>

Perfect! One last question: I have this script working in the tag event script:

```python
from com.inductiveautomation.ignition.gateway import IgnitionGateway
context = IgnitionGateway.get()
themes = context.systemManager.dataDir.toPath().resolve("modules").resolve("com.inductiveautomation.perspective").resolve("themes")
filePath = "themes: {}, type(themes): {}".format(themes, type(themes))

system.tag.writeBlocking(["[default]themesDS"], filePath)

```

I'm looking to get the list of themes programmatically, just like there is a list in the designer. Is there a method that will retrieve the files and folders located at `\themes`, which I'll then check for extensions on?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 4, 2023, 3:56pm UTC](https://forum.inductiveautomation.com/t/access-perspective-theme-folder-in-web-dev-python-endpoint/44759/15 "2023-05-04T15:56:09Z")

</div>

Look at the Files utility class, full of static methods that accept a Path object like `themes` in your code:  
[https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Files.html](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/file/Files.html)
