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

Custom action on Page loading #643

Closed
1 task done
BalaNagendraReddy opened this issue Aug 21, 2024 · 5 comments
Closed
1 task done

Custom action on Page loading #643

BalaNagendraReddy opened this issue Aug 21, 2024 · 5 comments
Assignees
Labels
General Question ❓ Issue contains a general question

Comments

@BalaNagendraReddy
Copy link

Question

Hi Team,

I'm currently working on a multipage app using the vizro library and I need to implement a feature that extracts file names from MongoDB when a specific page is loaded. The goal is to dynamically load the page with all the extracted file names based on the output of a function.

Objective: I need to ensure that when the page is opened, the extract_files_from_db function is called, and the page content is dynamically updated with the file names extracted from MongoDB.

Challenges: I am not sure how to integrate the function with the page loading process or how to update the page content dynamically based on the result.
Could you please provide guidance on how to:

Trigger the extract_files_from_db function when the page loads.
Update the page content with the extracted file names.

Any assistance or examples on how to achieve this with the vizro library would be greatly appreciated.

Code/Examples

import vizro.models as vm
from time import sleep

def extract_files_from_db():
    """Custom action."""
    print("Extracting files from database...")
    sleep(5)
    print("Files extracted.")

my_page = vm.Page(
    title="Mytitle",
    path="path1/path12",
    components=[
        # Action to be triggered when the page is loaded
        vm.Card(text="My text here"),
    ],
)

Package Version: vizro==0.1.18

Which package?

vizro

Code of Conduct

@BalaNagendraReddy BalaNagendraReddy added General Question ❓ Issue contains a general question Needs triage 🔍 Issue needs triaging labels Aug 21, 2024
@maxschulz-COL maxschulz-COL removed the Needs triage 🔍 Issue needs triaging label Aug 21, 2024
@petar-qb petar-qb self-assigned this Aug 21, 2024
@petar-qb
Copy link
Contributor

Hi @BalaNagendraReddy and thanks for the great question. 🚀

Triggering custom actions when the page is loaded, natively through the Vizro configuration, is currently unavailable feature and will be available once this PR become merged. As it doesn't look like this PR is going to be merged soon, I'm posting two Vizro examples on how this already could be achieved (in less native Vizro way).

The first example solves the problem by utilising dash callbacks.

"""Dev app to try things out."""
from time import sleep
from dash import callback, Input, Output

from vizro import Vizro
import vizro.models as vm


MONGO_DB_FILES = ["file_1.csv", "file_2.csv", "file_3.csv", "file_4.csv"]


def extract_mongo_db_files():
    print("Extracting files from database...")
    sleep(2)
    print(f"Files extracted:\n{MONGO_DB_FILES}")
    return MONGO_DB_FILES


home_page = vm.Page(
    title="Home Page",
    components=[vm.Card(text="Go to the 'Mongo Files Page' to see the extracted files.")],
)

mongo_files_page = vm.Page(
    title="Mongo Files Page",
    path="path1/path2",
    id="mongo_files_page_id",
    components=[
        vm.Card(
            id="my_card_id",
            text=""
        ),
    ],
)


@callback(
    Output("my_card_id", "children"),
    Input(f'on_page_load_action_trigger_{mongo_files_page.id}', "data"),
)
def update_my_card_id(data):
    files = extract_mongo_db_files()
    return f"Extracted files: {files}"


dashboard = vm.Dashboard(pages=[home_page, mongo_files_page])

if __name__ == "__main__":
    Vizro().build(dashboard).run()

The second example solves the same problem in fully native Vizro way.

Useful references:

  • More about static/dynamic Vizro data you can find here.
  • More about how to speed-up you Vizro app significantly if the dynamic data is used you can find here.
  • More about custom figures and how to make any component to depend on the data that's loaded you can find here.
"""Dev app to try things out."""
import pandas as pd
from time import sleep
from dash import dcc
import dash_bootstrap_components as dbc

from vizro import Vizro
import vizro.models as vm
import vizro.plotly.express as px
from vizro.managers import data_manager
from vizro.models.types import capture
from vizro.tables import dash_ag_grid


