CompileError when trying to customize a shiny theme

Hi all,

I'm trying to reproduce this code example to customize a shiny for pyhton theme. Here is what I did:

First, I installed libsass using

pip install libsass

Then, I created the my_theme.py file as shown in the example and tried to run the script but I ran into this error:

Traceback (most recent call last):
  File "c:\Users\tl100\PycharmProjects\shiny_amulator\development\theme_freecastle.py", line 19, in <module>
    f.write(my_theme.to_css())
            ^^^^^^^^^^^^^^^^^
  File "C:\Users\tl100\.conda\envs\shi\Lib\site-packages\shiny\ui\_theme.py", line 430, in to_css
    self._css = sass.compile(string=self.to_sass(), **args)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\tl100\.conda\envs\shi\Lib\site-packages\sass.py", line 725, in compile
    raise CompileError(v)
sass.CompileError: Error: File to import not found or unreadable: C:Userstl100.conda♫nvsshiLibsite-packagesshinywwwsharedsasspresetshiny_01_functions.scss.
        on line 1:1 of stdin
>> @import "C:\Users\tl100\.conda\envs\shi\Lib\site-packages\shiny\www\shared\s
   ^

And indeed, the path that could not be found or read looks really strange. So, I tried to paste the absolute path into the _theme.py file:

    def to_sass(self) -> str:
        """
        Returns the custom theme as a single Sass string.

        Returns
        -------
        :
            The custom theme as a single Sass string.
        """
        # path_functions = path_pkg_preset(self._preset, "_01_functions.scss")
        path_functions = "C:/Users/tl100/.conda/envs/shi/Lib/site-packages/shiny/www/shared/sass/preset/shiny_01_functions.scss"
        path_defaults = path_pkg_preset(self._preset, "_02_defaults.scss")
        path_mixins = path_pkg_preset(self._preset, "_03_mixins.scss")
        path_rules = path_pkg_preset(self._preset, "_04_rules.scss")

However, I get the same issue:

Traceback (most recent call last):
  File "C:\Users\tl100\PycharmProjects\shiny_amulator\development\theme_freecastle.py", line 19, in <module>
    f.write(my_theme.to_css())
            ^^^^^^^^^^^^^^^^^
  File "C:\Users\tl100\.conda\envs\shi\Lib\site-packages\shiny\ui\_theme.py", line 430, in to_css
    self._css = sass.compile(string=self.to_sass(), **args)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\tl100\.conda\envs\shi\Lib\site-packages\sass.py", line 725, in compile
    raise CompileError(v)
sass.CompileError: Error: File to import not found or unreadable: C:/Users/tl100/.conda/envs/shi/Lib/site-packages/shiny/www/shared/sass/preset/shiny_01_functions.scss.
        on line 1:1 of stdin
>> @import "C:/Users/tl100/.conda/envs/shi/Lib/site-packages/shiny/www/shared/s
   ^

Yet, the path looks different but still could not be accessed. I also tried to customize a shinyswatch theme using this approach:

import shinyswatch

(
  shinyswatch.theme.zephyr
  .add_defaults(
    primary="#aa00ff",  # purple
    secondary="#bfff00",  # lime green
  )
  .add_rules(
    """
    strong {
      color: $primary;
    }
    """
  )
)

But I run into the same error.

Does someone of have an idea of what else I could do? Please let me know if you need further information. I appreciate any help, thanks :raising_hand_man:

HI @thundert, welcome to the forum!

Although I am using macOS, I too am running into issues with that example...I've started a thread internally to get some understanding of what is happening, I will respond back here when we understand the issue better.

Best,
Randy

Hi @thundert, can you confirm that the following folder actually exists on your computer?

@grrrck 's question is a good one, but I also want to add that I opened a GitHub issue about a bug I am facing:

So you might also check that @thundert by putting your app.py and my_theme.py files in a directory by themselves and seeing if that works.

Best,
Randy

1 Like

Hi you two :slight_smile: ,

thanks for diving into the topic. I checked the folder and it exists:

However, I realized that in my first post the absolute path I used was wrong. It was

path_functions = "C:/Users/tl100/.conda/envs/shi/Lib/site-packages/shiny/www/shared/sass/preset/shiny_01_functions.scss"

, while it should be (there was a slash missing after shiny)

path_functions = "C:/Users/tl100/.conda/envs/shi/Lib/site-packages/shiny/www/shared/sass/preset/shiny/_01_functions.scss"

Once, I paste the corrected absolute paths into _theme.py, my_theme.py compiles without issues and I can use it in my app as

app_ui = ui.fluid_page(
...
theme=Path(__file__).parent / "my_theme.css",
)

Thus, my naive assumption is that path_pkg_preset() does not correctly create the paths to the .scss files.

Best,
Tobi :upside_down_face:

1 Like

Hi again,

I have another question on this topic. Once I use the workaround with the absolute paths in _theme.py, I get a .css file and I can use this as

app_ui = ui.page_fluid(
...,
theme=Path(__file__).parent / "my_theme.css"
)

and my app looks accordingly. That's nice! :star_struck:

However, in the README on GitHub it says I can use .colors after importing the theme to theme my plots like:

from shinyswatch.theme import minty as shiny_theme

color = shiny_theme.colors.primary

Now, I wondering how to import my custom theme? What I tried, but what is not DRY, is:

from shinyswatch.theme import minty as shiny_theme

shiny_theme = shiny_theme.add_defaults(
    primary="#aa00ff",
    secondary="#bfff00",
)

color = shiny_theme.colors.primary

However, this did not change the color :slightly_frowning_face: Does someone know the solution to this issue? That would be great!

Best,
Tobi

Hi @thundert! Glad you figured out the path issues. (or if you haven't and I've misread the above thread, please feel free to open an issue on github at https://github.com/posit-dev/py-shiny/issues.)

In terms of the .color property of shinyswatch themes, unfortunately that's a feature specific to prebuilt shinyswatch themes. I think it's worth us considering doing this more generally. It doesn't work like this at the moment because there are many ways to update the Sass value of $primary and we wouldn't be able to capture them all. That said, it'd be reasonable to watch for colors being set via the .add_defaults() method. I opened an issue for this feature request: Capture theme color changes made via `.add_defaults()` · Issue #46 · posit-dev/py-shinyswatch · GitHub