singer 团队官方处了一个tap-s3-csv 的tap,对于没有使用aws 的人来说并不是很方便了,所以简单修改了
下源码,可以支持通用的s3 csv 文件的处理,同时发布到了官方pip 仓库中,方便大家使用。
以下是简单代码修改部分的说明,以及如何发布pip包

修改说明

主要是关于连接s3 的部分,因为tap-s3-csv 使用的是boto3 我们需要修改的就是关于boto3 连接s3 的部署
添加上aws_access_key_id,aws_secret_access_key,endpoint_url
关于s3 自定义连接的说明,格式如下:

 
  s3_client = boto3.session.Session().client(
        service_name='s3',
        aws_access_key_id=aws_access_key_id,
        aws_secret_access_key=aws_secret_access_key,
        endpoint_url=endpoint_url,
    )

几个需要修改的部分

  • s3.py
    get_input_files_for_table 部分,主要是传递参数的
    修改如下:
 
def get_input_files_for_table(config, table_spec, modified_since=None):
    bucket = config['bucket']
    aws_access_key_id = config['aws_access_key_id']
    aws_secret_access_key =config['aws_secret_access_key']
    endpoint_url =config['endpoint_url']
    to_return = []
    pattern = table_spec['search_pattern']
    try:
        matcher = re.compile(pattern)
    except re.error as e:
        raise ValueError(
            ("search_pattern for table `{}` is not a valid regular "
             "expression. See "
             "https://docs.python.org/3.5/library/re.html#regular-expression-syntax").format(table_spec['table_name']),
            pattern) from e
    LOGGER.info(
        'Checking bucket "%s" for keys matching "%s"', bucket, pattern)
    matched_files_count = 0
    unmatched_files_count = 0
    max_files_before_log = 30000
    for s3_object in list_files_in_bucket(bucket,aws_access_key_id,aws_secret_access_key,endpoint_url, table_spec.get('search_prefix')):
        key = s3_object['Key']
        last_modified = s3_object['LastModified']
        LOGGER.info(key)
        LOGGER.info(last_modified)
        if s3_object['Size'] == 0:
            LOGGER.info('Skipping matched file "%s" as it is empty', key)
            unmatched_files_count += 1
            continue
        if matcher.search(key):
            matched_files_count += 1
            if modified_since is None or modified_since < last_modified:
                LOGGER.info('Will download key "%s" as it was last modified %s',
                            key,
                            last_modified)
                yield {'key': key, 'last_modified': last_modified}
        else:
            unmatched_files_count += 1
        if (unmatched_files_count + matched_files_count) % max_files_before_log == 0:
            # Are we skipping greater than 50% of the files?
            if 0.5 < (unmatched_files_count / (matched_files_count + unmatched_files_count)):
                LOGGER.warn(("Found %s matching files and %s non-matching files. "
                             "You should consider adding a `search_prefix` to the config "
                             "or removing non-matching files from the bucket."),
                            matched_files_count, unmatched_files_count)
            else:
                LOGGER.info("Found %s matching files and %s non-matching files",
                            matched_files_count, unmatched_files_count)
    if 0 == matched_files_count:
        raise Exception("No files found matching pattern {}".format(pattern))

list_files_in_bucket 修改核心部分,关于连接s3 的
修改如下:

 
 @retry_pattern()
def list_files_in_bucket(bucket,aws_access_key_id,aws_secret_access_key,endpoint_url, search_prefix=None):
    s3_client = boto3.session.Session().client(
        service_name='s3',
        aws_access_key_id=aws_access_key_id,
        aws_secret_access_key=aws_secret_access_key,
        endpoint_url=endpoint_url,
    )
    s3_object_count = 0
    max_results = 1000
    args = {
        'Bucket': bucket,
        'MaxKeys': max_results,
    }
    if search_prefix is not None:
        args['Prefix'] = search_prefix
    paginator = s3_client.get_paginator('list_objects_v2')
    pages = 0
    for page in paginator.paginate(**args):
        pages += 1
        LOGGER.debug("On page %s", pages)
        s3_object_count += len(page['Contents'])
        yield from page['Contents']
    if 0 < s3_object_count:
        LOGGER.info("Found %s files.", s3_object_count)
    else:
        LOGGER.warning('Found no files for bucket "%s" that match prefix "%s"', bucket, search_prefix)

