keboola/ex-generic-v2

通用HTTP API提取器

安装: 44

依赖项: 2

建议者: 2

安全: 0

星标: 11

关注者: 22

分支: 7

开放问题: 44

类型:项目

4.4.4 2024-08-14 08:00 UTC

README

已迁移到 新文档

基础

已迁移到 新文档

  • 提取器配置包含3部分 - apiconfigcache
  • api部分定义了API行为,例如认证方法、分页、API的基础URI等
  • config部分应包含实际的认证信息(令牌等),以及jobs部分中的各个端点
  • cache部分启用了私有透明代理缓存,用于缓存HTTP响应

API定义

已迁移到 新文档

baseUrl

已迁移到 新文档

配置最重要的部分,API URL(应以/结尾)

  • 必须是字符串或用户函数(允许自定义域名,见示例)

示例

https://yourDomain.zendesk.com/api/v2/

-- OR --

    {
        "api": {
            "function": "concat",
            "args": [
                "https://",
                { "attr": "domain" },
                ".zendesk.com/api/v2/"
            ]
        },
        "config": {
            "domain": "yourDomain"
        }
    }

retryConfig

已迁移到 新文档

设置重试限制、速率限制重置头和HTTP代码,如果API返回错误则重试

  • retryConfig.headerName: (string) Retry-After
    • 包含我们何时可以再次访问API信息的头名称
  • retryConfig.httpCodes: (array) [500, 502, 503, 504, 408, 420, 429]
    • 要重试的HTTP代码
  • retryConfig.curlCodes: (array) [6, 7, 28, 35, 52]
    • 要重试的CURL错误代码
  • retryConfig.maxRetries: (int) 10
    • 最大重试尝试次数(如果不存在限制重置头,则用于指数退避)

http.requiredHeaders

