Skip to content

Commit

Permalink
Merge branch 'main' into docs/add-dash-enterprise
Browse files Browse the repository at this point in the history
  • Loading branch information
maxschulz-COL authored Feb 7, 2025
2 parents 2ee2737 + 985d15e commit bac91a2
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Highlights ✨
- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Removed
- A bullet item for the Removed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Added
- A bullet item for the Added category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Changed
- A bullet item for the Changed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Deprecated
- A bullet item for the Deprecated category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Fixed
- A bullet item for the Fixed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Security
- A bullet item for the Security category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
A new scriv changelog fragment.
Uncomment the section that is right (remove the HTML comment wrapper).
-->

<!--
### Highlights ✨
- A bullet item for the Highlights ✨ category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Removed
- A bullet item for the Removed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Added
- A bullet item for the Added category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Changed
- A bullet item for the Changed category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
<!--
### Deprecated
- A bullet item for the Deprecated category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->

### Fixed

- Fix a bug where `add_type` would raise an error if the `type` had already been added. ([#999](https://github.com/mckinsey/vizro/pull/999))


<!--
### Security
- A bullet item for the Security category with a link to the relevant PR at the end of your entry, e.g. Enable feature XXX. ([#1](https://github.com/mckinsey/vizro/pull/1))
-->
4 changes: 2 additions & 2 deletions vizro-core/docs/pages/user-guides/custom-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,8 @@ As mentioned above, custom components can trigger action. To enable the custom c
Carousel(
id="carousel",
items=[
{"key": "1", "src": "path_to_your_image"},
{"key": "2", "src": "path_to_your_image"},
{"key": "1", "src": "assets/slide_1.jpg"},
{"key": "2", "src": "assets/slide_2.jpg"},
],
actions=[
vm.Action(
Expand Down
70 changes: 3 additions & 67 deletions vizro-core/examples/scratch_dev/app.py
Original file line number Diff line number Diff line change
@@ -1,75 +1,11 @@
"""Dev app to try things out."""
"""Test app"""

import pandas as pd
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro

# For more information, refer to the API reference for kpi_card and kpi_card_reference
from vizro.figures import kpi_card, kpi_card_reference

df_kpi = pd.DataFrame({"Actual": [100, 200, 700], "Reference": [100, 300, 500], "Category": ["A", "B", "C"]})

example_cards = [
kpi_card(data_frame=df_kpi, value_column="Actual", title="KPI with value"),
kpi_card(data_frame=df_kpi, value_column="Actual", title="KPI with aggregation", agg_func="median"),
kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with formatting",
value_format="${value:.2f}",
),
kpi_card(
data_frame=df_kpi,
value_column="Actual",
title="KPI with icon",
icon="shopping_cart",
),
]

example_reference_cards = [
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference (pos)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
agg_func="median",
title="KPI reference (neg)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference with formatting",
value_format="{value:.2f}€",
reference_format="{delta:+.2f}€ vs. last year ({reference:.2f}€)",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference with icon",
icon="shopping_cart",
),
kpi_card_reference(
data_frame=df_kpi,
value_column="Actual",
reference_column="Reference",
title="KPI reference (reverse color)",
reverse_color=True,
),
]

# Create a layout with four rows and columns. The KPI cards are positioned in the first nine cells, while the remaining cells are empty.
page = vm.Page(
title="KPI cards",
layout=vm.Layout(grid=[[0, 1, 2, 3], [4, 5, 6, 7], [8, -1, -1, -1], [-1, -1, -1, -1]]),
components=[vm.Figure(figure=figure) for figure in example_cards + example_reference_cards],
controls=[vm.Filter(column="Category")],
title="foo", components=[vm.Graph(figure=px.scatter(data_frame=px.data.iris(), x="sepal_width", y="sepal_length"))]
)

dashboard = vm.Dashboard(pages=[page])
Expand Down
14 changes: 12 additions & 2 deletions vizro-core/src/vizro/models/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,17 @@ def _extract_captured_callable_data_info() -> set[str]:

def _add_type_to_union(union: type[Any], new_type: type[Any]): # TODO[mypy]: not sure how to type the return type
args = get_args(union)
return Union[args + (new_type,)] # noqa: RUF005 #as long as we support Python 3.9, we can't use the new syntax
all_types = args + (new_type,) # noqa: RUF005 #as long as we support Python 3.9, we can't use the new syntax
# The below removes duplicates by type, which would trigger a pydantic error (TypeError: Value 'xxx'
# for discriminator 'type' mapped to multiple choices) otherwise.
# We get the type value by accessing the type objects model_fields attribute, which is a dict of the fields
# of the model. Since in Vizro we always define the type with a default value (and don't change it), the default
# value of the type field is the only possible `type`.
# Last added type will be the one that is kept - this is replicating V1 behavior that would other raise an error
# in V2, and thus we are defining NEW behavior here. This works by using .values(), which extract values by
# insertion order (since Python 3.7), thus the last added type will be the one that is kept.
unique_types = tuple({t.model_fields["type"].default: t for t in all_types}.values())
return Union[unique_types]


def _add_type_to_annotated_union(union, new_type: type[Any]): # TODO[mypy]: not sure how to type the return type
Expand Down Expand Up @@ -256,7 +266,7 @@ def add_type(cls, field_name: str, new_type: type[Any]):
if _is_discriminated_union_via_field_info(field)
else _add_type_to_annotated_union_if_found(old_type, new_type, field_name)
)
field = cls.model_fields[field_name] = FieldInfo.merge_field_infos(field, annotation=new_annotation)
cls.model_fields[field_name] = FieldInfo.merge_field_infos(field, annotation=new_annotation)

# We need to resolve all ForwardRefs again e.g. in the case of Page, which requires update_forward_refs in
# vizro.models. The vm.__dict__.copy() is inspired by pydantic's own implementation of update_forward_refs and
Expand Down
23 changes: 23 additions & 0 deletions vizro-core/tests/unit/vizro/models/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,3 +600,26 @@ def test_to_python_complete_dashboard(self, complete_dashboard):
# Test more complete and nested model
result = complete_dashboard._to_python(extra_imports={"from typing import Optional"})
assert result == expected_complete_dashboard


class TestAddingDuplicateDiscriminator:
def test_add_same_model(self, Parent):
"""Test whether adding same model re-defined avoids pydantic discriminator error."""

class MultipleChild(vm.VizroBaseModel):
type: Literal["derived"] = "derived"

Parent.add_type("child", MultipleChild)

class MultipleChild(vm.VizroBaseModel):
type: Literal["derived"] = "derived"

Parent.add_type("child", MultipleChild)

def test_add_duplicate_type(self, Parent):
"""Test whether adding model of same type avoids pydantic discriminator error."""

class MultipleChild(ChildX):
pass

Parent.add_type("child", MultipleChild)

0 comments on commit bac91a2

Please sign in to comment.