get_file_handle 部分,主要是关于获取s3 对象内容的

@retry_pattern()
def get_file_handle(config, s3_path):
    bucket = config['bucket']
    aws_access_key_id = config['aws_access_key_id']
    aws_secret_access_key =config['aws_secret_access_key']
    endpoint_url =config['endpoint_url']
    s3_client = boto3.resource(
       service_name="s3",
       aws_access_key_id=aws_access_key_id,
       aws_secret_access_key=aws_secret_access_key,
       endpoint_url=endpoint_url)
    s3_bucket = s3_client.Bucket(bucket)
    s3_object = s3_bucket.Object(s3_path)
    return s3_object.get()['Body']
  • init.py
    关于tap 命令处理的部分,比如模式发现,执行同步,以及参数检验的
    参数校验修改,修改为我们配置参数需要的
REQUIRED_CONFIG_KEYS = ["start_date", "bucket", "aws_access_key_id", "aws_secret_access_key", "endpoint_url"]

main 函数:

@singer.utils.handle_top_exception(LOGGER)
def main():
    args = singer.utils.parse_args(REQUIRED_CONFIG_KEYS)
    config = args.config
    bucket = config['bucket']
    aws_access_key_id = config['aws_access_key_id']
    aws_secret_access_key =config['aws_secret_access_key']
    endpoint_url =config['endpoint_url']
    config['tables'] = validate_table_config(config)
    try:
        for page in s3.list_files_in_bucket(bucket,aws_access_key_id,aws_secret_access_key,endpoint_url):
            break
        LOGGER.warning("I have direct access to the bucket without assuming the configured role.")
    except:
        LOGGER.error("can't connect to s3 storage")
    if args.discover:
        do_discover(args.config)
    elif args.properties:
        do_sync(config, args.properties, args.state)
  • pip 包约定处理
    为了不和官方冲突,重新别名
    setup.py:
 
#!/usr/bin/env python
from setuptools import setup
setup(name='tap-minio-csv',
      version='1.2.2',
      description='Singer.io tap for extracting CSV files from minio',
      author='rongfengliang',
      url='https://github.com/rongfengliang/tap-minio-csv',
      classifiers=['Programming Language :: Python :: 3 :: Only'],
      py_modules=['tap_minio_csv'],
      install_requires=[
          'backoff==1.3.2',
          'boto3==1.9.57',
          'singer-encodings==0.0.3',
          'singer-python==5.1.5',
          'voluptuous==0.10.5'
      ],
      extras_require={
          'dev': [
              'ipdb==0.11'
          ]
      },
      entry_points='''
          [console_scripts]
          tap-minio-csv=tap_minio_csv:main
      ''',
      packages=['tap_minio_csv'])
  • 项目包名称

发布pip 包

  • 安装工具
python3 -m pip install --user --upgrade setuptools wheel twine
  • 生成文件
python3 setup.py sdist bdist_wheel
  • 上传
    需要先注册账户,执行以下命令,按照提示输入账户信息即可
 
