v.0.14

2023.01.13

This version has been deprecated. If used with the current API version it can produce unexpected behaviour or errors.

The package shimoku-api-python is no longer maintained

pip install --upgrade shimoku-api-python

This version comes with a lot of new features and quality of life improvements! This will be a trend for a couple of the next versions.

Fixes

  • Tabs have been fixed and improved! Now when they are deleted they will delete all their contents and will not leave child plots around like they did until now. Also tables work within tabs and a feature to order the tabs order inside of the tabs group has been added.

    By default the tabs will respect the order of creation but the function s.plt.change_tabs_group_internal_order() can be used to give them an arbitrary order.

    This example:

    menu_path: str = 'test/tabs-test'
    
    data = [
        {'date': dt.date(2021, 1, 1), 'x': 5, 'y': 5},
        {'date': dt.date(2021, 1, 2), 'x': 6, 'y': 5},
        {'date': dt.date(2021, 1, 3), 'x': 4, 'y': 5},
        {'date': dt.date(2021, 1, 4), 'x': 7, 'y': 5},
        {'date': dt.date(2021, 1, 5), 'x': 3, 'y': 5},
    ]
    
    s.plt.bar(
        data=data,
        x='date', y=['x', 'y'],
        menu_path=menu_path,
        x_axis_name='Date',
        y_axis_name=['Revenue'],
        # row=1, column=1,
        order=0, rows_size=2,
        cols_size=12,
        tabs_index=("Tabs group", "Bar")
    )
    
    report_dataset_properties = {
        'fields': [
            {
                'title': 'Personal information',
                'fields': [
                    {
                        'mapping': 'name',
                        'fieldName': 'name',
                        'inputType': 'text',
                    },
                    {
                        'mapping': 'surname',
                        'fieldName': 'surname',
                        'inputType': 'text',
                    },
                    {
                        'mapping': 'age',
                        'fieldName': 'age',
                        'inputType': 'number',
                    },
                    {
                        'mapping': 'tel',
                        'fieldName': 'phone',
                        'inputType': 'tel',
                    },
                    {
                        'mapping': 'gender',
                        'fieldName': 'Gender',
                        'inputType': 'radio',
                        'options': ['Male', 'Female', 'No-binary', 'Undefined'],
                    },
                    {
                        'mapping': 'email',
                        'fieldName': 'email',
                        'inputType': 'email',
                    },
    
                ],
            },
            {
                'title': 'Other data',
                'fields': [
                    {
                        'mapping': 'skills',
                        'fieldName': 'Skills',
                        'options': ['Backend', 'Frontend', 'UX/UI', 'Api Builder', 'DevOps'],
                        'inputType': 'checkbox',
                    },
                    {
                        'mapping': 'birthDay',
                        'fieldName': 'Birthday',
                        'inputType': 'date',
                    },
                    {
                        'mapping': 'onCompany',
                        'fieldName': 'Time on Shimoku',
                        'inputType': 'dateRange',
                    },
                    {
                        'mapping': 'hobbies',
                        'fieldName': 'Hobbies',
                        'inputType': 'select',
                        'options': ['Make Strong Api', 'Sailing to Canarias', 'Send Abracitos'],
                    },
                    {
                        'mapping': 'textField2',
                        'fieldName': 'Test Text',
                        'inputType': 'text',
                    },
                    {
                        'mapping': 'objectives',
                        'fieldName': 'Objetivos',
                        'inputType': 'multiSelect',
                        'options': ['sleep', 'close eyes', 'awake']
                    },
    
                ],
            },
        ],
    }
    
    s.plt.input_form(
        menu_path=menu_path, order=0,
        report_dataset_properties=report_dataset_properties,
        tabs_index=("Tabs group", "Input Form")
    )
    data_table = [
        {'date': dt.date(2021, 1, 1), 'x': 5, 'y': 5, 'filtA': 'A', 'filtB': 'Z', 'name': 'Ana'},
        {'date': dt.date(2021, 1, 2), 'x': 6, 'y': 5, 'filtA': 'B', 'filtB': 'Z', 'name': 'Laura'},
        {'date': dt.date(2021, 1, 3), 'x': 4, 'y': 5, 'filtA': 'A', 'filtB': 'W', 'name': 'Audrey'},
        {'date': dt.date(2021, 1, 4), 'x': 7, 'y': 5, 'filtA': 'B', 'filtB': 'W', 'name': 'Jose'},
        {'date': dt.date(2021, 1, 5), 'x': 3, 'y': 5, 'filtA': 'A', 'filtB': 'Z', 'name': 'Jorge'},
    ]
    filter_columns: List[str] = ['filtA', 'filtB']
    search_columns: List[str] = ['name']
    
    s.plt.table(
        title="Test-table",
        data=data_table,
        menu_path=menu_path,
        order=0,
        filter_columns=filter_columns,
        sort_table_by_col={'date': 'asc'},
        search_columns=search_columns,
        tabs_index=('Tabs group', 'Table')
    )
    
    s.plt.change_tabs_group_internal_order(
        group_name='Tabs group', menu_path=menu_path,
        tabs_list=['Table', 'Bar', 'Input Form']
    )

    Resutls in:

