# API Reference

## The Spreadsheet Component

To display a Mito spreadsheet in a Dash application, use the following code:

```python
from mitosheet.mito_dash.v1 import Spreadsheet, activate_mito
from dash import Dash, html
import pandas as pd

app = Dash(__name__)
activate_mito(app)

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')

app.layout = html.Div([
    html.H1('Empty Mito Spreadsheet'),
    Spreadsheet(df, id={'type': 'spreadsheet', 'id': 'sheet'})
])

if __name__ == '__main__':
    app.run_server(debug=True)
```

## Activate Mito

After creating a Dash app instance, you need to activate Mito. This activation step simply sets up communication between the Mito frontend and the backend, and ensures that Mito works like a proper spreadsheet.&#x20;

```python
from mitosheet.mito_dash.v1 import activate_mito, Spreadsheet
from dash import Dash

app = Dash(__name__)
activate_mito(app)
```

## Spreadsheet Component API

After you have activated Mito, you can now create a Spreadsheet component. It has the following API:

{% code fullWidth="false" %}

```python
from mitosheet.mito_dash.v1 import activate_mito, Spreadsheet

Spreadsheet(
    *args: Union[pd.Dataframe, str, None],
    id: str,
    import_folder: Optional[str]=None,
    df_names: Optional[List[str]]=None,
    sheet_functions: Optional[List[Callable]]=None, 
    importers: Optional[List[Callable]]=None,
    code_options: Optional[CodeOptions]=None,
    track_selection: Optional[bool]=False
) -> Tuple[Dict[str, pd.DataFrame], str]
```

{% endcode %}

<table data-full-width="true"><thead><tr><th width="211">Argument Name</th><th width="264.3333333333333">Type</th><th>Explanation</th></tr></thead><tbody><tr><td><code>*args</code></td><td><pre><code>Union[pd.DataFrame, str, None]
</code></pre></td><td>Pass any number of Pandas dataframes or paths to CSV files that will be displayed by in the Mito spreadsheet.</td></tr><tr><td><code>id</code></td><td><pre><code>{
    type: "spreadsheet",
    id: str
}
</code></pre></td><td>An necessary key that uniquely identifies this component as a spreadsheet with a unique ID. Must be a dictonary the the keys <code>type</code> and <code>id</code>, where <code>type: spreadsheet</code> and <code>id</code> is a unique string. </td></tr><tr><td><code>import_folder</code></td><td><pre><code>Optional[str]
</code></pre></td><td>A file path to a folder where users can import data from. Any subfolders will be available for navigation and importing within the Mito file browser. <a href="api-reference/understanding-import_folder">See more here.</a></td></tr><tr><td><code>df_names</code></td><td><pre><code>Optional[List[str]]
</code></pre></td><td>if you pass Pandas dataframes through the <code>args</code>, then optionally include the names of these dataframes in this list. This makes Mito generated code more correct.</td></tr><tr><td><code>sheet_functions</code></td><td><pre><code>Optional[List[Callable]]
</code></pre></td><td>Pass functions that are available as spreadsheet functions in the Mito spreadsheet. <a href="../how-to/interacting-with-your-data/bring-your-own-spreadsheet-functions">See more here. </a><em>(Mito Enterprise)</em></td></tr><tr><td><code>importers</code></td><td><pre><code>Optional[List[Callable]]
</code></pre></td><td>Pass custom data importers that get an auto-generated UI. <a href="../how-to/importing-data-to-mito/import-generated-ui-from-any-python-function">See more here. </a><em>(Mito Enterprise)</em></td></tr><tr><td><code>editors</code></td><td><pre><code>Optional[List[Callable]]
</code></pre></td><td>Pass Python functions that edit a dataframe to get an auto-generated Ui. <a href="https://docs.trymito.io/how-to/custom-editors-autogenerate-ui-from-any-function">See more here.</a> <em>(Mito Enterprise)</em></td></tr><tr><td><code>code_options</code></td><td><pre><code>Optional[CodeOptions]
</code></pre></td><td>Pass a <code>CodeOptions</code> object to specify how the code should be generated. <a href="../how-to/code-options">See more here.</a> <em>(Mito Enterprise)</em></td></tr><tr><td><code>track_selection</code></td><td><pre><code>Optional[bool]
</code></pre></td><td>If you want to register callbacks based on selection changes in the sheet, set this to True. Has a performance impact on scrolling through your data.</td></tr></tbody></table>

## Callback Props and Types