twine upload dist/*
  • pip 包

说明

以上是一个简单的说明,详细代码可以参考https://github.com/rongfengliang/tap-minio-csv

参考资料

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html
https://github.com/singer-io/tap-s3-csv
https://github.com/rongfengliang/tap-minio-csv

Singer 修改tap-s3-csv 支持minio 连接的更多相关文章

  1. ECMall如何支持SSL连接邮件服务器的配置

    首先,主要是ecmall使用的phpmailer版本太低,不支持加密连接. 然后,得对相应代码做一定调整. 1. 覆盖phpmailer 请从附件进行下载: http://files.cnblogs. ...

  2. 在SSIS 的 64 位版本中不支持 Excel 连接管理器

    Microsoft sql server 2008 R2——> SQL SERVER Business Intelligence Development Studio 使用EXCEL数据源或目标 ...

  3. vs中开发web站点使IIS Express支持局域网连接

    vs中开发web站点使IIS Express支持局域网连接 在开发webapi的时候,客户端设备都会使用局域网的地址访问webapi,有时候需要调试api.这个时候就需要使用一些技巧了,这里我记录了我 ...

  4. MySQL不支持远程连接的解决办法

    如果mysql不支持远程连接,会出现提示:错误代码是1130,ERROR 1130: Host * is not allowed to connect to this MySQL server ,解决 ...

  5. NetworkComms V3 之支持TCP连接和UDP连接

    NetworkComms V3 无缝的支持TCP连接和UDP连接. 您可以很容易的创建这两种连接 //创建一个连接信息对象 ConnectionInfo connInfo = ); //创建一个TCP ...

  6. Mysql 连接查询 Mysql支持的连接查询有哪些

    CREATE TABLE `chx` (   `id` VARCHAR(20) NOT NULL,   `name` VARCHAR(50) DEFAULT NULL,   `name2` CHAR( ...

  7. 已使用 163 邮箱测试通过,且支持 SSL 连接。 发送邮件

    示例:Jack 发送一封邮件给 Rose. public class SendMail {     public static void main(String[] args) {         b ...

  8. HslCommunication库的二次协议扩展,适配第三方通讯协议开发,基础框架支持长短连接模式

    本文将使用一个gitHub开源的项目来扩展实现二次协议的开发,该项目已经搭建好了基础层架构,并实现了三菱,西门子,欧姆龙,MODBUS-TCP的通讯示例,也可以参照这些示例开发其他的通讯协议,并Pul ...

  9. SQLServer 2016 Express 安装部署,并配置支持远程连接

    在项目中需要用到SQLServer,于是安装部署了SQLServer,部署的过程中遇到了一下问题,记录一下以便之后遇到同样问题能快速解决. 一.安装包下载 首先下载必要的安装包: 1.SQLServe ...

随机推荐

  1. Prometheus 标签使用示例整合

    Prometheus 监控实例 一.Prometheus 根据标签聚合总CPU使用率 1.主机添加标签(可在多个主机内添加相同标签实现聚合):vim prometheus.conf static_co ...

  2. NOI2019网络同步赛游记

    我发的邮件**f没收到,后来去专门询问才整到一个名额(估计是嫌我太菜,参加了也是垫底) day -1 上午写了到类似随机游走的高斯消元期望dp,然后颓颓颓 下午打洛咕月赛.T1一直50pts,后来才知 ...

  3. 解决 win10 家庭版环境下 MySQL 的ODBC驱动下载及安装

    目录 写在前面 下载安装 1.首先,我们需要去官网下载ODBC驱动. 配置 1.打开控制面板.查看方式:选择大图标. 2.选择管理工具的ODBC 数据源(64 位). 3.在驱动程序目录下.我们可以看 ...

  4. 锤子剪刀布pat-1018

    题目描述 大家应该都会玩“锤子剪刀布”的游戏:现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. 输入描述: 输入第1行给出正整数N(<=105),即双方交 ...

  5. python基础--py2与py3编码

    python2 与 python3的编码和解码 注意:小心,容易弄混 目录: 1.python2d 的encode & decode 2.python3的encode & decode ...

  6. vue打包后页面显示空白但是不报错

    在使用vue打包的时候页面显示空白,并且控制台不报错 设置vue-router的时候mode设置为history模式了,这种模式要有后台的配合,一般还是使用哈希模式就不会出现页面空白了.

  7. Java语言的介绍

    1. 计算机语言 语言:沟通交流的方式 计算机语言:人与计算机之间的交流方式 java是一门计算机编程语言,也是意大利自行车品牌 软件工程师,java开发工程师 <--------------- ...

  8. EXCHANGE上冒充任意用户--Exchange Server权限提升漏洞(CVE-2018-8581)分析

    0x00 前言 这是我们2018年Top 5趣案系列中的第三个案例.这些漏洞都有一些因素使它们从今年发布的大约1,400个报告中脱颖而出.今天我们将分析一个Exchange漏洞,它允许任何经过身份验证 ...

  9. Python如何去实际提高工作的效率?也许这个会有用!

    4月初,班主任的某次周会议上,华华关切的问了一下:最近班主任们有什么难题吗?就是花费了你们大部分时间的工作!我们Python天团可以帮你们解决问题. 班主任大主管星星说:有.目前有一个大难题.我们每天 ...

  10. Windows Server 2012 R2 远程桌面自动设置为不允许连接问题解决方案

    用“gpedit.msc”调出策略组设置窗口,在策略组界面点击:计算机配置->管理模块->Windows组件->远程桌面服务->远程桌面会话主机->连接->允许用户 ...