日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用

瀏覽:26日期:2022-06-22 08:49:55

本文示例代碼已上傳至我的Github倉(cāng)庫(kù)https://github.com/CNFeffery/DataScienceStudyNotes

1 簡(jiǎn)介

在今天的教程中,我們將介紹如何在Dash中高效地開(kāi)發(fā)web應(yīng)用中非常重要的「文件上傳」及「下載」功能。

2 在Dash中實(shí)現(xiàn)文件上傳與下載2.1 在Dash中配合dash-uploader實(shí)現(xiàn)文件上傳

其實(shí)在自帶的dash_core_components中就封裝了基于html5原生API的dcc.Upload()組件,可以實(shí)現(xiàn)簡(jiǎn)單的文件上傳功能,但說(shuō)實(shí)話(huà),非常的「不好用」,其主要缺點(diǎn)有:

「文件大小有限制,150M到200M左右即出現(xiàn)瓶頸」 「策略是先將用戶(hù)上傳的文件存放在瀏覽器內(nèi)存,再通過(guò)base64形式傳遞到服務(wù)端再次解碼,非常低效」 「整個(gè)上傳過(guò)程無(wú)法配合準(zhǔn)確的進(jìn)度條」

正是因?yàn)镈ash自帶的上傳部件如此不堪,所以一些優(yōu)秀的第三方拓展涌現(xiàn)出來(lái),其中最好用的要數(shù)dash-uploader,它解決了上面提到的dcc.Upload()的所有短板。通過(guò)pip install dash-uploader進(jìn)行安裝之后,就可以直接在Dash應(yīng)用中使用了。

我們先從極簡(jiǎn)的一個(gè)例子出發(fā),看一看在Dash中使用dash-uploader的正確姿勢(shì):

app1.py

import dashimport dash_uploader as duimport dash_bootstrap_components as dbcimport dash_html_components as htmlapp = dash.Dash(__name__)# 配置上傳文件夾du.configure_upload(app, folder=’temp’)app.layout = html.Div( dbc.Container(du.Upload() ))if __name__ == ’__main__’: app.run_server(debug=True)

90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用

可以看到,僅僅十幾行代碼,我們就配合dash-uploader實(shí)現(xiàn)了簡(jiǎn)單的文件上傳功能,其中涉及到dash-uploader兩個(gè)必不可少的部分:

2.1.1 利用du.configure_upload()進(jìn)行配置

要在Dash中正常使用dash-uploader,我們首先需要利用du.configure_upload()進(jìn)行相關(guān)配置,其主要參數(shù)有:

「app」,即對(duì)應(yīng)已經(jīng)實(shí)例化的Dash對(duì)象;

「folder」,用于設(shè)置上傳的文件所保存的根目錄,可以是相對(duì)路徑,也可以是絕對(duì)路徑;

「use_upload_id」,bool型,默認(rèn)為T(mén)rue,這時(shí)被用戶(hù)上傳的文件不會(huì)直接置于「folder」參數(shù)指定目錄,而是會(huì)存放于du.Upload()部件的upload_id對(duì)應(yīng)的子文件夾之下;設(shè)置為False時(shí)則會(huì)直接存放在根目錄,當(dāng)然沒(méi)有特殊需求還是不要設(shè)置為False。

通過(guò)du.configure_upload()我們就完成了基本的配置。

2.1.2 利用du.Upload()創(chuàng)建上傳部件

接下來(lái)我們就可以使用到du.Upload()來(lái)創(chuàng)建在瀏覽器中渲染供用戶(hù)使用的上傳部件了,它跟常規(guī)的Dash部件一樣具有「id」參數(shù),也有一些其他的豐富的參數(shù)供開(kāi)發(fā)者充分自由地自定義功能和樣式:

「text」,字符型,用于設(shè)置上傳部件內(nèi)顯示的文字;

「text_completed」,字符型,用于設(shè)置上傳完成后顯示的文字內(nèi)容前綴;

