posit-dev / py-shiny-site

The documentation website for Shiny for Python
https://shiny.posit.co/py/
MIT License
17 stars 17 forks source link

TypeError: Invalid type for attribute: <class 'htmltools._core.TagList'>.Consider calling str() on this value before treating it as a tag attribute. #225

Closed Jessica-Crystal closed 1 month ago

Jessica-Crystal commented 1 month ago

I got this error when creating a shiny app with python. After ui.sidebar with all input, I added ui.panel_fixed(output_widget('some_plot')). I don't understand what's happening however I've checked many times, and everything was correct.

gadenbuie commented 1 month ago

Can you please share a small app that reproduces your issue? You can use https://shinylive.io/py/ as a quick way to write and share the app.

Jessica-Crystal commented 1 month ago
from shiny import App, ui, session, Outputs, Inputs
from shinywidgets import output_widget, render_widget
from pathlib import Path
TITLE = "Baobab"
page = ui.tags.head(
    ui.tags.link(rel="stylesheet",type="text/css",href="style.css")
)

app_ui = ui.page_navbar( 
    ui.nav_panel("Baobab",
    ui.layout_sidebar(
        sidebar=ui.sidebar(
            ui.input_file('data','Please upload csv file', accept=['.csv']),
            ui.input_date('start','Start', value='1980-01-01'),
            ui.input_date('end', 'End', value='2024-05-29'),

        ), 
         main=ui.panel_fixed(
              output_widget("plot", width="auto",height="auto"),
         )
    )

 ),

ui.nav_panel('Machine Learning', 
             ui.layout_sidebar(
                 sidebar=ui.sidebar(
                     ui.input_select('select', 'Select', ['supervised','unsupervised','deep learning']),
        )

      )
    ),   
    #id="page", 
    title = ui.tags.div(#ui.img(src='baobab.jpg', height="40px", style="margin:5px;"),
                        ui.h5(""+TITLE),
                        style="display:flex;-webkit-filter:drop-shadow(2px 2px 2px #222)"),
                        bg="#0062cc",
                        inverse=True,
                        header=page 
) 

www_dir = Path(__file__).parent / "www"
def server(input, output, session):
    pass

app = App(app_ui, server, static_assets=www_dir)
Jessica-Crystal commented 1 month ago

I want to make a plot on a sidebar but when I run only this code it I got TypeError: Invalid type for attribute: <class 'htmltools._core.TagList'>.Consider calling str() on this value before treating it as a tag attribute.

gadenbuie commented 1 month ago

You're very close! You just need to make two small adjustments.

    ui.nav_panel(
        "Baobab",
        ui.layout_sidebar(
-           sidebar=ui.sidebar(
+           ui.sidebar(
                ui.input_file("data", "Please upload csv file", accept=[".csv"]),
                ui.input_date("start", "Start", value="1980-01-01"),
                ui.input_date("end", "End", value="2024-05-29"),
            ),
-           main=ui.panel_fixed(
+           ui.panel_fixed(
                output_widget("plot", width="auto", height="auto"),
            ),
        ),
    ),

First, instead of main=ui.panel_fixed(), pass ui.panel_fixed() as a direct child of ui.layout_sidebar(). ui.layout_sidebar() doesn't require a main argument, instead all of its unnamed children are added directly to the main area. When you use main=, it's being treated as an HTML attribute to be added to the layout container.

Second, the first argument of ui.layout_sidebar() should be the sidebar, which should be passed positionally, i.e. without the sidebar=.

Jessica-Crystal commented 1 month ago

Thank you so much! It works now!