MONGO_DB_FILES = ["file_1.csv", "file_2.csv", "file_3.csv", "file_4.csv"]


# TODO - DOCS: More about how to use Vizro cache to speed up your app -> https://vizro.readthedocs.io/en/stable/pages/user-guides/data/#configure-cache
def extract_mongo_db_files():
    print("Extracting files from database...")
    sleep(1)
    print(f"Files extracted:\n{MONGO_DB_FILES}")
    return pd.DataFrame({"files": MONGO_DB_FILES})


data_manager["my_data"] = extract_mongo_db_files


# TODO - DOCS: More about custom figures -> https://vizro.readthedocs.io/en/stable/pages/user-guides/custom-figures/
@capture("figure")
def my_responsive_card(data_frame, id, column):
    return dbc.Card(
        id=id,
        children=f"Files extracted:\n{list(data_frame[column].values)}",
    )


@capture("figure")
def my_responsive_dropdown(data_frame, id, column):
    options = list(data_frame[column].values)

    return dcc.Dropdown(
        id=id,
        options=options,
        value=options[0] if options else None,
        multi=False,
    )


home_page = vm.Page(
    title="Home Page",
    components=[vm.Card(text="Go to the 'Mongo Files Page' to see the extracted files.")],
)


mongo_files_page = vm.Page(
    title="Mongo Files Page",
    path="path1/path2",
    id="mongo_files_page_id",
    components=[
        vm.Figure(
            figure=my_responsive_card(
                data_frame="my_data",
                id="my_card_id",
                column="files",
            )
        ),
        vm.Figure(
            figure=my_responsive_dropdown(
                data_frame="my_data",
                id="my_dropdown_id",
                column="files",
            )
        ),
        vm.AgGrid(
            id="my_ag_grid_id",
            figure=dash_ag_grid(data_frame="my_data")
        ),
    ],
)


dashboard = vm.Dashboard(pages=[home_page, mongo_files_page])

if __name__ == "__main__":
    Vizro().build(dashboard).run()

@maxschulz-COL maxschulz-COL added the Custom Components 🚀 Issue contains a custom component request label Aug 21, 2024
@BalaNagendraReddy
Copy link
Author

Hi @petar-qb,

Thank you for your prompt response.

The function is working, but I noticed that with the second method, the function executes automatically even before navigating to the Mongo Files Page. This seems to create unnecessary load on the website. Ideally, the function should execute only when the user clicks on the Mongo Files Page.

Here is the output I observed:

Extracting files from database...
Files extracted:
['file_1.csv', 'file_2.csv', 'file_3.csv', 'file_4.csv']
Extracting files from database...
Files extracted:
['file_1.csv', 'file_2.csv', 'file_3.csv', 'file_4.csv']
Extracting files from database...
Files extracted:
['file_1.csv', 'file_2.csv', 'file_3.csv', 'file_4.csv']
Dash is running on http://127.0.0.1:8050/

INFO:dash.dash:Dash is running on http://127.0.0.1:8050/

 * Serving Flask app 'vh2_custom_action_page_loading'
 * Debug mode: off
INFO:werkzeug:WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:8050
INFO:werkzeug:Press CTRL+C to quit

@petar-qb
Copy link
Contributor

Hi @BalaNagendraReddy, this behaviour will be fixed when we merge this #644 and publish the release. We expect that to happen in the middle of next week.

Let's keep this issue opened until we merge mentioned PR 😃.

@BalaNagendraReddy
Copy link
Author

Hi @petar-qb ,

Thanks for the clarification.

@petar-qb petar-qb removed the Custom Components 🚀 Issue contains a custom component request label Aug 23, 2024
@petar-qb
Copy link
Contributor

Hey @BalaNagendraReddy 👋

The unnecessary website overloading bug has been fixed and you should no longer encounter this behaviour with the new vizro==0.1.21 released this morning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
General Question ❓ Issue contains a general question
Projects
None yet
Development

No branches or pull requests

3 participants