「cancel_button」,bool型,用于設(shè)置是否在上傳過(guò)程中顯示“取消”按鈕;

「pause_button」,bool型,用于設(shè)置是否在上傳過(guò)程中顯示“暫停”按鈕;

「filetypes」,用于限制用戶(hù)上傳文件的格式范圍,譬如[’zip’, ’rar’, ’7zp’]就限制用戶(hù)只能上傳這三種格式的文件。默認(rèn)為None即無(wú)限制;

「max_file_size」,int型,單位MB,用于限制單次上傳的大小上限,默認(rèn)為1024即1GB;

「default_style」,類(lèi)似常規(guī)Dash部件的style參數(shù),用于傳入css鍵值對(duì),對(duì)部件的樣式進(jìn)行自定義;

「upload_id」,用于設(shè)置部件的唯一id信息作為du.configure_upload()中所設(shè)置的緩存根目錄的下級(jí)子目錄,用于存放上傳的文件,默認(rèn)為None,會(huì)在Dash應(yīng)用啟動(dòng)時(shí)自動(dòng)生成一個(gè)隨機(jī)值;

「max_files」,int型,用于設(shè)置一次上傳最多可包含的文件數(shù)量,默認(rèn)為1,也推薦設(shè)置為1,因?yàn)槟壳皩?duì)于多文件上傳仍有「進(jìn)度條異常」、「上傳結(jié)束顯示異常」等bug,所以不推薦設(shè)置大于1。

知曉了這些參數(shù)的作用之后,我們就可以創(chuàng)建出更符合自己需求的上傳部件:

app2.py

import dashimport dash_uploader as duimport dash_bootstrap_components as dbcimport dash_html_components as htmlapp = dash.Dash(__name__)# 配置上傳文件夾du.configure_upload(app, folder=’temp’)app.layout = html.Div( dbc.Container(du.Upload( id=’uploader’, text=’點(diǎn)擊或拖動(dòng)文件到此進(jìn)行上傳!’, text_completed=’已完成上傳文件:’, cancel_button=True, pause_button=True, filetypes=[’md’, ’mp4’], default_style={’background-color’: ’#fafafa’,’font-weight’: ’bold’ }, upload_id=’我的上傳’) ))if __name__ == ’__main__’: app.run_server(debug=True)

90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用

但像前面的例子那樣直接在定義app.layout時(shí)就傳入實(shí)際的du.Upload()部件,會(huì)產(chǎn)生一個(gè)問(wèn)題——應(yīng)用啟動(dòng)后,任何訪(fǎng)問(wèn)應(yīng)用的用戶(hù)都對(duì)應(yīng)一樣的upload_id,這顯然不是我們期望的,因?yàn)椴煌脩?hù)的上傳文件會(huì)混在一起。

因此可以參考下面例子的方式,在每位用戶(hù)訪(fǎng)問(wèn)時(shí)再渲染隨機(jī)id的上傳部件,從而確保唯一性:

app3.py

import dashimport dash_uploader as duimport dash_bootstrap_components as dbcimport dash_html_components as htmlimport uuidapp = dash.Dash(__name__)# 配置上傳文件夾du.configure_upload(app, folder=’temp’)def render_random_id_uploader(): return du.Upload( id=’uploader’, text=’點(diǎn)擊或拖動(dòng)文件到此進(jìn)行上傳!’, text_completed=’已完成上傳文件:’, cancel_button=True, pause_button=True, filetypes=[’md’, ’mp4’], default_style={’background-color’: ’#fafafa’,’font-weight’: ’bold’ }, upload_id=uuid.uuid1())def render_layout(): return html.Div( dbc.Container(render_random_id_uploader() ))app.layout = render_layoutif __name__ == ’__main__’: app.run_server(debug=True)

可以看到,每次訪(fǎng)問(wèn)時(shí)由于upload_id不同,因此不同的會(huì)話(huà)擁有了不同的子目錄。

90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用

2.1.3 配合du.Upload()進(jìn)行回調(diào)