已迁移到 新文档

  • 在配置部分中必须设置的头部

  • 应为数组,例如:App-Key,X-User-Email

  • http.headers.{Header-Name}配置部分中的属性(例如:http.headers.App-Key

    {
        "api": {
            "http": {
                "requiredHeaders": [
                    "App-Key",
                    "X-User-Email"
                ]
            }
        },
        "config": {
            "http": {
                "headers": {
                    "App-Key": "asdf1234",
                    "X-User-Email": "some@email.com"
                }
            }
        }
    }
    

http.headers.{Header-Name}

已迁移到 新文档

  • 将与所有请求一起发送的头部
  • 例如:http.headers.Accept-Encoding: gzip

http.defaultOptions

已迁移到 新文档

  • 定义默认请求选项,这些选项将包含在所有请求中
  • 例如:http.defaultOptions.params.queryParameter: value

认证

已迁移到 新文档

方法

basic

已迁移到 新文档

  • authentication.type: basic

  • 在配置部分中使用usernamepassword#password属性。

  • 如果两者都设置,则password优先于#password

    {
        "api": {
            "authentication": {
                "type": "basic"
            }
        },
        "config": {
            "username": "whoever",
            "password": "soSecret"
        }
    }
    

query

已迁移到 新文档

  • 支持将签名函数作为值

  • 值应在 api 部分描述

  • 示例桶属性

  • authentication.type: query

  • authentication.query.apiKey: {"attr": "apiKey"}

    • 这将查找名为 apiKey 的配置属性中的 apiKey 查询参数值
  • authentication.query.sig:

    {
        "function": "md5",
        "args": [
            {
                "function": "concat",
                "args": [
                    {
                        "attr": "apiKey"
                    },
                    {
                        "attr": "secret"
                    },
                    {
                        "function": "time"
                    }
                ]
            }
        ]
    }
    
    • 这将根据合并的配置表属性 apiKeysecret 的 MD5 生成 sig 参数值,然后是请求时的当前 time()(time() 是 PHP 函数)

    • 允许的函数在 用户函数 部分列出

    • 如果您使用 "attr": "parameterName" 通过任何配置参数,它必须与实际配置中的字符串相同,包括如果使用 KBC Docker 加密的话可能的 #

      {
          "api": {
              "authentication": {
                  "type": "url.query",
                  "query": {
                      "apiKey": {
                          "attr": "apiKey"
                      },
                      "sig": {
                          "function": "md5",
                          "args": [
                              {
                                  "function": "concat",
                                  "args": [
                                      {
                                          "attr": "apiKey"
                                      },
                                      {
                                          "attr": null
                                      },
                                      {
                                          "function": "time"
                                      }
                                  ]
                              }
                          ]
                      }
                  }
              }
          },
          "config": {
              "apiKey": "asdf1234"
          }
      }
      
  • 可用于构建签名的数据

    • attr: 来自 config 的属性(仅第一级)
    • query: 来自查询参数的值
      • 例:{ "query": "par1" } 如果查询包含 ?par1=val1,则返回 val1
    • request: 关于请求的信息
      • 可用信息
        • url
        • path
        • queryString
        • method
        • hostname
        • port
        • resource

login

已移动到 新文档

  • 登录到网络服务以获取令牌,然后使用该令牌进行签名请求

  • authentication.type: login

  • authentication.loginRequest: 描述登录到服务的请求

    • endpoint: string(必需)
    • params: array
    • method: string:[GET|POST|FORM]
    • headers: array
  • authentication.apiRequest: 定义如何使用登录的结果

    • headers: 使用响应中的值作为请求头
      • [$headerName => $responsePath]
    • query: 使用响应中的值作为请求查询
      • [$queryParameter => $responsePath]
  • authentication.expires(可选)

    • 如果设置为整数,登录操作将每 n 秒执行一次,其中 n 是值
    • 如果设置为数组,它 必须 包含 response 键,其值包含响应中到期时间的路径
      • relative 键设置到期值是否相对于当前时间。默认为 False。

        {
            "api": {
                "authentication": {
                    "type": "login",
                    "loginRequest": {
                        "endpoint": "Security/Login",
                        "headers": {
                            "Content-Type": "application/json"
                        },
                        "method": "POST",
                        "params": {
                            "UserName": {
                                "attr": "username"
                            },
                            "PassWord": {
                                "attr": "password"
                            }
                        }
                    },
                    "apiRequest": {
                        "headers": {
                            "Ticket": "Ticket"
                        }
                    }
                }
            },
            "config": {
                "username": "whoever",
                "password": "soSecret"
            }
        }
        

oauth10

已移动到 新文档

  • 使用 OAuth 1.0 令牌
  • 在 KBC ex-generic-v2 中使用 OAuth 当前要求应用程序在 API 组件 ID 下注册,并且不能在通用提取器中配置

这要求配置中的 authorization.oauth_api.credentials 对象包含 #dataappKey#appSecret,其中 #data 必须 包含一个具有 oauth_tokenoauth_token_secret 属性的 JSON 编码对象。 appKey 必须 包含消费者密钥,并且 #appSecret 必须 包含消费者密钥。

使用 Keboola Docker 和 OAuth API 集成 生成授权配置部分。

  • authentication.type: oauth10

示例最小 config.json

{
    "authorization": {
        "oauth_api": {
            "credentials": {
                "#data": {"oauth_token":"userToken","oauth_token_secret":"tokenSecret"},
                "appKey": 1234,
                "#appSecret": "asdf"
            }
        }
    },
    "parameters": {
        "api": {
            "authentication": {
                "type": "oauth10"
            }
        }
    }
}

oauth20

已移动到 新文档

使用用户函数在头或查询中使用令牌。而不是使用attrtime参数,您应该使用authorization来访问OAuth数据。如果数据是原始令牌字符串,请使用authorization: data来访问它。如果是JSON字符串,请使用authentication.format: json,并在注解中访问其值,如下例所示(authorization: data.access_token)。

查询和请求信息也可以像在querry认证方法中一样使用。

  • 认证类型: oauth20

示例配置:Bearer令牌使用

{
    "authorization": {
        "oauth_api": {
            "credentials": {
                "#data": {"status": "ok","access_token": "testToken"}
            }
        }
    },
    "parameters": {
        "api": {
            "authentication": {
                "type": "oauth20",
                "format": "json",
                "headers": {
                    "Authorization": {
                        "function": "concat",
                        "args": [
                            "Bearer ",
                            {
                                "authorization": "data.access_token"
                            }
                        ]
                    }
                }
            }
        }
    }
}

示例:MAC认证

  • 假设用户令牌位于OAuth数据JSON中的access_token键中,MAC密钥位于相同的JSON中的mac_secret键中。
{
    "authorization": {
        "oauth_api": {
            "credentials": {
                "#data": {"status": "ok","access_token": "testToken", "mac_secret": "iAreSoSecret123"},
                "appKey": "clId",
                "#appSecret": "clScrt"
            }
        }
    },
    "parameters": {
        "api": {
            "baseUrl": "http://private-834388-extractormock.apiary-mock.com",
            "authentication": {
                "type": "oauth20",
                "format": "json",
                "headers": {
                    "Authorization": {
                        "function": "concat",
                        "args": [
                            "MAC id=",
                            {
                                "authorization": "data.access_token"
                            },
                            ", ts=",
                            {
                                "authorization": "timestamp"
                            },
                            ", nonce=",
                            {
                                "authorization": "nonce"
                            },
                            ", mac=",
                            {
                                "function": "md5",
                                "args": [
                                    {
                                        "function": "hash_hmac",
                                        "args": [
                                            "sha256",
                                            {
                                                "function": "implode",
                                                "args": [
                                                    "\n",
                                                    [
                                                        {
                                                            "authorization": "timestamp"
                                                        },
                                                        {
                                                            "authorization": "nonce"
                                                        },
                                                        {
                                                            "request": "method"
                                                        },
                                                        {
                                                            "request": "resource"
                                                        },
                                                        {
                                                            "request": "hostname"
                                                        },
                                                        {
                                                            "request": "port"
                                                        },
                                                        "\n"
                                                    ]
                                                ]
                                            },
                                            {
                                                "authorization": "data.mac_secret"
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                }
            }
        }
    }
}

分页

已移至新文档

方法

api.pagination.method中配置

已移至新文档

偏移量

已移至新文档

  • 分页方法: offset

  • 分页限制: 整数

    • 如果配置文件中的params字段设置了限制,则将被其值覆盖
    • 如果API将结果计数限制为低于此设置的值,则滚动将在第一页后停止,因为它将在结果计数低于配置计数时停止
  • 分页限制参数(可选)

    • 设置哪个查询参数应包含限制值(默认为limit
  • 分页偏移量参数(可选)

    • 设置哪个查询参数应包含偏移量值(默认为offset

          "api": {
              "pagination": {
                  "method": "offset",
                  "limit": 1000,
                  "limitParam": "limit",
                  "offsetParam": "offset"
              }
          }
      
  • 分页第一页参数(可选)

    • 是否在第一次请求中包含限制和偏移量参数(默认为true
  • 分页从作业偏移量(可选)

    • 使用作业配置中指定的偏移量进行第一次请求(默认为false
    {
        "api": {
            "pagination": {
                "method": "offset",
                "limit": 1000,
                "offsetFromJob": true
            }
        },
        "config": {
            "jobs": [
                {
                    "endpoint": "resource",
                    "params": {
                        "offset": 100
                    }
                }
            ]
        }
    }
    

响应参数

已移至新文档

  • 分页方法: response.param

  • 分页响应参数:

    • 响应中指向用于滚动的值的路径
    • 如果值为空,则分页结束
  • 分页查询参数:

    • 将设置请求参数为响应中的值
  • 分页包含参数: false

    • 是否在下一页请求中使用作业配置中的参数
  • 分页滚动请求:

    • 可用于覆盖初始请求的设置(端点、方法等)
        "api": {
            "pagination": {
                "method": "response.param",
                "responseParam": "_scroll_id",
                "queryParam": "scroll_id",
                "scrollRequest": {
                    "endpoint": "_search/scroll",
                    "method": "GET",
                    "params": {
                        "scroll": "1m"
                    }
                }
            }
        }
    

响应URL

已移至新文档

  • 分页方法: response.url

  • 分页URL键: next_page

    • 响应对象中指向URL的路径
    • 如果该键的值为空,则分页结束
  • 分页参数是查询: false

    • 如果响应仅包含用于与同一端点一起使用的查询字符串,则启用
  • 分页包含参数: false

    • 是否将配置中的"params"添加到响应URL的查询中
    • 如果启用,并且下一页URL具有与"params"字段相同的查询参数,则使用"params"的值
        "api": {
            "pagination": {
                "method": "response.url",
                "urlKey": "nextPage",
                "includeParams": true
            }
        }
    

页码

已移至新文档

简单的页码递增1

  • 分页方法: pagenum

  • pagination.pageParam:(可选) 默认为page

  • pagination.limit:(可选) 整数

    • 定义页面大小
    • 如果省略limit,则一旦收到空页面,分页将结束。否则,它将在回复包含的条目少于limit时停止。
  • pagination.limitParam:(可选)

    • 用于limit的查询参数名称
        "api": {
            "pagination": {
                "method": "pagenum",
                "pageParam": "page",
                "limit": 500,
                "limitParam": "count"
            }
        }
    
  • pagination.firstPage: (可选) 默认为1。设置第一页码。

  • 分页第一页参数(可选)

    • 是否在第一次请求中包含limit和page参数(默认为true

游标

已移动到新文档

在响应的data中查找ID,然后将其用作滚动参数。

目的是在数据中查找标识符,并在下一次请求中,使用一个参数请求高于找到的最高ID(或相反,使用reverse参数低于最低ID)

  • pagination.method: cursor

  • pagination.idKey: (必需)

    • 响应data中的路径(即解析为CSV的数组),其中包含每个对象的标识符,然后用于下一次请求的查询
  • pagination.param: (必需)

    • 在下一次请求中传递值的参数名称
  • pagination.increment: (可选) 整数

    • 通过该数字增加找到的最高(/最低)值。
    • 可以是负数,例如,如果数据中的最低ID是10,并且increment设置为-1,则下一次请求参数值将是9
  • pagination.reverse: (可选) 布尔值,默认为false

    • 如果设置为true,则滚动器将查找最低值而不是最高值(默认值)
  • 示例

        "pagination": {
            "method": "cursor",
            "idKey": "id",
            "param": "max_id",
            "increment": -1,
            "reverse": true
        }
    
  • 数据

        "results": [
            {"id": 11},
            {"id": 12}
        ]
    
  • 请求

    http://api.example.com/resource?max_id=10
    

多个

已移动到新文档

允许为每个端点设置滚动器。

  • pagination.method: multiple

  • pagination.default: (可选)

    • 如果没有为端点指定默认滚动器,则设置默认滚动器使用(如果没有设置,则不使用滚动)
  • pagination.scrollers: (必需)

    • 一个对象,其中每个项代表一个受支持的滚动器及其相应的配置
    • 每个项的键用作滚动器的标识符,必须在作业的scroller参数中使用
  • 示例配置

    "pagination": {
        "method": "multiple",
        "scrollers": {
            "param_next_cursor": {
                "method": "response.param"
            },
            "param_next_results": {
                "method": "response.param"
            },
            "cursor_timeline": {
                "method": "cursor",
                "idKey": "id",
                "param": "max_id",
                "reverse": true,
                "increment": -1
            }
        }
    }
    "jobs": [
        {
            "endpoint": "statuses/user_timeline",
            "scroller": "cursor_timeline"
        },
        {
            "endpoint": "search",
            "scroller": "param_next_results",
            "params": {
                "q": "...(twitter search query)"
            }
        }
    ]

常见滚动参数

nextPageFlag

已移动到新文档

在响应中查找一个布尔字段,以确定是否继续滚动或不滚动。

用法

    "pagination": {
        "nextPageFlag": {
            "field": "hasMore",
            "stopOn": false,
            "ifNotSet": false
        }
    }

配置

元数据

  • 提取器将上次执行的开始时间加载到其元数据中。然后可以在用户函数中作为time: previousStart使用。
  • 当前执行的开始时间也可用在time: currentStart
  • 这可以用来创建具有最小重叠的增量导出,例如使用[start_time: [time: previousStart], end_time: [time: currentStart]]
  • 建议使用previousStartcurrentStart作为since>until对以确保数据中没有间隔和重叠。
  • 这两个值都存储为Unix时间戳。date函数可用于重新格式化它。

已移动到新文档

属性

已移动到新文档

属性必须根据api配置进行相应配置(例如authpaginationhttp.requiredHeaders)。它们位于配置的config部分。(见以下示例)

  • outputBucket:存储输出数据的桶名称

  • id:可选,如果设置了 outputBucket。否则,id 用于生成输出桶名称

  • debug:如果设置为 true,提取器将输出有关其运行的详细信息,包括所有 API 请求。 警告,这可能会在项目中暴露您的令牌或其他敏感数据!此功能仅用于帮助解决配置问题。

  • userData:一组 key:value 对,将添加到所有端点的结果的 root

    • 示例
    "config": {
        "userData": {
            "some": "tag",
            "another": "identifier"
        }
    }
    
  • incrementalOutput:(布尔值) 是否增量写入结果

    • 示例
    "config": {
        "incrementalOutput": true
    }
    

作业

已移至 新文档

    • endpoint (必需):API 端点

    • params:API 调用的查询/POST 参数,JSON 编码

      • JSON 编码对象中的每个参数可以包含一个字符串,例如:{""start_date"": ""2014-12-26""}
      • 或包含一个如以下所述的用户函数,例如从参数中加载数值
      "start_date": {
          "function": "date",
          "args": [
              "Y-m-d+H:i",
              {
                  "function": "strtotime",
                  "args": [
                      {
                          "attr": "job.1.success"
                      }
                  ]
              }
          ]
      }
      
    • dataType:端点返回的数据类型。它还描述了一个表名称,其中将存储结果

    • dataField:允许覆盖要导出的响应字段的名称。

      • 如果响应中有多个数组 "root",则提取器可能不知道要导出哪个数组,从而失败
      • 如果响应是一个数组,则默认使用整个响应
      • 如果没有根中的数组,必须在 dataField 中指定响应数据的路径
      • 可以包含到嵌套值的路径,点分隔符(例如 result.results.products
      • dataField 也可以是一个包含 path 的对象
    • children:子作业数组,这些作业使用作业的结果进行迭代

      • 端点必须使用大括号 {} 包裹的占位符

      • 占位符可以由一个数字前缀,该数字表示嵌套级别。默认情况下,使用直接父级的数据。直接父级可以用 {id}{1:id} 来引用。例如,“祖父母”结果将是 {2:id} 等。

      • 子表中的结果将包含包含父级数据的列(在占位符中使用),前缀为 parent_。例如,如果您的占位符是 {ticket_id},则将附加一个列 parent_ticket_id,其中包含当前迭代的值。

      • placeholders 数组必须定义每个占位符。它必须是一组 key: value 对,其中 key 是占位符(例如 "1:id"),而值是响应对象中的路径 - 如果嵌套,请使用 . 作为分隔符。

        • 示例
        "endpoint": "tickets.json",
        "children": [
            {
                "endpoint": "tickets/{id}/comments.json",
                "placeholders": {
                    "id": "id"
                },
                "children": [
                    {
                        "endpoint": "tickets/{2:ticket_id}/comments/{comment_id}/details.json",
                        "placeholders": {
                            "comment_id": "id",
                            "2:ticket_id": "id"
                        }
                    }
                ]
            }
        ]
        
        • 您还可以使用用户函数对来自父级的值进行操作,使用对象作为占位符值
        • 该对象必须包含一个 'path' 键,该键是占位符的值,以及一个函数。要在函数参数中访问值,请使用 {"placeholder": "value"}
          • 示例
          "placeholders": {
              "1:id": {
                  "path": "id",
                  "function": "urlencode",
                  "args": [
                      {
                          "placeholder": "value"
                      }
                  ]
              }
          }
          
      • 递归过滤器:

        • 可以包含一个由父级响应中字段的名称、逻辑运算符和要比较的值组成的价值。支持的运算符是 "=="、"<"、">"、"<="、">="、"!="
        • 示例:type!=employeeproduct.value>150
        • 该过滤器对空白敏感,因此 value == 100 将在 value␣ 中查找 ␣100 值,而不是可能期望的 value100
        • 更多文档可以在 https://github.com/keboola/php-filter 找到
    • method:GET(默认)、POST 或 FORM

    • responseFilter:允许过滤 API 响应中的数据,使其不被解析。

      • 过滤后的数据将被导入为 JSON 编码的字符串。
      • 此参数的值可以是包含响应数据中要过滤的数据的路径的字符串,或此类值的数组。
      • 示例
      "results": [
          {
              "id": 1,
              "data": "scalar"
          },
          {
              "id": 2,
              "data": {"object": "can't really parse this!"}
          }
      ]
      
      • 为了能够处理此类响应,请设置 "responseFilter": "data" - 它应该是响应数组中每个对象的路径,不包括响应数组的键。
      • 要过滤嵌套数组中的值,使用 "responseFilter": "data.array[].key"
      • 示例
      "results": [
          {
              "id": 1,
              "data": {
                  "array": [
                      {
                          "key": "value"
                      },
                      {
                          "key": {"another": "value"}
                      }
                  ]
              }
          }
      ]
      
      • 这将是一个无法解析的对象,因此上面的过滤器会将 { 'another': 'value' } 对象转换为字符串。
      • 要过滤整个数组,将 responseFilter 的值设置为 array。要单独过滤数组中的每个项,使用 array[]
    • responseFilterDelimiter:允许更改分隔符,如果您需要在 responseFilter 中进行嵌套,例如,如果您的数据包含包含 . 的键,这是默认分隔符。

      • 示例
      "results": [
          {
              "data.stuff": {
                  "something": [1,2,3]
              }
          }
      ]
      
      • 使用 'responseFilter': 'data.stuff/something''responseFilterDelimiter': '/' 一起过滤 something 中的数组。

映射

已迁移至 新文档

mappings 属性可以用于强制提取器将响应映射到 CSV 文件中的列,如 JSON to CSV Mapper 文档 中所述。每个 mappings 对象中的属性都必须遵循映射器设置,其中键是 jobdataType。请注意,如果没有设置 dataType,它将从端点生成,如果省略可能会令人困惑。

如果没有为 dataType 设置映射,则标准 JSON 解析器处理结果。

在递归作业中,由 parent_ 前缀和占位符 1:name 的值组成的值可用作 type: user,以便将子项链接到父项。请参阅下面的示例。

作业

"jobs": [
{
    "endpoint": "orgs/keboola/repos",
    "dataType": "repos",
    "children": [
    {
        "endpoint": "repos/keboola/{1:name}/issues",
        "placeholders": {
        "1:name": "name"
        },
        "dataType": "issues"
    }
    ]
}
]

映射(子项)

  "mappings": {
    "issues": {
      "parent_name": {
        "type": "user",
        "mapping": {
          "destination": "repo_name"
        }
      },
      "title": {
        "mapping": {
          "destination": "title"
        }
      },
      "id": {
        "mapping": {
          "destination": "id",
          "primaryKey": true,
          "propertyOrder": 1
        }
      }
    }
  }

parent_nameparent_ 前缀与占位符 1:name 的值的组合。

示例

  "mappings": {
    "get": {
      "id": {
        "mapping": {
          "destination": "id",
          "primaryKey": true
        }
      },
      "status": {
        "mapping": {
          "destination": "st"
        }
      }
    }
  },
  "jobs": [
    {
      "endpoint": "basic",
      "dataType": "get"
    }
  ]

迭代

配置可以多次运行,其中某些(或全部)config 部分的值被覆盖。例如,您可以为多个账户运行相同的配置,覆盖身份验证设置的值。

警告:

  • 如果在迭代中使用 userData,请确保它们都包含相同的键集!
  • 覆盖 incrementalOutput 只会使用写入每个 outputBucket 的最后 一次 迭代的设置。

示例

这样,您可以将来自两个不同账户的相同数据下载到单个输出表中,添加 owner 列以帮助您识别将每行结果引入配置的哪个迭代。

{
    "api": {
        "baseUrl": "http://example.com/api",
        "authentication": {
            "type": "basic"
        }
    },
    "config": {
        "outputBucket": "bunchOfResults",
        "jobs": [
            {
                "endpoint": "data"
            }
        ]
    },
    "iterations": [
        {
            "username": "chose",
            "password": "potato",
            "userData": {
                "owner": "Chose's results"
            }
        },
        {
            "username": "joann",
            "password": "beer",
            "userData": {
                "owner": "Joann's results"
            }
        }
    ]
}

用户函数

目前可以在查询类型身份验证或端点参数中使用。

已迁移至 新文档

允许的函数

已迁移至 新文档

  • md5:从其参数值生成 md5 密钥。
  • sha1:从其参数值生成 sha1 密钥。
  • time:返回从 Unix 纪元开始的时间(1970 年 1 月 1 日)的秒数。
  • date:以指定格式返回日期。
  • strtotime:将日期字符串转换为从 Unix 纪元开始的秒数。
  • base64_encode
  • hash_hmac:见 PHP 文档
  • sprintf:见 PHP 文档
  • concat:将其参数连接成一个字符串。
  • implode:使用第一个参数中的粘合字符串将第二个参数的数组连接起来。
  • ifempty:如果第一个参数不为空,则返回第一个参数,否则返回第二个参数。

语法

已移动到 新文档

函数必须指定为 JSON 格式,可能包含以下 4 个对象之一

  • 字符串: "something"

  • 函数: 上面的允许函数之一

    • 示例(这将返回当前日期,格式为:2014-12-08+09:38

      "function": "date",
      "args":[
          "Y-m-d+H:i"
          ]
      
    • 嵌套函数的示例(将返回 3 天前的相同格式的日期)

      "function": "date",
      "args":[
              "Y-m-d+H:i",
              {
              "function": "strtotime",
              "args": [
                  "3 days ago"
                  ]
              }
          ]
      
  • 配置属性: "attr": "attributeName""attr": "nested.attribute.name"

  • 元数据: time: previousStarttime: currentStart - 仅在作业参数中使用。

  • 查询参数: 待办

示例配置

已移动到 新文档

{
    "parameters": {
        "api": {
            "baseUrl": {
                "function": "concat",
                "args": [
                    "https://",
                    {
                        "attr": "domain"
                    },
                    ".zendesk.com/api/v2/"
                ]
            },
            "authentication": {
                "type": "basic"
            },
            "pagination": {
                "method": "response.url"
            },
            "name": "zendesk"
        },
        "config": {
            "id": "test_docker",
            "domain": "yours",
            "username": "you@wish.com/token",
            "password": "ohIdkSrsly",
            "jobs": [
                {
                    "endpoint": "exports/tickets.json",
                    "params": {
                        "start_time": {
                            "time": "previousStart"
                        },
                        "end_time": {
                            "function": "strtotime",
                            "args": [
                                "2015-07-20 00:00"
                            ]
                        }
                    },
                    "dataType": "tickets_export",
                    "dataField": "",
                    "children": [
                        {
                            "endpoint": "tickets/{id}/comments.json",
                            "recursionFilter": "status!=Deleted",
                            "dataType": "comments",
                            "placeholders": {
                                "id": "id"
                            }
                        }
                    ]
                },
                {
                    "endpoint": "users.json",
                    "params": {},
                    "dataType": "users",
                    "dataField": ""
                },
                {
                    "endpoint": "tickets.json",
                    "params": {},
                    "dataType": "tickets",
                    "dataField": ""
                }
            ]
        }
    }
}

缓存

使用私有代理缓存 HTTP 响应。这对于本地作业配置开发很有用。

启用缓存

"parameters": {
    "api": "...",
    "config": "...",
    "cache": true
}
  • 仅缓存具有以下之一 [200203300301410] HTTP 状态码的响应。
  • 缓存 TTL
    • Cache-ControlExpires 响应头中计算时间。
    • 如果计算值是 null,提取器将使用自己的默认值(30 天)
    • 默认 ttl 值可以被自定义配置值覆盖(以秒为单位)
"parameters": {
    "api": "...",
    "config": "...",
    "cache": {
        "ttl": 3600
    }
}

本地开发

已移动到 新文档

创建和测试新配置的最佳方式是在 Docker 容器中运行提取器。

先决条件

  • 克隆此仓库 git clone https://github.com/keboola/generic-extractor.git
  • 切换到提取器目录 cd generic-extractor
  • 构建容器 docker compose build
  • 本地安装依赖项 docker compose run --rm dev composer install
  • 为配置创建数据文件夹 mkdir data

执行

  • data 文件夹中创建 config.json

    示例配置,从 GitHub 下载 Keboola 开发者列表 data/config.json

    {
      "parameters": {
        "api": {
          "baseUrl": "https://api.github.com",
          "http": {
            "Accept": "application/json",
            "Content-Type": "application/json;charset=UTF-8"
          }
        },
        "config": {
          "debug": true,
          "jobs": [
            {
              "endpoint": "/orgs/keboola/members",
              "dataType": "members"
            }
          ]
        }
      }
    }
  • 运行提取 docker compose run --rm dev

  • 您将在 data/out 文件夹中找到提取的数据

  • 通过运行 docker compose run --rm dev rm -rf data/out 清除 data/out

  • 重复 :)

运行测试

docker compose run --rm tests

或(带有本地源代码和供应商副本)

docker compose run --rm tests-local

许可证

MIT 许可,请参阅 LICENSE 文件。