阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

仅20行代码,实现文件自动化上传至sftp

33次阅读
没有评论

共计 3890 个字符,预计需要花费 10 分钟才能阅读完成。

导读 最近接到一个产品需求是给指定的 sftp 服务器的指定目录定时推送文件数据。因为项目组已有现成的组件可以轻松实现 sftp 服务器文件的快速上传,本来是一件很容易的事情,但是问题出现在这个指定的 sftp 服务器所指定的密码带有系统关键字和一些特殊字符,导致现在的组件在解析过程中会失败。
1. 背景

最近接到一个产品需求是给指定的 sftp 服务器的指定目录定时推送文件数据。

因为项目组已有现成的组件可以轻松实现 sftp 服务器文件的快速上传,本来是一件很容易的事情,但是问题出现在这个指定的 sftp 服务器所指定的密码带有系统关键字和一些特殊字符,导致现在的组件在解析过程中会失败。

因此重新开发了下面的这套脚本来满足这个特殊的需求。

2. 代码实现

Python 代码

#test_upload.py
import os, sys
import yamlfrom optparse import OptionParserimport paramiko
import traceback


opt_parser = OptionParser()
opt_parser.add_option('--node', action='store', type='string', dest='node', help='sftp config')
opt_parser.add_option('--local_file', action='store', type='string', dest='local_file',  help='file to be transferred')


def load_config_from_param_conf(key):
    """
    :param key: 指定业务所使用的 sftp 服务的名称,例如 sftp.yaml 文件中的 key: test_file_upload
    :return: 从指定路径拿到 yaml 文件并读取指定 key,返回例如 sftp.yaml 文件中 key 为 test_file_upload 下的配置选项值
    包含: host,port,user,password,destination
    """config_file = f'{os.environ["TASK_MAIN"]}/test_conf/sftp.yaml' #获取指定路径下的 yaml 文件
    with open(config_file, 'r') as r: #打开 yaml 文件内容
        config = yaml.load(r) #转换 yaml 数据为字典
    return config['sftp']['upload'][key]


def upload(sftp_conf, local_file_path):
    """
    :param sftp_conf: 获取指定 sftp_conf=test_file_upload 下返回的字典值,这里的参数 sftp_conf 与 load_config_from_param_conf 函数里的参数值一致
    :param local_file_path: 指定本地要上传到 sftp 服务器的文件的绝对路径
    :return:
    """sf = paramiko.Transport((sftp_conf['host'], sftp_conf['port']))
    sf.connect(username=sftp_conf['user'], password=sftp_conf['password'])
    sftp = paramiko.SFTPClient.from_transport(sf)
    to_path = sftp_conf['destination']
    sftp.put(local_file_path, to_path + os.sep + os.path.split(local_file_path)[-1], confirm=False)
    sftp.close()


if __name__ == '__main__':
    option = opt_parser.parse_args(sys.argv[1:])[0]
    sftp_conf = load_config_from_param_conf(option.node)
    try:
        upload(sftp_conf, option.local_file)
    except Exception as e:
        print(traceback.format_exc())
        raise Exception('upload {} file error.'.format(option.local_file))

sftp 配置文件代码

#sftp.yaml
sftp:
  upload:
    test_file_upload:
      host: 10.12.34.6
      port: 808
      user: user_test
      password: 8Z.Lx/2@UH
      destination: /data/dump
3. 代码分析

(1). yaml 模块

import yaml

导入 yaml 模块前可以使用以下命令进行模块的安装

python3 -m pip install PyYaml

yaml 模块在这里的作用是读取 sftp 配置文件代码,将指定 key: test_file_upload 下的 key:value 的值转换为字典。
例如:load_config_from_param_conf 函数中的返回值就是使用 yaml 读取到 sftp 配置文件代码后,返回 key: test_file_upload 下配置选项值。
格式如下:

{ "host": "10.12.34.6",
  "port": "808",
  "user": "user_test",
  "password": "8Z.Lx/2@UH",
  "destination": "/data/dump"
}

最后将返回值传给 upload 函数作为参数。

(2). OptionParser 模块

from optparse import OptionParser

按照 yaml 模块的安装方法,先安装 optparse 模块后,然后在文件中从 optparse 中导入 OptionParser 模块

opt_parser = OptionParser()
opt_parser.add_option('--node', action='store', type='string', dest='node', help='sftp config')
opt_parser.add_option('--local_file', action='store', type='string', dest='local_file',  help='file to be uploaded')

在这里我使用了 OptionParser 这个类实例化了一个对象:opt_parser,通过对象来调用 add_option 方法添加了 2 个参数,分别是:node, local_file

1). 形参:–node,实参:node

所代表的业务含义是:指定要上传的 sftp 的节点,具体参数值对应 sftp 配置文件代码中的 test_file_upload

2). 形参:–local_file,实参:local_file

所代表的业务含义是:指定本地需要被上传到 sftp 服务器的具体文件路径

3). 调用命令

python3 test_upload.py --node test_file_upload --local_file 
/home/test/sftp_load/test_001.csv

4). add_option() 方法

add_option() 参数说明:action: 存储方式,分别为:store,store_false,store_true
type: 类型
dest: 存储的变量
default: 默认值
help: 帮助信息 

参数:action 的枚举

store: 参数列表中带有 --node, 那么就会将下一个元素即:test_file_upload 作为其 dest 实参 node 的值; 如果没有 --node, 那么对应的 node 的值就为 None;
store_true: 参数列表中有 --local_file, 那么其 dest 实参 local_file 的值就为 True; 否者就为 default 定义的默认值,这里没有给定 default 的默认值;
store_false: 参数列表中有 --local_file, 那么其 dest 实参 local_file 的值就为 False; 否者就为 default 定义的默认值,这里没有给定 default 的默认值;

参数:type

type 是指定传入参数的类型,这里的参数类型为 string 类型。

参数:dest

dest 是参数传入后由哪个变量来存储的,后面代码对该参数的引用也是使用这里定义的变量名来引用的。

参数:default

default 是与 action 的值结合使用的。当 action=store_true 时,default=123 时,如果有传入形参 --local_file,则实参 local_file 的值为:True
当 action=store_true 时,default=123 时,如果没有传入形参 --local_file,则实参 local_file 的值为:123
当 action=store_false 时,default=123 时,如果有传入形参 --local_file,则实参 local_file 的值为:False
当 action=store_false 时,default=123 时,如果没有传入形参 --local_file,则实参 local_file 的值为:123

参数:help

help 相当于帮助说明文档,用于描述这个参数的含义。

阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

代金券:在阿里云专用满减优惠券

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计3890字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中