"""Vizro Example Gallery"""
from typing import Literal, Optional
import dash
from dash import get_asset_url
import dash_bootstrap_components as dbc
import flask_talisman
import vizro.models as vm
from add_security_headers import set_security_headers_config
from dash import dcc, html
from vizro import Vizro
from werkzeug.middleware.proxy_fix import ProxyFix
try:
from pydantic.v1 import Field
except ImportError: # pragma: no cov
from pydantic import Field
class Image(vm.VizroBaseModel):
type: Literal["image"] = "image"
src: str
href: Optional[str] = None
def build(self):
if self.href:
return html.A(html.Img(id=self.id, src=dash.get_asset_url(self.src), className="image"), href=self.href, target="_blank")
else:
return html.Img(id=self.id, src=dash.get_asset_url(self.src), className="image")
class Markdown(vm.VizroBaseModel):
"""Markdown component."""
type: Literal["markdown"] = "markdown"
text: str = Field(
...,
description="Markdown string to create card title/text that should adhere to the CommonMark Spec.",
)
classname: str = ""
def build(self):
"""Returns a markdown component with an optional classname."""
return dcc.Markdown(
id=self.id,
children=self.text,
dangerously_allow_html=False,
className=self.classname,
)
class FlexContainer(vm.Container):
"""Custom flex `Container`."""
type: Literal["flex_container"] = "flex_container"
title: str = None # Title exists in vm.Container but we don't want to use it here.
def build(self):
"""Returns a flex container."""
return html.Div(
id=self.id,
children=[component.build() for component in self.components],
className="flex-container",
)
vm.Page.add_type("components", FlexContainer)
vm.Container.add_type("components", Image)
FlexContainer.add_type("components", Markdown)
## PAGE
page = vm.Page(
title="A toolkit for creating modular data visualization applications",
components=[
FlexContainer(
components=[
Markdown(
text="""

# Welcome to the Vizro examples gallery
### where we showcase a range of Vizro dashboards for you to try out
#### What is Vizro? It's an open source Python framework for creating modular data visualization applications.
""",
classname="info-text",
),
vm.Container(
title="",
layout=vm.Layout(grid=[[0, 1], [0, 2], [0, 3]], col_gap="80px"),
components=[
Image(src="images/general/vizro_spash_teaser.gif"),
vm.Card(
text="""

### Live Demo
A Vizro example dashboard in practice.
""",
href="https://huggingface.co/spaces/vizro/demo-kpi",
),
vm.Card(
text="""

### Gallery
Check out all our other demos on Hugging Face.
""",
href="https://huggingface.co/vizro",
),
vm.Card(
text="""

### py.cafe
Try out Vizro live - without the need to install anything!
""",
href="https://py.cafe/snippet/vizro/v1",
),
],
),
Markdown(
text="""## And now there's Vizro-AI: Vizro enhanced with genAI.""",
classname="info-text",
),
vm.Container(
title="",
layout=vm.Layout(grid=[[1, 0], [2, 0], [-1, 0]], col_gap="80px"),
components=[
Image(src="images/general/readme_animation.gif"),
vm.Card(
text="""

### Live Chart Creation
Try out Vizro-AI charts live.
""",
href="https://py.cafe/app/vizro-official/vizro-ai-charts",
),
vm.Card(
text="""

### Live Dashboard Creation
Try out Vizro-AI dashboards live.
""",
href="https://colab.research.google.com/github/mckinsey/vizro/blob/main/vizro-ai/examples/dashboard_by_vizro_ai.ipynb",
),
],
),
Markdown(
text="""
## Introducing our visual vocabulary: A collection of beautiful charts
#### learn when to use them and get sample code to create them in Plotly and Vizro
""",
classname="info-text",
),
vm.Container(
title="",
components=[
Image(src="images/general/vizro-visual-vocabulary.gif", href="https://huggingface.co/spaces/vizro/demo-visual-vocabulary"),
],
),
]
),
],
)
dashboard = vm.Dashboard(pages=[page], title="Vizro")
app = Vizro(assets_folder="./assets").build(dashboard)
app.dash.layout.children.append(
html.Div(
[
dbc.NavLink("Contact us", href="https://github.com/mckinsey/vizro/issues"),
dbc.NavLink("GitHub", href="https://github.com/mckinsey/vizro"),
dbc.NavLink("Docs", href="https://vizro.readthedocs.io/en/stable/"),
html.Div(
[
"Made using ",
html.Img(
src=get_asset_url("logo.svg"), id="banner", alt="Vizro logo"
),
"vizro",
],
),
],
className="anchor-container",
)
)
server = app.dash.server
server.wsgi_app = ProxyFix(
server.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1, x_port=1
)
# ADD SECURITY HEADERS
csp = {
"default-src": ["'self'", "https://cdn.plot.ly/world_110m.json", "data:"],
"img-src": ["'self'", "data:", "blob:"],
"font-src": [
"'self'",
"fonts.gstatic.com",
"https://vizro.alpha.mckinsey.digital",
"https://vizro.mckinsey.com/",
"data:",
],
"style-src": [
"'self'",
"'unsafe-inline'",
"https://fonts.googleapis.com",
"https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css",
],
"script-src": [
"'self'",
"'unsafe-inline'",
"'unsafe-eval'",
"'sha256-PLASfTOXCNC/zzYs5pfSve2C3jtMetNBZ+OTvwQg4ME='",
],
}
http_security_headers_config = {
"force_https": True,
"content_security_policy": csp,
}
http_security_headers_config = set_security_headers_config(
headers_config=http_security_headers_config, app=app.dash
)
flask_talisman.Talisman(server, **http_security_headers_config) # type: ignore
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7065)