Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tidy] Bump to Pydantic V2 #917

Open
wants to merge 43 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6f11390
Run bump-pydantic
maxschulz-COL Nov 12, 2024
2cdb045
Un-v1 actions.py
maxschulz-COL Nov 12, 2024
bbaeae5
Do not fail on warnings
maxschulz-COL Nov 12, 2024
b90f165
Run bump-pydantic
maxschulz-COL Nov 12, 2024
7ee047c
Un-v1 actions.py
maxschulz-COL Nov 12, 2024
b47fd4b
Do not fail on warnings
maxschulz-COL Nov 12, 2024
48957af
Merge branch 'feature/pydantic_v2' of github.com:mckinsey/vizro into …
maxschulz-COL Nov 13, 2024
28b3ffe
Refactor action and component models to use SkipJsonSchema for Captur…
maxschulz-COL Nov 13, 2024
15aba94
Refactor model forward references to use model_rebuild
maxschulz-COL Nov 13, 2024
c77df9b
Refactor id validator to field_validator
maxschulz-COL Nov 13, 2024
554afd3
Refactor validator usage in Dashboard model for Pydantic v2 compatibi…
maxschulz-COL Nov 13, 2024
ffef6dc
Refactor layout model to use field_validator and update regex to patt…
maxschulz-COL Nov 13, 2024
03f9b09
Refactor imports in various models to remove Pydantic v1 compatibilit…
maxschulz-COL Nov 13, 2024
4094e32
Remove Pydantic v1 compatibility code from test files and update impo…
maxschulz-COL Nov 13, 2024
b0f79f7
Refactor Parameter model to use AfterValidator via Annotated for targ…
maxschulz-COL Nov 14, 2024
a15e325
Refactor accordion model to remove Pydantic v1 compatibility code and…
maxschulz-COL Nov 15, 2024
b7dcd67
Refactor Dashboard and Navigation models to use Optional for nullable…
maxschulz-COL Nov 15, 2024
3663293
Refactor Page model to use Optional for layout field and update Pydan…
maxschulz-COL Nov 15, 2024
5052693
Refactor form, container, tabs, and page models to use conlist and Be…
maxschulz-COL Nov 15, 2024
34651ae
Enable CapturedCallable as type
maxschulz-COL Nov 22, 2024
e93d6da
Fix Parameter model twith nested Annotated and AfterValidator to vali…
maxschulz-COL Nov 22, 2024
180e75e
Merge branch 'main' into feature/pydantic_v2
maxschulz-COL Nov 22, 2024
7158c01
Refactor remaining v1 out of code base
maxschulz-COL Nov 22, 2024
286b039
Fix unit tests for Action and Checklist
maxschulz-COL Dec 2, 2024
335c0b8
Fix form component unit tests
maxschulz-COL Dec 3, 2024
4af444c
Merge branch 'main' into feature/pydantic_v2
maxschulz-COL Dec 3, 2024
6b77fbf
Fix more form component unit tests
maxschulz-COL Dec 3, 2024
8bff295
Fix remaining unit tests plus the Filter optional argument
maxschulz-COL Dec 3, 2024
f05c474
Fix remaining unit tests
maxschulz-COL Dec 3, 2024
906a448
Align unit tests for CapturedCallable with new way of validating it
maxschulz-COL Dec 3, 2024
ee6722e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Dec 3, 2024
46035b3
Refactor BaseModel.add_type
maxschulz-COL Dec 6, 2024
d6b11d9
Fix unit tests for types
maxschulz-COL Dec 6, 2024
a64d2cc
Refactor code to allow `_to_python` in V2
maxschulz-COL Jan 16, 2025
3493a40
Finalise dashboard model file
maxschulz-COL Jan 16, 2025
4fc0c3d
Finalise page, layout and container models
maxschulz-COL Jan 16, 2025
5c2f7b9
Finalising the component models
maxschulz-COL Jan 16, 2025
6bbf1b2
Finalise form component models (Checklist, Dropdown, Radio Items)
maxschulz-COL Jan 17, 2025
3dd2eb9
Finalise form model (DatePicker, RangeSlider, Slider
maxschulz-COL Jan 17, 2025
e381c0b
Finalise accordion
maxschulz-COL Jan 17, 2025
8291f82
Finalise filter
maxschulz-COL Jan 17, 2025
bf8534d
Finalise remaining models (Navigation, NavBar and NavLink)
maxschulz-COL Jan 17, 2025
28a38b5
Clean up all remains
maxschulz-COL Jan 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions vizro-core/docs/pages/user-guides/custom-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,18 +402,12 @@ As mentioned above, custom components can trigger action. To enable the custom c

=== "app.py"
```py
from typing import Literal
from typing import Annotated, Literal

import dash_bootstrap_components as dbc
import vizro.models as vm
from dash import html
from pydantic import AfterValidator, Field, PlainSerializer
from vizro import Vizro

try:
from pydantic.v1 import Field, PrivateAttr
except ImportError:
from pydantic import PrivateAttr

from vizro.models import Action
from vizro.models._action._actions_chain import _action_validator_factory
from vizro.models.types import capture
Expand All @@ -423,9 +417,14 @@ As mentioned above, custom components can trigger action. To enable the custom c
class Carousel(vm.VizroBaseModel):
type: Literal["carousel"] = "carousel"
items: list
actions: list[Action] = []
# Here we set the action so a change in the active_index property of the custom component triggers the action
_set_actions = _action_validator_factory("active_index")
actions: Annotated[
list[Action],
# Here we set the action so a change in the active_index property of the custom component triggers the action
AfterValidator(_action_validator_factory("active_index")),
# Here we tell the serializer to only serialize the actions field
PlainSerializer(lambda x: x[0].actions),
Field(default=[]),
]

def build(self):
return dbc.Carousel(
Expand All @@ -437,6 +436,7 @@ As mentioned above, custom components can trigger action. To enable the custom c
# 2. Add new components to expected type - here the selector of the parent components
vm.Page.add_type("components", Carousel)


# 3. Create custom action
@capture("action")
def slide_next_card(active_index):
Expand All @@ -445,6 +445,7 @@ As mentioned above, custom components can trigger action. To enable the custom c

return "First slide"


page = vm.Page(
title="Custom Component",
components=[
Expand All @@ -459,9 +460,9 @@ As mentioned above, custom components can trigger action. To enable the custom c
vm.Action(
function=slide_next_card(),
inputs=["carousel.active_index"],
outputs=["carousel-card.children"]
outputs=["carousel-card.children"],
)
]
],
),
],
)
Expand Down
112 changes: 56 additions & 56 deletions vizro-core/examples/dev/app.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Example app to show all features of Vizro."""

from time import sleep
from typing import Literal, Optional
from typing import Optional

import dash_bootstrap_components as dbc
import pandas as pd
Expand Down Expand Up @@ -492,7 +492,7 @@
column="size",
selector=vm.Slider(title="Slider (Tips - size)", step=1, value=2),
),
vm.Filter(targets=["graph-stocks"], column="date", selector=vm.DatePicker(title="Date Picker (Stocks - date)")),
# vm.Filter(targets=["graph-stocks"], column="date", selector=vm.DatePicker(title="Date Picker (Stocks - date)")),
],
)

Expand Down Expand Up @@ -643,65 +643,65 @@ def my_custom_table(data_frame=None, chosen_columns: Optional[list[str]] = None)

# CUSTOM COMPONENTS -------------------------------------------------------------
# 1. Extend existing components
class TooltipNonCrossRangeSlider(vm.RangeSlider):
"""Custom numeric multi-selector `TooltipNonCrossRangeSlider`."""
# class TooltipNonCrossRangeSlider(vm.RangeSlider):
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note so self, check on this

# """Custom numeric multi-selector `TooltipNonCrossRangeSlider`."""

type: Literal["other_range_slider"] = "other_range_slider"
# type: Literal["other_range_slider"] = "other_range_slider"

def build(self):
"""Extend existing component by calling the super build and update properties."""
range_slider_build_obj = super().build()
range_slider_build_obj[self.id].allowCross = False
range_slider_build_obj[self.id].tooltip = {"always_visible": True, "placement": "bottom"}
return range_slider_build_obj
# def build(self):
# """Extend existing component by calling the super build and update properties."""
# range_slider_build_obj = super().build()
# range_slider_build_obj[self.id].allowCross = False
# range_slider_build_obj[self.id].tooltip = {"always_visible": True, "placement": "bottom"}
# return range_slider_build_obj


vm.Filter.add_type("selector", TooltipNonCrossRangeSlider)
# vm.Filter.add_type("selector", TooltipNonCrossRangeSlider)


# 2. Create new custom component
class Jumbotron(vm.VizroBaseModel):
"""New custom component `Jumbotron`."""

type: Literal["jumbotron"] = "jumbotron"
title: str
subtitle: str
text: str

def build(self):
"""Build the new component based on Dash components."""
return html.Div([html.H2(self.title), html.H3(self.subtitle), html.P(self.text)])


vm.Page.add_type("components", Jumbotron)

custom_components = vm.Page(
title="Custom Components",
components=[
Jumbotron(
title="Custom component based on new creation",
subtitle="This is a subtitle to summarize some content.",
text="This is the main body of text of the Jumbotron.",
),
vm.Graph(
id="for_custom_chart",
figure=px.scatter(
iris,
title="Iris Dataset",
x="sepal_length",
y="petal_width",
color="sepal_width",
),
),
],
controls=[
vm.Filter(
column="sepal_length",
targets=["for_custom_chart"],
selector=TooltipNonCrossRangeSlider(title="Custom component based on extension"),
)
],
)
# class Jumbotron(vm.VizroBaseModel):
# """New custom component `Jumbotron`."""

# type: Literal["jumbotron"] = "jumbotron"
# title: str
# subtitle: str
# text: str

# def build(self):
# """Build the new component based on Dash components."""
# return html.Div([html.H2(self.title), html.H3(self.subtitle), html.P(self.text)])


# vm.Page.add_type("components", Jumbotron)

# custom_components = vm.Page(
# title="Custom Components",
# components=[
# Jumbotron(
# title="Custom component based on new creation",
# subtitle="This is a subtitle to summarize some content.",
# text="This is the main body of text of the Jumbotron.",
# ),
# vm.Graph(
# id="for_custom_chart",
# figure=px.scatter(
# iris,
# title="Iris Dataset",
# x="sepal_length",
# y="petal_width",
# color="sepal_width",
# ),
# ),
# ],
# controls=[
# vm.Filter(
# column="sepal_length",
# targets=["for_custom_chart"],
# selector=TooltipNonCrossRangeSlider(title="Custom component based on extension"),
# )
# ],
# )


# CUSTOM ACTIONS ---------------------------------------------------------------
Expand Down Expand Up @@ -778,7 +778,7 @@ def multiple_cards(data_frame: pd.DataFrame, n_rows: Optional[int] = 1) -> html.
components = [graphs, ag_grid, table, cards, figure, button, containers, tabs]
controls = [filters, parameters, selectors]
actions = [export_data_action, chart_interaction]
extensions = [custom_charts, custom_tables, custom_components, custom_actions, custom_figures]
extensions = [custom_charts, custom_tables, custom_actions, custom_figures] # custom_components

dashboard = vm.Dashboard(
title="Vizro Features",
Expand All @@ -805,7 +805,7 @@ def multiple_cards(data_frame: pd.DataFrame, n_rows: Optional[int] = 1) -> html.
"Extensions": [
"Custom Charts",
"Custom Tables",
"Custom Components",
# "Custom Components",
"Custom Actions",
"Custom Figures",
],
Expand Down
67 changes: 15 additions & 52 deletions vizro-core/examples/scratch_dev/app.py
Original file line number Diff line number Diff line change
@@ -1,69 +1,32 @@
from typing import List, Literal

from dash import html

import vizro.models as vm
import vizro.plotly.express as px
from dash import html
from vizro import Vizro
from vizro.models.types import ControlType

df_gapminder = px.data.gapminder()


class ControlGroup(vm.VizroBaseModel):
"""Container to group controls."""
from vizro._themes._color_values import COLORS
from vizro.actions import export_data

type: Literal["control_group"] = "control_group"
title: str
controls: List[ControlType] = []
df = px.data.iris()

def build(self):
return html.Div(
[html.H4(self.title), html.Hr()] + [control.build() for control in self.controls],
)


vm.Page.add_type("controls", ControlGroup)

page1 = vm.Page(
title="Relationship Analysis",
page = vm.Page(
title="Page 1",
components=[
vm.Graph(id="scatter", figure=px.scatter(df_gapminder, x="gdpPercap", y="lifeExp", size="pop")),
],
controls=[
ControlGroup(
title="Group A",
controls=[
vm.Parameter(
id="this",
targets=["scatter.x"],
selector=vm.Dropdown(
options=["lifeExp", "gdpPercap", "pop"], multi=False, value="gdpPercap", title="Choose x-axis"
),
),
vm.Parameter(
targets=["scatter.y"],
selector=vm.Dropdown(
options=["lifeExp", "gdpPercap", "pop"], multi=False, value="lifeExp", title="Choose y-axis"
),
),
],
),
ControlGroup(
title="Group B",
controls=[
vm.Parameter(
targets=["scatter.size"],
selector=vm.Dropdown(
options=["lifeExp", "gdpPercap", "pop"], multi=False, value="pop", title="Choose bubble size"
),
)
vm.Graph(figure=px.bar(df, x="sepal_width", y="sepal_length")),
vm.Button(
text="Export data",
actions=[
vm.Action(function=export_data()),
vm.Action(function=export_data()),
],
),
],
)

dashboard = vm.Dashboard(pages=[page1])
dashboard = vm.Dashboard(pages=[page])

if __name__ == "__main__":
Vizro().build(dashboard).run()
# print(dashboard._to_python())
# print(dashboard.model_dump(context={"add_name": True}))
9 changes: 2 additions & 7 deletions vizro-core/examples/visual-vocabulary/custom_components.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
"""Contains custom components used inside the dashboard."""

from typing import Literal
from urllib.parse import quote

import dash_bootstrap_components as dbc
import vizro.models as vm
from dash import dcc, html

try:
from pydantic.v1 import Field
except ImportError: # pragma: no cov
from pydantic import Field

from urllib.parse import quote
from pydantic import Field


class CodeClipboard(vm.VizroBaseModel):
Expand Down
2 changes: 1 addition & 1 deletion vizro-core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ addopts = [
"--import-mode=importlib"
]
filterwarnings = [
"error",
# "error",
# Ignore until pandas is made compatible with Python 3.12:
"ignore:.*utcfromtimestamp:DeprecationWarning",
# Ignore until pandas 3 is released:
Expand Down
28 changes: 7 additions & 21 deletions vizro-core/src/vizro/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,13 @@
from ._layout import Layout
from ._page import Page

Tabs.update_forward_refs(Container=Container)
Container.update_forward_refs(
AgGrid=AgGrid, Button=Button, Card=Card, Figure=Figure, Graph=Graph, Layout=Layout, Table=Table, Tabs=Tabs
)
Page.update_forward_refs(
Accordion=Accordion,
AgGrid=AgGrid,
Button=Button,
Card=Card,
Container=Container,
Figure=Figure,
Filter=Filter,
Graph=Graph,
Parameter=Parameter,
Table=Table,
Tabs=Tabs,
)
Navigation.update_forward_refs(Accordion=Accordion, NavBar=NavBar, NavLink=NavLink)
Dashboard.update_forward_refs(Page=Page, Navigation=Navigation)
NavBar.update_forward_refs(NavLink=NavLink)
NavLink.update_forward_refs(Accordion=Accordion)
Tabs.model_rebuild()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are removed entirely I presume things don't work?

Container.model_rebuild()
Page.model_rebuild()
Navigation.model_rebuild()
Dashboard.model_rebuild()
NavBar.model_rebuild()
NavLink.model_rebuild()

__all__ = [
"Accordion",
Expand Down
Loading
Loading