# Python 使用PySftp連線SFTP Server
###### tags: `python` `sftp` `pysft`
[TOC]
> Reference:
https://mileslin.github.io/2020/02/%E4%BD%BF%E7%94%A8-Docker-%E5%BB%BA%E7%BD%AE-FTP-SFTP-%E7%92%B0%E5%A2%83/
https://ovvo.cc/python-pysftp/
### 建立 sftp image
#### step1: 建立 public/private SSH 金鑰
```gherkin=
ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key
```
#### step2: 製作 Dockerfile
使用 atmoz/sftp image,須把 public key 放在 /home/{username}/.ssh/keys/ 底下
將剛剛產生的 public key ssh_host_rsa_key.pub 複製到 /home/deployer/.ssh/keys/
```docker=
FROM atmoz/sftp
RUN mkdir -p /home/deployer/.ssh/keys
COPY ./ssh_host_rsa_key.pub /home/miles/.ssh/keys/
```
#### step3: 製作 mysftp image
```gherkin=
docker build . -t mysftp
```
#### step4: run image
```gherkin=
# 帳號:密碼:uid:gid:子資料夾
account=deployer
password=123456
uid=
gid=
folder=upload
port=2223
publichost=172.105.230.31
docker run -p $port:22 -d mysftp -e PUBLICHOST="localhost" $account:$password:$uid:$gid:$folder
```
### Python 程式碼
#### 安裝 PySftpPermalink
```gherkin=
pip install pysftp
```
#### pysftp 檔案上傳範例
```python=
import pysftp
import paramiko
from base64 import decodebytes
sHostName = 'localhost'
sUserName = 'deployer'
sPassWord = '123456'
ConecPort = 2223
# 可以寫設定檔 .known_hosts
# cnopts = pysftp.CnOpts(knownhosts='known_hosts')
# 或者寫在程式碼內
keydata = b"""AAAAB3NzaC1yc2EAAAADAQABAAACAQDjmWHZlDKnTkJx0/UPwTUKTnHS+.."""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('127.0.0.1', 'ssh-rsa', key)
cnopts.hostkeys = None
with pysftp.Connection(sHostName, username=sUserName, password=sPassWord, cnopts=cnopts, port=ConecPort) as sftp:
sftp.cwd('./upload/')
sftp.put('./2output.csv')
```
docker-compose.yaml
```dokcer=
version: '2'
services:
ftp:
image: stilliard/pure-ftpd
ports:
- "2221:21"
- "30010-30019:30010-30019"
environment:
PUBLICHOST: "localhost"
FTP_USER_NAME: miles
FTP_USER_PASS: 123456
FTP_USER_HOME: /home/miles
FTP_PASSIVE_PORTS: "30010:30019"
sftp:
image: atmoz/sftp
ports:
- "2222:22"
command: miles:123456:::upload
sftpssh:
build:
context: .
dockerfile: Dockerfile
ports:
- "2223:22"
command: miles::::upload
```
### SFTP connect by command line
```gherkin=
sftp -v fx_zzzzz@filex-m1.oclc.org <<EOF
lcd /zzzzz/bib/xfer/out/
cd /xfer/metacoll/in/bib/
put 1234567.zzzzz.bibs.20200101.mrc
quit
```