# v.0.14

{% hint style="danger" %}
This version has been deprecated. If used with the current API version it can produce unexpected behaviour or errors.
{% endhint %}

{% hint style="danger" %}
The package shimoku-api-python is no longer maintained
{% endhint %}

{% hint style="info" %}
To get the new version :rocket:
{% endhint %}

```
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.&#x20;

  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:

  <pre class="language-python"><code class="lang-python">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')
  )

  <strong>s.plt.change_tabs_group_internal_order(
  </strong><strong>    group_name='Tabs group', menu_path=menu_path,
  </strong><strong>    tabs_list=['Table', 'Bar', 'Input Form']
  </strong><strong>)
  </strong></code></pre>

  Resutls in:

  <figure><img src="/files/BRRP20wRWDlA7sAlcxvb" alt=""><figcaption><p>Arbitrary tabs order and table within tabs</p></figcaption></figure>

### Improvements <a href="#fixes" id="fixes"></a>

* 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.&#x20;

  An example on how to use it is:

  ```python
  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:

  <figure><img src="/files/B43q9ihJbkowbkjZ3Lu9" alt=""><figcaption><p>Modified theme shimoku</p></figcaption></figure>

* 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:

  <figure><img src="/files/aEmcfdOCcSpdkzUCWp5z" alt=""><figcaption><p>New Toolbox</p></figcaption></figure>

* 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:

  <pre class="language-python"><code class="lang-python">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",
      },
  ]
  <strong>order = s.plt.indicator(
  </strong>    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,
  <strong>    order=order,
  </strong>    value='val',
      header='header',
      footer='footer',
      align='alignment',
      color='col'
  )
  </code></pre>

  the result is:

  <figure><img src="/files/QG2r29qsfU343DC3Nar2" alt=""><figcaption><p>Resulting indicators with dynamic order</p></figcaption></figure>

* 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:

  ```python
  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:

  <figure><img src="/files/XBQG8tUjrU7RGa5Nv6wG" alt=""><figcaption><p>Vertical arrangement of indicators</p></figcaption></figure>

* 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:

  ```python
  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:

  <figure><img src="/files/QaXbZTmwsvuOq6ogEMaL" alt=""><figcaption><p>Gauge indicators</p></figcaption></figure>

* 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:

  ```python
  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:

  <figure><img src="/files/vTBtbADymtuIt7gDx7K6" alt=""><figcaption><p>Audio recorder component</p></figcaption></figure>

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

  <figure><img src="/files/6L8C1cjY1N0PZt7fRpmN" alt=""><figcaption></figcaption></figure>

  And press it again to stop recording:

  <figure><img src="/files/F4HZgx6eQerwq64Jv8V7" alt=""><figcaption></figcaption></figure>

  Multiple audios can be recorded:

  <figure><img src="/files/TRAkvuUethwPw1WuT2dO" alt=""><figcaption></figcaption></figure>

* 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().*&#x20;

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

  ```python
  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,
  )
  ```

  <figure><img src="/files/ucCrJsIleYjs7jQAI62t" alt=""><figcaption><p>Html component created without manually importing the library</p></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.shimoku.com/dev/releases/2023/v.0.14.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
