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

Upload Component #73

Merged
merged 20 commits into from Oct 14, 2017

Conversation

Projects
None yet
4 participants
@chriddyp
Member

chriddyp commented Sep 12, 2017

@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp

chriddyp Sep 12, 2017

Member

Usage (15 lines of app code! 😻 )

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt
import pandas as pd
import io

app = dash.Dash()

app.layout = html.Div([
    html.H1('Dash Upload Component'),
    dcc.Upload(id='upload'),
    dt.DataTable(
        id='datatable',
        rows=[{}]
    ),
], className="container")

@app.callback(
    Output('datatable', 'rows'),
    [Input('upload', 'contents')])
def update_figure(content):
    if not content:
        return []
    dff = pd.read_csv(io.StringIO(content))
    return dff.to_dict('records')

app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})

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

upload-component

Member

chriddyp commented Sep 12, 2017

Usage (15 lines of app code! 😻 )

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt
import pandas as pd
import io

app = dash.Dash()

app.layout = html.Div([
    html.H1('Dash Upload Component'),
    dcc.Upload(id='upload'),
    dt.DataTable(
        id='datatable',
        rows=[{}]
    ),
], className="container")

@app.callback(
    Output('datatable', 'rows'),
    [Input('upload', 'contents')])
def update_figure(content):
    if not content:
        return []
    dff = pd.read_csv(io.StringIO(content))
    return dff.to_dict('records')

app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})

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

upload-component

@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp
Member

chriddyp commented Sep 12, 2017

@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp

chriddyp Sep 12, 2017

Member

I've published this on the prerelease channel. Try this out with:

pip install dash-core-components==0.13.0rc1
Member

chriddyp commented Sep 12, 2017

I've published this on the prerelease channel. Try this out with:

pip install dash-core-components==0.13.0rc1
@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp

chriddyp Sep 13, 2017

Member

Just published another release with properties:

pip install dash-core-components==0.13.0rc2

Some examples:

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt

import json
import pandas as pd
import plotly
import io

app = dash.Dash()

app.scripts.config.serve_locally = True

app.layout = html.Div([
    html.H1('Dash Upload Component'),

    html.Hr(),
    html.H3('Default'),
    dcc.Upload(id='upload'),

    html.Hr(),
    html.H3('Custom Style with Children'),
    dcc.Upload(
        children=html.Div([
            'Drag and Drop or ',
            html.A('Select a File')
        ]),
        style={
            'width': '100%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center'
        }
    ),

    html.Hr(),
    html.H3('Styled as a Button'),
    dcc.Upload(
        html.Button('Upload'),
        style={}
    ),

    html.Hr(),

], className="container")


app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

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

image

Member

chriddyp commented Sep 13, 2017

Just published another release with properties:

pip install dash-core-components==0.13.0rc2

Some examples:

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt

import json
import pandas as pd
import plotly
import io

app = dash.Dash()

app.scripts.config.serve_locally = True

app.layout = html.Div([
    html.H1('Dash Upload Component'),

    html.Hr(),
    html.H3('Default'),
    dcc.Upload(id='upload'),

    html.Hr(),
    html.H3('Custom Style with Children'),
    dcc.Upload(
        children=html.Div([
            'Drag and Drop or ',
            html.A('Select a File')
        ]),
        style={
            'width': '100%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center'
        }
    ),

    html.Hr(),
    html.H3('Styled as a Button'),
    dcc.Upload(
        html.Button('Upload'),
        style={}
    ),

    html.Hr(),

], className="container")


app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

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

image

chriddyp added some commits Sep 13, 2017

@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp

chriddyp Sep 13, 2017

Member

I think that I will initialize the style to be {} and offer the html.Button and the dashed-style dropzone syntax as the canonical examples

Member

chriddyp commented Sep 13, 2017

I think that I will initialize the style to be {} and offer the html.Button and the dashed-style dropzone syntax as the canonical examples

chriddyp added some commits Sep 13, 2017

@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp

chriddyp Sep 13, 2017

Member

I have published v0.13.0-rc3. Upgrade with:

pip install dash-core-components==0.13.0rc3

This prerelease changes the default styles and changes the format of the content property into a base64 encoded string. Here's the new usage:

upload-component

Usage (Python 2)

import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt

import base64
import json
import pandas as pd
import plotly
import io

app = dash.Dash()

app.scripts.config.serve_locally = True

app.layout = html.Div([
    html.Div(id='waitfor'),
    dcc.Upload(
        id='upload',
        children=html.Div([
            'Drag and Drop or ',
            html.A('Select a File')
        ]),
        style={
            'width': '100%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
            'margin': '10px'
        }
    ),
    html.Div(id='output'),
    html.Div(dt.DataTable(rows=[{}]), style={'display': 'none'})
])

pre_style = {
    'whiteSpace': 'pre-wrap',
    'wordBreak': 'break-all',
    'whiteSpace': 'normal'
}


@app.callback(Output('output', 'children'),
              [Input('upload', 'contents')])