Like any other Dash component, the `Spreadsheet` component allows you to make your Dash app interactive by registering [callback functions](https://dash.plotly.com/basic-callbacks). However, to give you a better callback experience, Mito works slighly differently than default dash callbacks.&#x20;

#### A simple interactive example

Mito works differently in that it requires you to use the `@mito_callback` decorator when you're subscribing to `Input` or `State` changes from a Mito spreadsheet.&#x20;

A simple example:

```python
from mitosheet.mito_dash.v1 import Spreadsheet, mito_callback, activate_mito
from dash import Dash, html, Input, Output, State
import pandas as pd

app = Dash(__name__)
activate_mito(app)

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')

app.layout = html.Div([
    html.H1('Simple Mito Example'),
    Spreadsheet(df, id={'type': 'spreadsheet', 'id': 'sheet'}),
    html.Div(id='output')
])

@mito_callback(
    Output('output', 'children'),
    Input({'type': 'spreadsheet', 'id': 'sheet'}, 'spreadsheet_result'),
)
def update_output(spreadsheet_result):
    return html.Div([
        html.H3('Spreadsheet Result'),
        html.Code(f'Code: {spreadsheet_result.code()}', style={'whiteSpace': 'pre-wrap'}),
        html.Div(f'Selection: {spreadsheet_result.selection()}'),
        html.Div(f'Dataframes: {spreadsheet_result.dfs()}')
    ])

if __name__ == '__main__':
    app.run_server(debug=True)
```

#### &#x20;How is @mito\_callback different?

1. Only two valid `props` you can subscribe to for the Mito component are:
   1. `spreadsheet_result`: returns the `SpreadsheetResult` class defined below.
   2. `spreadsheet_selection`: returns the data that is currently selected in the Mito spreadsheet.
2. Both of these properties do not return JSON that you need to parse. Rather, they return the actual objects you want to use - resulting in a much better developer experience than having to parse various types of JSON.

## The `SpreadsheetResult` object

The `SpreadsheetResult` object gives you access to:

* `dfs`: The **dataframes** generated by the analysis
* `code`: The **code** generated by the analysis
* `selection`: The **currently selected cells** in the mitosheet
* `analysis`: A `RunnableAnalysis` object to help **rerun the analysis on new data**. To learn more, see the [RunnableAnalysis documentation](https://docs.trymito.io/mito-for-streamlit/api-reference/runnableanalysis-class).&#x20;

```python
from typing import List
import pandas as pd
from mitosheet.mito_dash.v1 import mito_callback, SpreadsheetResult, activate_mito

@mito_callback(
    Output('output', 'children'),
    Input({'type': 'spreadsheet', 'id': 'sheet'}, 'spreadsheet_result'),
)
def update_output(spreadsheet_result: SpreadsheetResult):

    # The code that corresponds to the 
    code: str = spreadsheet_result.code()
    
    # The current dataframes in the mitosheet
    dfs: List[pd.DataFrame] = spreadsheet_result.dfs()
    
    # The currently selected data in the Mito sheet
    selection: Optional[Union[pd.DataFrame, pd.Series]] = spreadsheet_result.selection()
```

## Examples

Below are examples of common uses of the Mito spreadsheet component in a Dash application.

#### Empty Mito Spreadsheet

```python
from mitosheet.mito_dash.v1 import Spreadsheet, activate_mito
from dash import Dash, html
import pandas as pd

app = Dash(__name__)
activate_mito(app)

app.layout = html.Div([
    html.H1('Empty Mito Spreadsheet'),
    Spreadsheet(id={'type': 'spreadsheet', 'id': 'sheet'})
])

if __name__ == '__main__':
    app.run_server(debug=True)
```

#### Display a Dataframe for Editing

```python
from mitosheet.mito_dash.v1 import Spreadsheet, mito_callback, activate_mito
from dash import Dash, html, Input, Output, State
import pandas as pd

app = Dash(__name__)
activate_mito(app)

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')

app.layout = html.Div([
    html.H1('Simple Dataframe Editing Example'),
    Spreadsheet(df, id={'type': 'spreadsheet', 'id': 'sheet'}),
    html.Div(id='output')
])

@mito_callback(
    Output('output', 'children'),
    Input({'type': 'spreadsheet', 'id': 'sheet'}, 'spreadsheet_result'),
)
def update_output(spreadsheet_result):
    return html.Div([
        html.H3('Edited Dataframes'),
        html.Div(f'Dataframes: {spreadsheet_result.dfs()}')
    ])

if __name__ == '__main__':
    app.run_server(debug=True)
```

#### Display a CSV file for Editing

```python
from mitosheet.mito_dash.v1 import Spreadsheet, mito_callback, activate_mito
from dash import Dash, html, Input, Output, State
import pandas as pd

app = Dash(__name__)
activate_mito(app)

app.layout = html.Div([
    html.H1('Simple CSV Editing Example'),
    Spreadsheet('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv', id={'type': 'spreadsheet', 'id': 'sheet'}),
    html.Div(id='output')
])

@mito_callback(
    Output('output', 'children'),
    Input({'type': 'spreadsheet', 'id': 'sheet'}, 'spreadsheet_result'),
)
def update_output(spreadsheet_result):
    return html.Div([
        html.H3('Edited Dataframes'),
        html.Div(f'Dataframes: {spreadsheet_result.dfs()}')
    ])

if __name__ == '__main__':
    app.run_server(debug=True)
```

#### Displaying Mito generated code

```python
from mitosheet.mito_dash.v1 import Spreadsheet, mito_callback, activate_mito
from dash import Dash, html, Input, Output, State
import pandas as pd

app = Dash(__name__)
activate_mito(app)

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')

app.layout = html.Div([
    html.H1('Simple Dataframe Editing Example'),
    Spreadsheet(df, id={'type': 'spreadsheet', 'id': 'sheet'}),
    html.Div(id='output')
])

@mito_callback(
    Output('output', 'children'),
    Input({'type': 'spreadsheet', 'id': 'sheet'}, 'spreadsheet_result'),
)
def update_output(spreadsheet_result):
    return html.Div([
        html.H3('Mito Generated Code'),
        html.Code(spreadsheet_result.code(), style={'whiteSpace': 'pre-wrap'}),
    ])

if __name__ == '__main__':
    app.run_server(debug=True)
```
