最近接觸的某個數據挖掘項目將近尾聲(其實並無……),客戶開始關心模型最終部署的問題,但願將模型部署在巨硬雲Azure上,他們按期上傳數據,按期跑跑模型,獲得預測便可。我以爲這應該挺簡單的,客戶把數據上傳到某個文件夾裏,個人程序直接讀取就好啦,而後跑完模型結果保存在另外一個文件夾裏。結果客戶說,咱們的數據會上傳到一個SFTP上,你得從那上面讀取,這樣的話咱們能夠隨時換VM或者換SFTP,至於怎麼實現大家本身搞定。python
雖然客戶的需求頗有道理,但這讓我有點懵逼了,感受彷佛變成了隔空取物,畢竟我無法直接在python裏用os操做SFTP上的遠程文件夾,也無法直接用pandas讀取。不過幸虧,咱們有pysftp這個庫。3d
pysftp這個庫專門用於鏈接並操做SFTP,咱們只須要提供SFTP的地址,用戶名和密碼,其餘的基本跟os的操做同樣了。此庫安裝也很是簡單,直接pip install pysftp便可。blog
總體的思路很是簡單,咱們先來看看整個系統的流程:ip
用戶的數據上傳至SFTP上的Input_remote文件夾,咱們將其同步到Azure上的Input_local文件夾中。而後咱們的模型從Input_local讀取數據,運行,並將結果返回至Azure上的Output_local文件夾中。隨後咱們再將其推送至SFTP上的Output_remote文件夾,用戶經過該文件夾獲取。這樣一來咱們就實現了VM與SFTP的分離,二者隨時想換就能換。rem
而後就是附上代碼的環節了:部署
1. 導入庫get
import pysftp import os import warnings warnings.filterwarnings(action='ignore')
pysftp用於鏈接與操做SFTP,os用於操做VM上的本地文件。warnings僅用於過濾掉警告消息(強迫症患者)。同步
2. 遠程文件同步到本地(SFTP -> VM)pandas
cnopts = pysftp.CnOpts() cnopts.hostkeys = None with pysftp.Connection('***.com', username='******', password='******', cnopts=cnopts) as sftp: sftp.chdir('./remote_folder') # 變動遠程目標文件夾 print(sftp.listdir()) # 同步前文件夾的內容 print(os.listdir()) sftp.get_d(remotedir='./', localdir='./') # 遠程同步到本地 print(sftp.listdir()) # 同步後文件夾的內容 print(os.listdir())
開頭兩行是鏈接選項,不加可能會報錯。而後咱們用with語句開啓一個通往SFTP的鏈接,在pysftp.Connection中依次輸入SFTP的鏈接地址、用戶名和密碼。使用with的好處是,當咱們使用完畢時,會自動關掉這個鏈接。it
咱們在這裏能夠看到,pysftp的操做基本和os別無二致,很是簡單,咱們在這一步所作的就是:更改遠程目標文件夾 -> 分別查看遠程/本地文件夾的內容 -> 使用get_d從遠程同步到本地 -> 再次查看遠程/本地文件夾的內容。咱們看一下結果:
能夠看到咱們把SFTP上的test1.csv同步到了本地。
3. 本地文件推送至遠程(VM -> SFTP)
在這裏,咱們先把test1.csv改個名字,改爲test2.csv,而後把這個文件推送到遠程文件夾裏。
os.rename('test1.csv', 'test2.csv')
with pysftp.Connection('***.com', username='******', password='******', cnopts=cnopts) as sftp: sftp.chdir('./remote_folder') # 變動遠程目標文件夾 print(sftp.listdir()) # 查看 print(os.listdir()) sftp.put('test2.csv') # 推送單個文件 print(sftp.listdir()) # 再次查看 print(os.listdir())
因爲上次使用的with語句在執行結束後關閉了鏈接,所以咱們在這裏要從新變動遠程目標文件夾,咱們經過put命令將本地的test2.csv推送至遠程文件夾,執行先後分別查看一下:
能夠看到咱們把VM上的test2.csv推送到了遠程。若是咱們想直接同步整個文件夾的內容的話,咱們能夠用put_d命令(跟get_d相似)。
經過上述簡單的演示,咱們基本上完成了一個最簡易的SFTP-VM的數據打通環節,須要注意的是,同步與推送的過程當中,新出現的文件老是會直接覆蓋已存在的同名文件(overwrite),因此千萬要注意不要一失足成千古恨。
此外,咱們能夠把同步與推送的過程寫在一個with語句裏,並把咱們的模型打包嵌入進去,這樣一來咱們就基本完成了一個最簡單的模型部署。