在du.Upload()中額外還有isCompleted與fileNames兩個(gè)屬性,前者用于判斷當(dāng)前文件是否上傳完成,后者則對(duì)應(yīng)此次上傳的文件名稱(chēng),參考下面這個(gè)簡(jiǎn)單的例子:

app4.py

import dashimport dash_uploader as duimport dash_bootstrap_components as dbcimport dash_html_components as htmlfrom dash.dependencies import Input, Output, Stateapp = dash.Dash(__name__)# 配置上傳文件夾du.configure_upload(app, folder=’temp’)app.layout = html.Div( dbc.Container([ du.Upload(id=’uploader’), html.H5(’上傳中或還未上傳文件!’, id=’upload_status’)] ))@app.callback( Output(’upload_status’, ’children’), Input(’uploader’, ’isCompleted’), State(’uploader’, ’fileNames’))def show_upload_status(isCompleted, fileNames): if isCompleted:return ’已完成上傳:’+fileNames[0] return dash.no_updateif __name__ == ’__main__’: app.run_server(debug=True, port=8051)

90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用

2.2 配合flask進(jìn)行文件下載

相較于文件上傳,在Dash中進(jìn)行文件的下載就簡(jiǎn)單得多,因?yàn)槲覀兛梢耘浜蟜lask的send_from_directory以及html.A()部件來(lái)為指定的服務(wù)器端文件創(chuàng)建下載鏈接,譬如下面的簡(jiǎn)單示例就打通了文件的上傳與下載:

app5.py

from flask import send_from_directoryimport dashimport dash_uploader as duimport dash_html_components as htmlimport dash_bootstrap_components as dbcfrom dash.dependencies import Input, Outputimport osapp = dash.Dash(__name__)du.configure_upload(app, ’temp’, use_upload_id=False)app.layout = html.Div( dbc.Container([ du.Upload(id=’upload’), html.Div(id=’download-files’ )] ))@app.server.route(’/download/<file>’)def download(file): return send_from_directory(’temp’, file)@app.callback( Output(’download-files’, ’children’), Input(’upload’, ’isCompleted’))def render_download_url(isCompleted): if isCompleted:return html.Ul( [html.Li(html.A(f’/{file}’, href=f’/download/{file}’, target=’_blank’))for file in os.listdir(’temp’) ]) return dash.no_updateif __name__ == ’__main__’: app.run_server(debug=True)

90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用

3 用Dash編寫(xiě)簡(jiǎn)易個(gè)人網(wǎng)盤(pán)應(yīng)用

在學(xué)習(xí)了今天的案例之后,我們就掌握了如何在Dash中開(kāi)發(fā)文件上傳及下載功能,下面我們按照慣例,結(jié)合今天的主要內(nèi)容,來(lái)編寫(xiě)一個(gè)實(shí)際的案例;

今天我們要編寫(xiě)的是一個(gè)簡(jiǎn)單的個(gè)人網(wǎng)盤(pán)應(yīng)用,我們可以通過(guò)瀏覽器訪(fǎng)問(wèn)它,進(jìn)行文件的上傳、下載以及刪除:

90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用