def update_output(contents):
    if contents is not None:
        content_type, content_string = contents.split(',')
        if 'csv' in content_type:
            df = pd.read_csv(io.StringIO(base64.b64decode(content_string).decode('utf-8')))
            return html.Div([
                dt.DataTable(rows=df.to_dict('records')),
                html.Hr(),
                html.Div('Raw Content'),
                html.Pre(contents, style=pre_style)
            ])
        elif 'image' in content_type:
            return html.Div([
                html.Img(src=contents),
                html.Hr(),
                html.Div('Raw Content'),
                html.Pre(contents, style=pre_style)
            ])
        else:
            # xlsx will have 'spreadsheet' in `content_type` but `xls` won't
            # have anything
            try:
                df = pd.read_excel(io.BytesIO(base64.b64decode(content_string)))
                return html.Div([
                    dt.DataTable(rows=df.to_dict('records')),
                    html.Hr(),
                    html.Div('Raw Content'),
                    html.Pre(contents, style=pre_style)
                ])
            except:
                return html.Div([
                    html.Hr(),
                    html.Div('Raw Content'),
                    html.Pre(contents, style=pre_style)
                ])



app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

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

chriddyp commented Sep 13, 2017

I have published v0.13.0-rc3. Upgrade with:

pip install dash-core-components==0.13.0rc3

This prerelease changes the default styles and changes the format of the content property into a base64 encoded string. Here's the new usage:

upload-component

Usage (Python 2)

import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_table_experiments as dt

import base64
import json
import pandas as pd
import plotly
import io

app = dash.Dash()

app.scripts.config.serve_locally = True

app.layout = html.Div([
    html.Div(id='waitfor'),
    dcc.Upload(
        id='upload',
        children=html.Div([
            'Drag and Drop or ',
            html.A('Select a File')
        ]),
        style={
            'width': '100%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
            'margin': '10px'
        }
    ),
    html.Div(id='output'),
    html.Div(dt.DataTable(rows=[{}]), style={'display': 'none'})
])

pre_style = {
    'whiteSpace': 'pre-wrap',
    'wordBreak': 'break-all',
    'whiteSpace': 'normal'
}


@app.callback(Output('output', 'children'),
              [Input('upload', 'contents')])
def update_output(contents):
    if contents is not None:
        content_type, content_string = contents.split(',')
        if 'csv' in content_type:
            df = pd.read_csv(io.StringIO(base64.b64decode(content_string).decode('utf-8')))
            return html.Div([
                dt.DataTable(rows=df.to_dict('records')),
                html.Hr(),
                html.Div('Raw Content'),
                html.Pre(contents, style=pre_style)
            ])
        elif 'image' in content_type:
            return html.Div([
                html.Img(src=contents),
                html.Hr(),
                html.Div('Raw Content'),
                html.Pre(contents, style=pre_style)
            ])
        else:
            # xlsx will have 'spreadsheet' in `content_type` but `xls` won't
            # have anything
            try:
                df = pd.read_excel(io.BytesIO(base64.b64decode(content_string)))
                return html.Div([
                    dt.DataTable(rows=df.to_dict('records')),
                    html.Hr(),
                    html.Div('Raw Content'),
                    html.Pre(contents, style=pre_style)
                ])
            except:
                return html.Div([
                    html.Hr(),
                    html.Div('Raw Content'),
                    html.Pre(contents, style=pre_style)
                ])



app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

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

chriddyp added some commits Sep 13, 2017

@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp

chriddyp Sep 13, 2017

Member

I'm pretty happy with this. I'll keep this PR open for a few days and solicit feedback before I merge it in.

Member

chriddyp commented Sep 13, 2017

I'm pretty happy with this. I'll keep this PR open for a few days and solicit feedback before I merge it in.

chriddyp added some commits Sep 13, 2017

"required": false,
"description": "ID of the component. Used to identify component\nin Dash callback functions."
},
"contents": {

This comment has been minimized.

@kevinchiang

kevinchiang Sep 15, 2017

Would it be possible to add a "filename(s)" property here to indicated which file or files have been dropped? Then set the property on line 35 of src/components/Upload.react.js, and add to Upload.propTypes? Or is there a way to get the filename that I'm not seeing?

Thanks

@kevinchiang

kevinchiang Sep 15, 2017

Would it be possible to add a "filename(s)" property here to indicated which file or files have been dropped? Then set the property on line 35 of src/components/Upload.react.js, and add to Upload.propTypes? Or is there a way to get the filename that I'm not seeing?

Thanks

This comment has been minimized.

@chriddyp

chriddyp Sep 18, 2017

Member

Good idea @kevinchiang ! Added this in dfa51bd

@chriddyp

chriddyp Sep 18, 2017

Member

Good idea @kevinchiang ! Added this in dfa51bd

@pabjusae

This comment has been minimized.

Show comment
Hide comment
@pabjusae

pabjusae Sep 22, 2017

Is possible to get the path from the input file?

Thank you

pabjusae commented Sep 22, 2017

Is possible to get the path from the input file?

Thank you

@chriddyp chriddyp merged commit b7f776f into master Oct 14, 2017

2 checks passed

ci/circleci Your tests passed on CircleCI!
Details
percy/dash-core-components Visual review approved by @chriddyp
Details
@chriddyp

This comment has been minimized.

Show comment
Hide comment
@chriddyp

chriddyp Oct 18, 2017

Member

This is now available in dash-core-components==0.14.0. Docs available at: https://plot.ly/dash/dash-core-components/upload

Member

chriddyp commented Oct 18, 2017

This is now available in dash-core-components==0.14.0. Docs available at: https://plot.ly/dash/dash-core-components/upload

@tantrev

This comment has been minimized.

Show comment
Hide comment
@tantrev

tantrev Jul 19, 2018

It would also be super nice if the upload could support input from an external URL.

tantrev commented Jul 19, 2018

It would also be super nice if the upload could support input from an external URL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment