How to create a user card class?

i have question ,i want to implement a function ,it’s using panel to list many trader account cards which show the position,pnl or other infos. because there many trader account ,so i want to use python class to implement, now i just implement a funtion can return a card.

def get_user_card(account_id,nick_name,uid):
    header_title=f"{account_id} {nick_name} {uid}"
    account_balance_number = pn.indicators.Number(
    name='Account_balance', value=72, format='{value}%',
    total_pnl_trend = pn.indicators.Trend(name='Price', data=data, width=200, height=200,plot_type="bar")

    close_all_position_button=pn.widgets.Button(name="Close_all_position", button_type="primary", button_style="solid")
    update_account_button=pn.widgets.Button(name="updata", button_type="info", button_style="solid")
    open_trade_button=pn.widgets.Button(name="Open Trade", button_type="success", button_style="solid")



button_accordion=pn.Accordion(("Trade bot",pn.Row(update_account_button,
user_card=pn.Card(card_cols,title=header_title,header_color='white',header_background='#2f2f2f',collapsed=False,collapsible=True,styles={'background': 'WhiteSmoke'})
return user_card 

i find many demos class are based param.Parameterized but i don’t know why
use the param.Parameterized exactly ,so how can i design the user card class? whether based param or not?

  • List item

Wrapping your INPUTS (parameter/attribute) and OUTPUTS (UI) into param.Parameterized classes gives you some nice things for “free”:
a) more robust and less code:

  • automatic definition and Type and range checking of the INPUTS at realtime (you don’t have to verify user-input in your code anymore)
  • often you don’t have to define any init code anymore
  • you can get notifications if values change
    → see Simplifying Codebases — param v1.13.0
    b) because panel uses param internally as well, it can automate some UI work based on the parameters you’ve defined in your param.parameterized class:
  • you can autogenerate widgets and cross-link the UI widgets to your param.Parameterized class parameters (something that otherwise you’d have to do yourself)
  • you can change parameters directly on the class or on the UI or both
  • you can easily get callbacks if anything changes on the widgets/UI or parameters (some widgets allow to add some JS or python callbacks directly but otherwise you’d have to poll the widget value for changes

But as you said, nothing forces you to use param.Parameterized. But it makes stuff much easier, especially if you have an app that gets more complex and grows. Or also for quick&dirty simple apps with a few parameters and an output.

I personally encapsulate most of my stuff in param.Parameterized. For Trading stuff you can eg. have classes for Watchlists, Screeners, the Stock-Data, Depots, Charts, … And Screeners/Watchlists/Depots share a lot of stuff inherited from a class “Tickers”


Here an example how to wrap things into a param.parameterized class.
Should give you an idea how param.Parameterized fits in.

You can later try to update some of the parameters (uid, …) either during instantiation or later to see the automatic value/type checking in action.
Also once you define the stuff this way, you can update the parameters either by UI or directly in the class.
You can also close the UI (eg if you have multiple TABS with UI Info) completely and would still have all the user/account-detail stuff available to query, update or later launch a UI again by simply rerunning the .view() method. You can also mirror the same UI info (or parts of it) on another UI TAB, etc …

import param
import panel as pn
import pandas as pd
import numpy as np

class User(param.Parameterized):
    ''' Unique User Information '''
    nick_name = param.String(doc='User Nickname')
    uid = param.Integer(default=1000, bounds=(1000, 9999), doc='User Id')

class AccountDetails(User):
    ''' Account Details, up to 5 accounts per user possible '''
    account_id = param.Integer(default=1, bounds=(1, 5), doc='Account ID')

    # account statistics
    account_balance = param.Number(default=72, softbounds=(-1000, 1000000), doc='Account Balance in $')
    total_pnl_trend = param.DataFrame(allow_None=False, label='Price', doc='PNL data')

    def open_trade(self):
    def user_update(self):

    def user_close(self):
    def view(self):
        close_all_position_button=pn.widgets.Button(name="Close_all_position", button_type="primary", button_style="solid")
        update_account_button=pn.widgets.Button(name="update", button_type="warning", button_style="solid")
        open_trade_button=pn.widgets.Button(name="Open Trade", button_type="success", button_style="solid")


        return pn.Card(
                self.param.account_balance, format='{value}%',
                plot_x='IDX', plot_y='Price', 
                width=200, height=200, plot_type="bar"), 
                ("Trade bot",pn.Row(update_account_button, open_trade_button))),     
            title=f"{self.account_id} {self.nick_name} {self.uid}", 
            styles={'background': 'WhiteSmoke'})

account1 = AccountDetails(
    nick_name='OurExpert', uid=1000, account_id=1, 
    total_pnl_trend=pd.DataFrame({'IDX': range(50), 'Price': np.random.randn(50).cumsum()}))


# simulate updating the account balance:
account1.account_balance = 99

thanks very much! it’s very useful for me.