【测试开发】AutoS3Tool 项目:使用Python自动化AWS

虽然接触Python蛮久了,但这算是第一次正儿八经做的项目,起源于实习过程中的一个需求,当时想着用Python还是Java,考虑到Pyhton对于测试人员接受度更高,于是决定用Python写这个项目,写完后也经过了两次优化,因此特来和大家分享。

一、项目介绍

Github 地址:yinyuscloor/AutoS3Tool: v1.0

主要用于AWS-S3的自动化/批量操作,绝对原创哦~

1、依据S3批量操作(批量下载、修改文件名、上传)需求,分析后采用Python的AWS 开发工具包—boto3进行工具的构建

2、设计三层框架,Base层存放基础的方法或工具(包括路径、S3基础操作、utils、Excel基础操作),BusinessScript层存放业务代码供使用 (businessS3:具体业务中S3的步骤方法,businessExcelCsv:具体业务中excel/csv的步骤方法),demandScript.py存放具体的业务。

3、Config.ini配置完基础信息后,该工具主要实现S3批量操作上传修改下载等操作,同时具备定制化需求(如下载+修改文件名+上传),具备可拓展性,易于推广使用!

①目录结构

②工具层面代码

工具层可能大家单独用得到,因此放上来。

baseS3Helper.py

import boto3
import re
import sys


from Base.utils import read_config_ini
from Base.basePath import BasePath

"""
Boto3 官方文档:
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html
使用Python访问AWS S3
AWS配置,放在Config.ini文件里
boto3 不支持python3.6
"""

S3_FILE_CONF = read_config_ini(BasePath.CONFIG_FILE)['S3_FILE_CONF']

class S3Helper(object):
    """
    需要下载boto3模块
    """
    def __init__(self):
        self.access_key = S3_FILE_CONF.get("ocr.lls.aws.s3.access-key")
        self.secret_key = S3_FILE_CONF.get("ocr.lls.aws.s3.secret-key")
        self.region_name = S3_FILE_CONF.get("ocr.lls.aws.s3.end-point")
        self.bucket_name = S3_FILE_CONF.get("BUCKET_NAME")
        self.url = S3_FILE_CONF.get("ENDPOINT_URL")

        # 连接s3
        self.s3 = boto3.resource(
            service_name='s3',
            aws_access_key_id=self.access_key,
            aws_secret_access_key=self.secret_key,
            endpoint_url=self.url,
        )

        self.client = boto3.client(
            service_name='s3',
            region_name=self.region_name,
            aws_access_key_id=self.access_key,
            aws_secret_access_key=self.secret_key,
        )

    def download_file_s3(self, bucket_name, file_name, local_file):
        """
        从s3下载指定文件到本地
        需要本地运行程序的目录下新建一个local_file完整目录
        :param bucket_name: 桶名称
        :param file_name: 要下载的文件,所在路径
        :return: 下载完成返回True,下载出问题返回False,并打印错误
        """

        bucket = self.s3.Bucket(bucket_name)

        for obj in bucket.objects.all():
            if obj.key == file_name:
                p = re.compile(r'.*/(.*)')
                result = p.search(file_name).group(1)

                down_file = local_file + result
                try:
                    bucket.download_file(file_name, down_file)
                    return True
                except Exception as e:
                    print('出错了:' + str(e))
                    return False

    def get_list_s3(self, bucket_name, file_name):
        """
        用来列举出该目录下的所有文件
        :param bucket_name: 桶名称
        :param file_name: 要查询的文件夹
        :return: 该目录下所有文件列表
        """
        print("S3连接成功,开始获取【{}】目录下的文件".format(file_name))
        # 用来存放文件列表
        file_list = []

        response = self.client.list_objects_v2(
            Bucket=bucket_name,
            Delimiter='/',
            Prefix=file_name,
        )

        for file in response['Contents']:
            s = str(file['Key'])
            p = re.compile(r'.*/(.*)(\..*)')
            if p.search(s):
                s1 = p.search(s).group(1)
                s2 = p.search(s).group(2)
                result = s1 + s2
                file_list.append(result)
        return file_list

    def upload_file_s3(self, file_name, bucket, s3_dir):
        """
        上传本地文件到s3指定文件夹下
        :param file_name: 本地文件路径
        :param bucket: 桶名称
        :param s3_dir:要上传到的s3文件夹名称
        :return: 上传成功返回True,上传失败返回False,并打印错误
        """
        res = sys.platform
        p = re.compile(r'\w{1}')
        s = p.search(res).group()

        if s == 'w':
            p = re.compile(r'.*\\(.*)(\..*)')
        else:
            p = re.compile(r'.*/(.*)(\..*)')

        if p.search(file_name):
            s1 = p.search(file_name).group(1)
            s2 = p.search(file_name).group(2)
            file = s1 + s2
        s3_file = s3_dir + file

        try:
            self.s3.Object(bucket, s3_file).upload_file(file_name)
        except Exception as e:
            print('出错了:' + str(e))
            return False
        return True