import dashimport dash_bootstrap_components as dbcimport dash_html_components as htmlfrom dash.dependencies import Input, Output, Stateimport dash_uploader as duimport osfrom flask import send_from_directoryimport timeapp = dash.Dash(__name__, suppress_callback_exceptions=True)du.configure_upload(app, ’NetDisk’, use_upload_id=False)app.layout = html.Div( dbc.Container([ html.H3(’簡(jiǎn)易的個(gè)人云盤(pán)應(yīng)用’), html.Hr(), html.P(’文件上傳區(qū):’), du.Upload(id=’upload’, text=’點(diǎn)擊或拖動(dòng)文件到此進(jìn)行上傳!’, text_completed=’已完成上傳文件:’, max_files=1000), html.Hr(), dbc.Row([ dbc.Button(’刪除選中的文件’, id=’delete-btn’, outline=True), dbc.Button(’打包下載選中的文件’, id=’download-btn’, outline=True)] ), html.Hr(), dbc.Spinner(dbc.Checklist( id=’file-list-check’) ), html.A(id=’download-url’, target=’_blank’)] ))@app.server.route(’/download/<file>’)def download(file): return send_from_directory(’NetDisk’, file)@app.callback( [Output(’file-list-check’, ’options’), Output(’download-url’, ’children’), Output(’download-url’, ’href’)], [Input(’upload’, ’isCompleted’), Input(’delete-btn’, ’n_clicks’), Input(’download-btn’, ’n_clicks’)], State(’file-list-check’, ’value’))def render_file_list(isCompleted, delete_n_clicks, download_n_clicks, check_value): # 獲取上下文信息 ctx = dash.callback_context if ctx.triggered[0][’prop_id’] == ’delete-btn.n_clicks’:for file in check_value: try:os.remove(os.path.join(’NetDisk’, file)) except FileNotFoundError:pass if ctx.triggered[0][’prop_id’] == ’download-btn.n_clicks’:import zipfilewith zipfile.ZipFile(’NetDisk/打包下載.zip’, ’w’) as zipobj: for file in check_value:try: zipobj.write(os.path.join(’NetDisk’, file))except FileNotFoundError: passreturn [ {’label’: file, ’value’: file} for file in os.listdir(’NetDisk’) if file != ’打包下載.zip’ ], ’打包下載鏈接’, ’/download/打包下載.zip’ time.sleep(2) return [ {’label’: file, ’value’: file} for file in os.listdir(’NetDisk’) if file != ’打包下載.zip’ ], ’’, ’’if __name__ == ’__main__’: app.run_server(debug=True)