Improvements

  • To increase the robustness of the Shimoku platform in situations of high loads, such as uploading large tables, we have implemented a technique called exponential backoff. This technique automatically retries failed operations or requests, increasing the chances of success. This feature is always on and does not require any configuration or enabling by the users.

  • The deletion of apps has been improved significantly efficiency-wise, now both s.plt.clear_business() and s.plt.delete_path() (Only when the app name is provided without a sub-path) are far faster and convenient to use.

  • Now there is an option to change the theme of the business to adatpt it more to the case needs. The function s.business.update_business_theme() needs to be provided with a dictionary for all the options that want to be changed, this features options will be explained in detail in it's respective entry.

    An example on how to use it is:

    theme = {
            "palette": {
                "primary": {
                    "main": "#FFA500",
                },
            },
            "typography": {
                "h1": {
                    "fontSize": "60px",
                },
            },
            "custom": {
                "radius": {
                    "xs": "0px",
                    "s": "0px",
                    "m": "0px",
                    "l": "0px",
                    "xl": "0px"
                },
                "logo": "https://pngimg.com/uploads/under_construction/under_construction_PNG63.png",
            }
        }
    
    s.business.update_business_theme(
        business_id=business_id,
        theme=theme,
    )

    with the result being:

  • The following charts got an update on the style of the toolbox: stacked barchart, horizontal stacked barchart and stacked area chart.

    The new toolbox look is:

  • Indicators now use an updated version that lets them have a lot of new features, but now when a group of indicators is passed as the input data each one of them uses one position in the grid, so they use n orders. To make this easier to work with, the function s.plt.indicator returns the next available order value

    An example on how to use it would be:

    menu_path: str = 'test/indicator-test'
    data_ = [
        {
            "footer": "",
            "header": "Estado",
            "val": "Abierto",
            "alignment": "center",
        },
        {
            "footer": "",
            "header": "Price ($)",
            "val": "455",
            "col": "success",
        },
        {
            "footer": "this is a description",
            "header": "Volumen",
            "val": "41153"
        },
        {
            "footer": "",
            "header": "Cambio €/$",
            "val": "1.1946",
        },
    ]
    order = s.plt.indicator(
        data=data_,
        menu_path=menu_path,
        order=0,
        value='val',
        header='header',
        footer='footer',
        align='alignment',
        color='col'
    )
    s.plt.indicator(
        data=data_+data_[2:],
        menu_path=menu_path,
        order=order,
        value='val',
        header='header',
        footer='footer',
        align='alignment',
        color='col'
    )

    the result is:

  • The option to arrange indicators vertically has been added, through the use of the parameter vertical. This allows the user to create a column of indicators, using a bentobox with the provided cols_size (that by default is 12), and including the indicators inside. This option has no limit of indicators and will continue to grow vertically. To use this feature, pass True to the vertical parameter when calling the indicator function. Additionally, a title can be added to the top of the bentobox by passing a string to the same parameter vertical (If its set to True it will arrange them vertically but will not set any title).

    An example would be:

    menu_path: str = 'test/indicator-test'
    
    data_ = [{
        "color": "success",
        "variant": "contained",
        "description": "This indicator has a Link",
        "targetPath": "/indicators/indicator/1",
        "title": "Target Indicator",
        "align": "left",
        "value": "500€",
    }, {
        "color": "warning",
        "backgroundImage": "https://images.unsplash.com/photo-1535957998253-26ae1ef29506?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=736&q=80",
        "variant": "outlined",
        "description": "This has a background",
        "title": "Super cool indicator",
        "align": "left",
        "value": "Value",
    }, {
        "color": "error",
        "variant": "outlined",
        "description": "This hasn't got any icons",
        "title": "Error indicator",
        "align": "left",
        "value": "Value",
        "icon": "Line/download",
    }, {
        "color": "caution",
        "variant": "contained",
        "description": "Aligned to right and full of icons",
        "title": "Multiple cases",
        "align": "right",
        "value": "Value",
        "icon": "Line/download",
        "bigIcon": "Line/calendar",
    }]
    
    order = s.plt.indicator(
        data=data_ + data_,
        menu_path=menu_path + '-vertical',
        order=0, rows_size=1, cols_size=6,
        value='value',
        header='title',
        footer='description',
        align='align',
        color='color',
        variant='variant',
        target_path='targetPath',
        icon='icon',
        big_icon='bigIcon',
        background_image='backgroundImage',
        vertical="Title of the indicators"
    )
    order = s.plt.indicator(
        data=data_,
        menu_path=menu_path + '-vertical',
        order=order, rows_size=2, cols_size=4,
        value='value',
        header='title',
        footer='description',
        align='align',
        color='color',
        variant='variant',
        target_path='targetPath',
        icon='icon',
        big_icon='bigIcon',
        background_image='backgroundImage',
        vertical=True
    )
    s.plt.indicator(
        data=data_[0],
        menu_path=menu_path + '-vertical',
        order=order, rows_size=8, cols_size=2,
        value='value',
        header='title',
        footer='description',
        align='align',
        color='color',
        variant='variant',
        target_path='targetPath',
        vertical="Title of the indicator"
    )

    resulting in:

  • A new composite plot has been added! The gauge indicator uses an indicator and a gauge chart and joins them with a bentobox.

    When we execute this example:

    s.plt.gauge_indicator(
        menu_path='Gauge indicators',
        order=0,
        title="Gauge indicator",
        description="composite chart",
        value=42,
    )
    s.plt.gauge_indicator(
        menu_path='Gauge indicators',
        order=2,
        title="Gauge indicator",
        description="composite chart",
        value=24,
        color=2
    )

    The result is:

  • A new input form component has been added, the audio-recorder. It is used to record snippets of audio and send them.

    An example on how to use it is:

    form_groups = {
        'Audio recorder': [
            {
                'mapping': 'voice',
                'fieldName': 'Audio recorder',
                'inputType': 'audio',
            }
        ]
    }
    s.plt.generate_input_form_groups(
        menu_path='Audio recorder',
        order=0,
        form_groups=form_groups
    )

    results in:

    To begin recording, the user just has to press the button with the microphone symbol:

    And press it again to stop recording:

    Multiple audios can be recorded:

  • The html components of the library shimoku-components-catalog have been added as an intern module of the SDK in the form of s.html_components. They are used in the same way as before, when called they provide the necessary html code to call s.plt.html().

    So now we can use the html components without needing to import the additional library:

    from os import getenv
    import shimoku_api_python as Shimoku
    
    universe_id: str = getenv('UNIVERSE_ID')
    business_id: str = getenv('BUSINESS_ID')
    environment: str = getenv('ENVIRONMENT')
    access_token: str = getenv('API_TOKEN')
    
    s = Shimoku.Client(
        access_token=access_token,
        universe_id=universe_id,
        environment=environment,
        business_id=business_id,
    )
    
    box_with_button = s.html_components.box_with_button(
        title='HTML example',
        line='integrated in the SDK',
        href='https://shimoku.com',
        background="https://images.unsplash.com/photo-1553356084-58ef4a67b2a7?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=774&q=80",
    )
    s.plt.html(
        html=box_with_button,
        menu_path="Box with button",
        order=0,
    )

Last updated