Skip to main content

User-configurable themes for Gradio applications - unlimited custom themes via JSON configuration

Project description

gradio_themer

Static Badge

User-configurable themes for Gradio applications - unlimited custom themes via JSON configuration

Installation

pip install gradio_themer

Usage

"""
Gradio Themer - MCP Server Entry Point
Clean entry point that exposes only the 4 intended MCP tools.
"""

import os
import gradio as gr

# CRITICAL: Enable MCP server mode (as per GRADIO_MCP_HF_SPACES_GUIDE.md)
os.environ["GRADIO_MCP_SERVER"] = "True"

# Import the 4 MCP tools - these will be exposed by the MCP server
from mcp_tools import (
    setup_package,
    generate_theme,
    convert_css_to_theme,
    generate_app_code,
)

if __name__ == "__main__":
    try:
        import page

        # Add hidden MCP endpoints to the existing demo
        with page.demo:
            # Add hidden MCP tool endpoints (invisible to users, visible to MCP)

            # Hidden setup_package endpoint
            setup_btn = gr.Button("Setup Package", visible=False)
            setup_output = gr.JSON(visible=False)
            setup_btn.click(
                fn=setup_package, outputs=setup_output, api_name="setup_package"
            )

            # Hidden generate_theme endpoint
            theme_name_input = gr.Textbox(visible=False)
            primary_color_input = gr.Textbox(visible=False, value="#3b82f6")
            theme_style_input = gr.Textbox(visible=False, value="light")
            accent_color_input = gr.Textbox(visible=False, value="")
            generate_theme_btn = gr.Button("Generate Theme", visible=False)
            generate_theme_output = gr.JSON(visible=False)
            generate_theme_btn.click(
                fn=generate_theme,
                inputs=[
                    theme_name_input,
                    primary_color_input,
                    theme_style_input,
                    accent_color_input,
                ],
                outputs=generate_theme_output,
                api_name="generate_theme",
            )

            # Hidden convert_css_to_theme endpoint
            css_input = gr.Textbox(visible=False)
            convert_theme_name_input = gr.Textbox(
                visible=False, value="converted_theme"
            )
            user_token_input = gr.Textbox(visible=False, value="")
            model_choice_input = gr.Textbox(visible=False, value="qwen")
            convert_css_btn = gr.Button("Convert CSS", visible=False)
            convert_css_output = gr.Textbox(visible=False)
            convert_css_btn.click(
                fn=convert_css_to_theme,
                inputs=[
                    css_input,
                    convert_theme_name_input,
                    user_token_input,
                    model_choice_input,
                ],
                outputs=convert_css_output,
                api_name="convert_css_to_theme",
            )

            # Hidden generate_app_code endpoint
            app_theme_names_input = gr.Textbox(
                visible=False, value="ocean_breeze,sunset_orange"
            )
            app_title_input = gr.Textbox(visible=False, value="My Themed App")
            include_components_input = gr.Textbox(
                visible=False, value="button,textbox,slider"
            )
            generate_app_btn = gr.Button("Generate App", visible=False)
            generate_app_output = gr.Textbox(visible=False)
            generate_app_btn.click(
                fn=generate_app_code,
                inputs=[
                    app_theme_names_input,
                    app_title_input,
                    include_components_input,
                ],
                outputs=generate_app_output,
                api_name="generate_app_code",
            )

        # Launch the demo with MCP server enabled
        page.demo.launch(
            mcp_server=True,  # CRITICAL: Enable MCP server functionality
            server_name="0.0.0.0",
            server_port=7860,
            share=False,
            debug=True,
            allowed_paths=["./"],
        )

    except ImportError as e:
        print(f"❌ Error importing demo interface: {e}")
        print("Make sure page.py exists and contains the 'demo' variable")
        exit(1)
    except AttributeError as e:
        print(f"❌ Error accessing demo object: {e}")
        print("Make sure page.py contains a 'demo' variable")
        exit(1)

GradioThemer

Initialization

name type default description
value
typing.Union[
    typing.Dict[str, typing.Any], typing.Callable, NoneType
][
    typing.Dict[str, typing.Any][str, typing.Any],
    Callable,
    None,
]
None Default theme configuration. Should be a dict with 'themeInput', 'themeConfig', and 'generatedCSS' keys.
theme_config_path
typing.Optional[str][str, None]
None Path to user themes configuration file (JSON). If None, searches for common filenames.
label
str | None
None The label for this component, displayed above the component if `show_label` is `True`.
every
float | None
None Continously calls `value` to recalculate it if `value` is a function.
inputs
typing.Union[
    gradio.components.base.FormComponent,
    typing.Sequence[gradio.components.base.FormComponent],
    set[gradio.components.base.FormComponent],
    NoneType,
][
    gradio.components.base.FormComponent,
    typing.Sequence[gradio.components.base.FormComponent][
        gradio.components.base.FormComponent
    ],
    set[gradio.components.base.FormComponent],
    None,
]
None Components that are used as inputs to calculate `value` if `value` is a function.
show_label
bool | None
None If True, will display label.
scale
int | None
None Relative size compared to adjacent Components.
min_width
int
160 Minimum pixel width.
interactive
bool | None
None If True, will be rendered as an editable component.
visible
bool
True If False, component will be hidden.
elem_id
str | None
None An optional string that is assigned as the id of this component in the HTML DOM.
elem_classes
list[str] | str | None
None An optional list of strings that are assigned as the classes of this component in the HTML DOM.
render
bool
True If False, component will not render be rendered in the Blocks context.
key
int | str | None
None A unique key for this component.

Events

name description
change Triggered when the value of the GradioThemer changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See .input() for a listener that is only triggered by user input.
input This listener is triggered when the user changes the value of the GradioThemer.
submit This listener is triggered when the user presses the Enter key while the GradioThemer is focused.

User function

The impact on the users predict function varies depending on whether the component is used as an input or output for an event (or both).

  • When used as an Input, the component only impacts the input signature of the user function.
  • When used as an output, the component only impacts the return signature of the user function.

The code snippet below is accurate in cases where the component is used as both an input and an output.

  • As output: Is passed, passes the theme configuration as a dict into the function.
  • As input: Should return, expects a dict with theme configuration data.
def predict(
    value: typing.Optional[typing.Dict[str, typing.Any]][
   typing.Dict[str, typing.Any][str, typing.Any], None
]
) -> typing.Optional[typing.Dict[str, typing.Any]][
   typing.Dict[str, typing.Any][str, typing.Any], None
]:
    return value

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gradio_themer-0.1.0.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gradio_themer-0.1.0-py3-none-any.whl (27.6 kB view details)

Uploaded Python 3

File details

Details for the file gradio_themer-0.1.0.tar.gz.

File metadata

  • Download URL: gradio_themer-0.1.0.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.14

File hashes

Hashes for gradio_themer-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fabf7b9eafa31b5e86ec25e7852ebefcc1e3d8c63dc200628f249e6bc0ff0b3c
MD5 d0d6ab9b809852709e0c790e6f2f5299
BLAKE2b-256 7e3942ffaef69873ae45c1ede2bfaa3538e6d76bd24dba5a7034eaf572d0d8b1

See more details on using hashes here.

File details

Details for the file gradio_themer-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: gradio_themer-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 27.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.14

File hashes

Hashes for gradio_themer-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1d3f47db73cba32f5cd1a5bacb9fae1528510ff2c87e4b72aaaae4d66f0ad9c7
MD5 0fc4b81a50341d644864690ce9ac9870
BLAKE2b-256 069a78566d01150f35725d7ee429fccf20c07f8e893e983a4638749728a7fc81

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page