baseExcel.py

import csv
from typing import Union, Any
from openpyxl.worksheet.worksheet import Worksheet
import openpyxl
"""
用于存放处理Excel和csv基础方法
"""

class BaseExcel(object):


    def open_sheet_Excel(self, filepath, sheet_name_or_index) -> Union[str, Worksheet]:
        '''打开表单-excel中某sheet'''
        worksheets = openpyxl.load_workbook(filepath)
        if isinstance(sheet_name_or_index, int): #若输入表单的序号
            worksheet = worksheets._sheets[sheet_name_or_index]
        elif isinstance(sheet_name_or_index, str): #若输入表单名
            worksheet = worksheets[sheet_name_or_index]
        else:
            return "sheet输入有误,请输入sheet_name_or_index"
        return worksheet


    def read_header_Excel(self,filepath, sheet_name_or_index):
        '''获取表单的表头'''
        worksheet = self.open_sheet_Excel(filepath,sheet_name_or_index)
        headers = []
        for i in worksheet[1]:
            headers.append(i.value)
        return headers


    def read_key_value_Excel(self,filepath,sheet_name_or_index):
        '''
        获取所有数据,且将表头中的内容与数据结合展示(以字典的形式)
        如:[{'序号':1,'会员卡号': '680021685898','机场名称':'上海机场'},{'序号':2,'会员卡号': '680021685899','机场名称':'广州机场'}]
        '''
        worksheet = self.open_sheet_Excel(filepath,sheet_name_or_index)
        rows = list(worksheet.rows)
        # 获取标题
        data = []
        for row in rows[1:]:
            rwo_data = []
            for cell in row:
                rwo_data.append(cell.value)
                # 列表转换成字典,与表头里的内容使用zip函数进行打包
            data_dict = dict(zip(self.read_header_Excel(filepath,sheet_name_or_index),rwo_data))
            data.append(data_dict)
        return data

    @staticmethod
    def write_change_Excel(filepath,sheet_name,row,column,data):
        '''写入Excel数据'''
        worksheets = openpyxl.load_workbook(filepath)
        worksheet = worksheets[sheet_name]
        # 修改单元格
        worksheet.cell(row,column).value = data
        # 保存
        worksheets.save(filepath)
        # 关闭
        worksheets.close()


    def csv_writer_csv(self,filepath):
        '''csv_writer'''
        #指定文件对象
        f = open(filepath,"w",encoding="utf-8",newline="")
        #基于稳健对象构建csv写入对象
        csv_writer = csv.writer(f)
        return csv_writer

二、环境依赖

1、Pycharm或其他编译器

2、python版本: python >= 3.7

3、boto3==1.24.85

boto3 是 python 中实现连接 S3 的库/软件包,可以拿来直接调用操作 S3(下载、上传等等); 此外 boto3 只支持 python3.7 及以上版本,建议安装高一些的 python 版本。

4、openpyxl==3.0.10

openpyxl是读写 xlsx/xlsm/xltx/xltm 的 Python 库,简单易用,功能广泛,本项目应用openpyxl来处理xlsx文件

5、部署:pip install -r requirement.txt 或其他形式装库皆可

总结

大家如果有疑问都可以评论提出,有不足之处请大家批评指正,希望能多结识这方面的朋友,共同学习、共同进步。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值