以上就是90行Python代碼開(kāi)發(fā)個(gè)人云盤(pán)應(yīng)用的詳細(xì)內(nèi)容,更多關(guān)于python 開(kāi)發(fā)個(gè)人云盤(pán)的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Python 編程
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品中文字幕一区二区三区av| 精品久久视频| 欧美亚洲国产激情| 欧美精选视频一区二区| 青青久久av| 国产99久久| 婷婷亚洲五月色综合| 欧美手机在线| 黄色日韩精品| 日韩在线黄色| 国产精品网站在线看| 另类综合日韩欧美亚洲| 日韩成人免费| 亚洲天堂成人| 夜久久久久久| 婷婷精品在线观看| 国产精品3区| 日韩国产专区| 国产日韩专区| 91精品麻豆| 成人一区而且| 欧美精品自拍| 久久亚洲图片| 国产欧美日韩影院| 福利一区在线| 欧美日韩国产免费观看视频| 中文字幕一区二区三区四区久久| 97久久超碰| 国产成人精品一区二区三区免费| 午夜欧美理论片| 日韩精品久久久久久久电影99爱| 国产综合婷婷| 最新国产精品视频| 欧美极品一区二区三区| 日韩三区免费| 免费高清在线一区| 欧美成人aaa| 亚洲精品福利电影| 亚洲欧美激情诱惑| 国产极品一区| 亚洲一级二级| 久久精品超碰| 久久中文视频| 日本免费一区二区视频| 精品亚洲免a| 亚洲欧美综合| 国产精品欧美大片| 99精品美女| 亚洲免费观看高清完整版在线观| 国产精品毛片久久久| 亚洲天堂久久| 国产乱人伦精品一区| 韩国三级一区| 日韩精品一区二区三区中文| www.com.cn成人| 日本一区福利在线| 亚洲伦乱视频| 青青国产91久久久久久| 久久精品国产68国产精品亚洲| 日韩午夜视频在线| 久久久一二三| 国产午夜久久av| 99精品在线观看| 国产亚洲欧美日韩在线观看一区二区| 亚洲爱爱视频| 国产亚洲高清在线观看| 欧美日韩国产欧| 欧美精品不卡| 噜噜噜躁狠狠躁狠狠精品视频 | 日韩欧美精品综合| 涩涩涩久久久成人精品| 五月天av在线| 国产欧美69| 欧美日韩少妇| 色爱综合网欧美| 国产亚洲一区二区三区啪| 亚洲精品123区| 日韩欧美看国产| 国产乱子精品一区二区在线观看| 亚洲色诱最新| 神马日本精品| 国产极品嫩模在线观看91精品| 日本大胆欧美人术艺术动态| 999视频精品| 日韩av在线播放网址| 国产剧情一区| 日本国产欧美| 亚洲色图综合| 亚洲欧洲另类| 成人精品天堂一区二区三区| 久久av影视| 久久国际精品| 日韩va亚洲va欧美va久久| 亚洲一区区二区| 999精品在线| 精品日韩视频| 精品国产欧美日韩| 国产精品久久777777毛茸茸| 日日夜夜免费精品| 中文一区一区三区免费在线观 | 卡一精品卡二卡三网站乱码| 日本亚洲三级在线| 免费不卡在线视频| 亚洲一区二区三区免费在线观看| 91精品国产成人观看| 国产一区二区三区网| 国产日韩欧美一区| 日韩一区二区三区精品视频第3页| 久久久一二三| 欧美香蕉视频| 青青久久av| 久久久久久黄| 久久久国产精品一区二区中文| 日本一二区不卡| 国产999精品在线观看| 久久精品国产久精国产| 久久中文精品| 福利视频一区| 首页国产精品| 特黄毛片在线观看| 日本少妇一区| 不卡在线一区| 亚洲免费精品| 欧美成人基地 | 久久精品xxxxx| 日韩av在线免费观看不卡| 日韩精品免费视频一区二区三区 | 精品欧美久久| 欧美日韩国产免费观看视频| 久久久久久夜| 日韩综合在线| 亚洲电影有码| 欧美精选一区二区三区| 中文亚洲欧美| 亚洲色图国产| 国产日韩视频在线| 麻豆精品视频在线观看视频| 麻豆91在线播放| 国产精品麻豆久久| 国产精品亚洲一区二区三区在线观看| 日韩欧美精品一区| 99精品视频在线| 国产午夜精品一区二区三区欧美| 亚洲一区二区三区免费在线观看| 黄色成人91| 亚洲精品国产精品粉嫩| 18国产精品| 精品国产一级| 色婷婷久久久| 蜜芽一区二区三区| 国产精品视频一区视频二区| 97国产精品| 欧美色图一区| 亚洲三区欧美一区国产二区| 日韩福利视频导航| 精品国产亚洲一区二区三区在线| 日韩在线欧美| 亚洲伊人精品酒店| 麻豆精品新av中文字幕| 日本激情一区| 亚洲一区中文| 国产精品亚洲成在人线| 97精品中文字幕| 亚洲一区二区三区高清| 国产日产一区| 四虎4545www国产精品| 蜜臀久久99精品久久久久久9| 国产情侣久久| 成人免费网站www网站高清| 蜜臀久久久99精品久久久久久| 国产美女亚洲精品7777| 亲子伦视频一区二区三区| 亚洲人成亚洲精品| 精品中国亚洲| 欧美成人高清| 欧美日韩亚洲国产精品| 日韩免费视频| 亚洲三级精品| 成人污污视频| 鲁大师成人一区二区三区| 国产精品99久久免费| 91国语精品自产拍| 国产极品一区| 玖玖玖国产精品| 理论片午夜视频在线观看| 综合干狼人综合首页| 肉色欧美久久久久久久免费看 | 黄页网站一区| 欧美国产极品| 男女激情视频一区| 亚洲精品88| 久久国产麻豆精品| 亚洲国产成人精品女人| 欧美国产免费| 亚洲色图综合| 久久理论电影| 精品久久影院| 日本精品一区二区三区在线观看视频| 中文另类视频| 乱一区二区av|