🎉 New Source: N8n [low-code cdk] (#18745)
* add n8n * update docs * add n8n to source def * auto-bump connector version Co-authored-by: marcosmarxm <marcosmarxm@gmail.com> Co-authored-by: Octavia Squidington III <octavia-squidington-iii@users.noreply.github.com>
This commit is contained in:
@@ -839,6 +839,13 @@
|
||||
icon: mysql.svg
|
||||
sourceType: database
|
||||
releaseStage: beta
|
||||
- name: n8n
|
||||
sourceDefinitionId: 4a961f66-5e99-4430-8320-a73afe52f7a2
|
||||
dockerRepository: airbyte/source-n8n
|
||||
dockerImageTag: 0.1.0
|
||||
documentationUrl: https://docs.airbyte.com/integrations/sources/n8n
|
||||
sourceType: api
|
||||
releaseStage: alpha
|
||||
- name: NASA
|
||||
sourceDefinitionId: 1a8667d7-7978-43cd-ba4d-d32cbd478971
|
||||
dockerRepository: airbyte/source-nasa
|
||||
|
||||
@@ -8211,6 +8211,28 @@
|
||||
supportsNormalization: false
|
||||
supportsDBT: false
|
||||
supported_destination_sync_modes: []
|
||||
- dockerImage: "airbyte/source-n8n:0.1.0"
|
||||
spec:
|
||||
documentationUrl: "https://docs.airbyte.com/integrations/sources/n8n"
|
||||
connectionSpecification:
|
||||
$schema: "http://json-schema.org/draft-07/schema#"
|
||||
title: "N8n Spec"
|
||||
type: "object"
|
||||
required:
|
||||
- "host"
|
||||
- "api_key"
|
||||
additionalProperties: true
|
||||
properties:
|
||||
host:
|
||||
type: "string"
|
||||
description: "Hostname of the n8n instance"
|
||||
api_key:
|
||||
type: "string"
|
||||
description: "Your API KEY. See <a href=\"https://docs.n8n.io/api/authentication\"\
|
||||
>here</a>"
|
||||
supportsNormalization: false
|
||||
supportsDBT: false
|
||||
supported_destination_sync_modes: []
|
||||
- dockerImage: "airbyte/source-nasa:0.1.0"
|
||||
spec:
|
||||
documentationUrl: "https://docs.airbyte.io/integrations/sources/nasa-apod"
|
||||
|
||||
6
airbyte-integrations/connectors/source-n8n/.dockerignore
Normal file
6
airbyte-integrations/connectors/source-n8n/.dockerignore
Normal file
@@ -0,0 +1,6 @@
|
||||
*
|
||||
!Dockerfile
|
||||
!main.py
|
||||
!source_n8n
|
||||
!setup.py
|
||||
!secrets
|
||||
38
airbyte-integrations/connectors/source-n8n/Dockerfile
Normal file
38
airbyte-integrations/connectors/source-n8n/Dockerfile
Normal file
@@ -0,0 +1,38 @@
|
||||
FROM python:3.9.11-alpine3.15 as base
|
||||
|
||||
# build and load all requirements
|
||||
FROM base as builder
|
||||
WORKDIR /airbyte/integration_code
|
||||
|
||||
# upgrade pip to the latest version
|
||||
RUN apk --no-cache upgrade \
|
||||
&& pip install --upgrade pip \
|
||||
&& apk --no-cache add tzdata build-base
|
||||
|
||||
|
||||
COPY setup.py ./
|
||||
# install necessary packages to a temporary folder
|
||||
RUN pip install --prefix=/install .
|
||||
|
||||
# build a clean environment
|
||||
FROM base
|
||||
WORKDIR /airbyte/integration_code
|
||||
|
||||
# copy all loaded and built libraries to a pure basic image
|
||||
COPY --from=builder /install /usr/local
|
||||
# add default timezone settings
|
||||
COPY --from=builder /usr/share/zoneinfo/Etc/UTC /etc/localtime
|
||||
RUN echo "Etc/UTC" > /etc/timezone
|
||||
|
||||
# bash is installed for more convenient debugging.
|
||||
RUN apk --no-cache add bash
|
||||
|
||||
# copy payload code only
|
||||
COPY main.py ./
|
||||
COPY source_n8n ./source_n8n
|
||||
|
||||
ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py"
|
||||
ENTRYPOINT ["python", "/airbyte/integration_code/main.py"]
|
||||
|
||||
LABEL io.airbyte.version=0.1.0
|
||||
LABEL io.airbyte.name=airbyte/source-n8n
|
||||
79
airbyte-integrations/connectors/source-n8n/README.md
Normal file
79
airbyte-integrations/connectors/source-n8n/README.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# N8n Source
|
||||
|
||||
This is the repository for the N8n configuration based source connector.
|
||||
For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.io/integrations/sources/n8n).
|
||||
|
||||
## Local development
|
||||
|
||||
#### Building via Gradle
|
||||
You can also build the connector in Gradle. This is typically used in CI and not needed for your development workflow.
|
||||
|
||||
To build using Gradle, from the Airbyte repository root, run:
|
||||
```
|
||||
./gradlew :airbyte-integrations:connectors:source-n8n:build
|
||||
```
|
||||
|
||||
#### Create credentials
|
||||
**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.io/integrations/sources/n8n)
|
||||
to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_n8n/spec.yaml` file.
|
||||
Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information.
|
||||
See `integration_tests/sample_config.json` for a sample config file.
|
||||
|
||||
**If you are an Airbyte core member**, copy the credentials in Lastpass under the secret name `source n8n test creds`
|
||||
and place them into `secrets/config.json`.
|
||||
|
||||
### Locally running the connector docker image
|
||||
|
||||
#### Build
|
||||
First, make sure you build the latest Docker image:
|
||||
```
|
||||
docker build . -t airbyte/source-n8n:dev
|
||||
```
|
||||
|
||||
You can also build the connector image via Gradle:
|
||||
```
|
||||
./gradlew :airbyte-integrations:connectors:source-n8n:airbyteDocker
|
||||
```
|
||||
When building via Gradle, the docker image name and tag, respectively, are the values of the `io.airbyte.name` and `io.airbyte.version` `LABEL`s in
|
||||
the Dockerfile.
|
||||
|
||||
#### Run
|
||||
Then run any of the connector commands as follows:
|
||||
```
|
||||
docker run --rm airbyte/source-n8n:dev spec
|
||||
docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-n8n:dev check --config /secrets/config.json
|
||||
docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-n8n:dev discover --config /secrets/config.json
|
||||
docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-n8n:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json
|
||||
```
|
||||
## Testing
|
||||
|
||||
#### Acceptance Tests
|
||||
Customize `acceptance-test-config.yml` file to configure tests. See [Source Acceptance Tests](https://docs.airbyte.io/connector-development/testing-connectors/source-acceptance-tests-reference) for more information.
|
||||
If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py.
|
||||
|
||||
To run your integration tests with docker
|
||||
|
||||
### Using gradle to run tests
|
||||
All commands should be run from airbyte project root.
|
||||
To run unit tests:
|
||||
```
|
||||
./gradlew :airbyte-integrations:connectors:source-n8n:unitTest
|
||||
```
|
||||
To run acceptance and custom integration tests:
|
||||
```
|
||||
./gradlew :airbyte-integrations:connectors:source-n8n:integrationTest
|
||||
```
|
||||
|
||||
## Dependency Management
|
||||
All of your dependencies should go in `setup.py`, NOT `requirements.txt`. The requirements file is only used to connect internal Airbyte dependencies in the monorepo for local development.
|
||||
We split dependencies between two groups, dependencies that are:
|
||||
* required for your connector to work need to go to `MAIN_REQUIREMENTS` list.
|
||||
* required for the testing need to go to `TEST_REQUIREMENTS` list
|
||||
|
||||
### Publishing a new version of the connector
|
||||
You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what?
|
||||
1. Make sure your changes are passing unit and integration tests.
|
||||
1. Bump the connector version in `Dockerfile` -- just increment the value of the `LABEL io.airbyte.version` appropriately (we use [SemVer](https://semver.org/)).
|
||||
1. Create a Pull Request.
|
||||
1. Pat yourself on the back for being an awesome contributor.
|
||||
1. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master.
|
||||
3
airbyte-integrations/connectors/source-n8n/__init__.py
Normal file
3
airbyte-integrations/connectors/source-n8n/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
||||
#
|
||||
@@ -0,0 +1,38 @@
|
||||
# See [Source Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/source-acceptance-tests-reference)
|
||||
# for more information about how to configure these tests
|
||||
connector_image: airbyte/source-n8n:dev
|
||||
acceptance_tests:
|
||||
spec:
|
||||
tests:
|
||||
- spec_path: "source_n8n/spec.yaml"
|
||||
connection:
|
||||
tests:
|
||||
- config_path: "secrets/config.json"
|
||||
status: "succeed"
|
||||
- config_path: "integration_tests/invalid_config.json"
|
||||
status: "failed"
|
||||
discovery:
|
||||
tests:
|
||||
- config_path: "secrets/config.json"
|
||||
basic_read:
|
||||
tests:
|
||||
- config_path: "secrets/config.json"
|
||||
configured_catalog_path: "integration_tests/configured_catalog.json"
|
||||
empty_streams: []
|
||||
# TODO uncomment this block to specify that the tests should assert the connector outputs the records provided in the input file a file
|
||||
# expect_records:
|
||||
# path: "integration_tests/expected_records.txt"
|
||||
# extra_fields: no
|
||||
# exact_order: no
|
||||
# extra_records: yes
|
||||
incremental:
|
||||
bypass_reason: "This connector does not implement incremental sync"
|
||||
# TODO uncomment this block this block if your connector implements incremental sync:
|
||||
# tests:
|
||||
# - config_path: "secrets/config.json"
|
||||
# configured_catalog_path: "integration_tests/configured_catalog.json"
|
||||
# future_state_path: "integration_tests/abnormal_state.json"
|
||||
full_refresh:
|
||||
tests:
|
||||
- config_path: "secrets/config.json"
|
||||
configured_catalog_path: "integration_tests/configured_catalog.json"
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
# Build latest connector image
|
||||
docker build . -t $(cat acceptance-test-config.yml | grep "connector_image" | head -n 1 | cut -d: -f2-)
|
||||
|
||||
# Pull latest acctest image
|
||||
docker pull airbyte/source-acceptance-test:latest
|
||||
|
||||
# Run
|
||||
docker run --rm -it \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /tmp:/tmp \
|
||||
-v $(pwd):/test_input \
|
||||
airbyte/source-acceptance-test \
|
||||
--acceptance-test-config /test_input
|
||||
|
||||
9
airbyte-integrations/connectors/source-n8n/build.gradle
Normal file
9
airbyte-integrations/connectors/source-n8n/build.gradle
Normal file
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
id 'airbyte-python'
|
||||
id 'airbyte-docker'
|
||||
id 'airbyte-source-acceptance-test'
|
||||
}
|
||||
|
||||
airbytePython {
|
||||
moduleDirectory 'source_n8n'
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#
|
||||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
||||
#
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"todo-stream-name": {
|
||||
"todo-field-name": "todo-abnormal-value"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#
|
||||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
||||
#
|
||||
|
||||
|
||||
import pytest
|
||||
|
||||
pytest_plugins = ("source_acceptance_test.plugin",)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def connector_setup():
|
||||
"""This fixture is a placeholder for external resources that acceptance test might require."""
|
||||
# TODO: setup test dependencies if needed. otherwise remove the TODO comments
|
||||
yield
|
||||
# TODO: clean up test dependencies
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"streams": [
|
||||
{
|
||||
"stream": {
|
||||
"name": "executions",
|
||||
"json_schema": {},
|
||||
"supported_sync_modes": ["full_refresh"]
|
||||
},
|
||||
"sync_mode": "full_refresh",
|
||||
"destination_sync_mode": "overwrite"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"api_key": "n8n_api",
|
||||
"host": "https://n8n.io"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"api_key": "n8n_api",
|
||||
"host": "https://n8n.io"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": 1007,
|
||||
"finished": false,
|
||||
"mode": "webhook",
|
||||
"retryOf": null,
|
||||
"retrySuccessId": null,
|
||||
"startedAt": "2022-10-24T13:00:31.946Z",
|
||||
"stoppedAt": "2022-10-24T13:01:32.612Z",
|
||||
"workflowId": "2",
|
||||
"waitTill": null
|
||||
}
|
||||
13
airbyte-integrations/connectors/source-n8n/main.py
Normal file
13
airbyte-integrations/connectors/source-n8n/main.py
Normal file
@@ -0,0 +1,13 @@
|
||||
#
|
||||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
||||
#
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from airbyte_cdk.entrypoint import launch
|
||||
from source_n8n import SourceN8n
|
||||
|
||||
if __name__ == "__main__":
|
||||
source = SourceN8n()
|
||||
launch(source, sys.argv[1:])
|
||||
@@ -0,0 +1,2 @@
|
||||
-e ../../bases/source-acceptance-test
|
||||
-e .
|
||||
29
airbyte-integrations/connectors/source-n8n/setup.py
Normal file
29
airbyte-integrations/connectors/source-n8n/setup.py
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
||||
#
|
||||
|
||||
|
||||
from setuptools import find_packages, setup
|
||||
|
||||
MAIN_REQUIREMENTS = [
|
||||
"airbyte-cdk~=0.1",
|
||||
]
|
||||
|
||||
TEST_REQUIREMENTS = [
|
||||
"pytest~=6.1",
|
||||
"pytest-mock~=3.6.1",
|
||||
"source-acceptance-test",
|
||||
]
|
||||
|
||||
setup(
|
||||
name="source_n8n",
|
||||
description="Source implementation for N8n.",
|
||||
author="Airbyte",
|
||||
author_email="contact@airbyte.io",
|
||||
packages=find_packages(),
|
||||
install_requires=MAIN_REQUIREMENTS,
|
||||
package_data={"": ["*.json", "*.yaml", "schemas/*.json", "schemas/shared/*.json"]},
|
||||
extras_require={
|
||||
"tests": TEST_REQUIREMENTS,
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
#
|
||||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
||||
#
|
||||
|
||||
|
||||
from .source import SourceN8n
|
||||
|
||||
__all__ = ["SourceN8n"]
|
||||
@@ -0,0 +1,50 @@
|
||||
version: "0.1.0"
|
||||
|
||||
definitions:
|
||||
selector:
|
||||
extractor:
|
||||
field_pointer: ["data"]
|
||||
requester:
|
||||
url_base: "{{ config['host'] }}/api/v1"
|
||||
http_method: "GET"
|
||||
authenticator:
|
||||
type: ApiKeyAuthenticator
|
||||
header: X-N8N-API-KEY
|
||||
api_token: "{{ config['api_key'] }}"
|
||||
request_options_provider:
|
||||
request_parameters:
|
||||
limit: "250"
|
||||
retriever:
|
||||
record_selector:
|
||||
$ref: "*ref(definitions.selector)"
|
||||
paginator:
|
||||
type: DefaultPaginator
|
||||
url_base: "*ref(definitions.requester.url_base)"
|
||||
page_size_option:
|
||||
inject_into: "request_parameter"
|
||||
field_name: ""
|
||||
pagination_strategy:
|
||||
type: "CursorPagination"
|
||||
cursor_value: "{{ response.nextCursor }}"
|
||||
page_size: 250
|
||||
page_token_option:
|
||||
field_name: "cursor"
|
||||
inject_into: "request_parameter"
|
||||
requester:
|
||||
$ref: "*ref(definitions.requester)"
|
||||
base_stream:
|
||||
retriever:
|
||||
$ref: "*ref(definitions.retriever)"
|
||||
executions_stream:
|
||||
$ref: "*ref(definitions.base_stream)"
|
||||
$options:
|
||||
name: "executions"
|
||||
primary_key: "id"
|
||||
path: "/executions"
|
||||
|
||||
streams:
|
||||
- "*ref(definitions.executions_stream)"
|
||||
|
||||
check:
|
||||
stream_names:
|
||||
- "executions"
|
||||
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": ["integer"]
|
||||
},
|
||||
"finished": {
|
||||
"type": ["boolean"]
|
||||
},
|
||||
"mode": {
|
||||
"type": ["string"]
|
||||
},
|
||||
"retryOf": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"retrySuccessId": {
|
||||
"type": ["null", "integer"]
|
||||
},
|
||||
"startedAt": {
|
||||
"type": ["string"]
|
||||
},
|
||||
"stoppedAt": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"workflowId": {
|
||||
"type": ["null", "string"]
|
||||
},
|
||||
"waitTill": {
|
||||
"type": ["null", "string"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright (c) 2022 Airbyte, Inc., all rights reserved.
|
||||
#
|
||||
|
||||
from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource
|
||||
|
||||
"""
|
||||
This file provides the necessary constructs to interpret a provided declarative YAML configuration file into
|
||||
source connector.
|
||||
|
||||
WARNING: Do not modify this file.
|
||||
"""
|
||||
|
||||
|
||||
# Declarative Source
|
||||
class SourceN8n(YamlDeclarativeSource):
|
||||
def __init__(self):
|
||||
super().__init__(**{"path_to_yaml": "n8n.yaml"})
|
||||
@@ -0,0 +1,16 @@
|
||||
documentationUrl: https://docs.airbyte.com/integrations/sources/n8n
|
||||
connectionSpecification:
|
||||
$schema: http://json-schema.org/draft-07/schema#
|
||||
title: N8n Spec
|
||||
type: object
|
||||
required:
|
||||
- host
|
||||
- api_key
|
||||
additionalProperties: true
|
||||
properties:
|
||||
host:
|
||||
type: string
|
||||
description: Hostname of the n8n instance
|
||||
api_key:
|
||||
type: string
|
||||
description: Your API KEY. See <a href="https://docs.n8n.io/api/authentication">here</a>
|
||||
31
docs/integrations/sources/n8n.md
Normal file
31
docs/integrations/sources/n8n.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# N8n
|
||||
|
||||
## Sync overview
|
||||
|
||||
This source can sync data from [N8n](https://docs.n8n.io/api/). At present this connector only supports full refresh syncs meaning that each time you use the connector it will sync all available records from scratch.
|
||||
|
||||
## This Source Supports the Following Streams
|
||||
|
||||
- [execitions](https://docs.n8n.io/api/api-reference/#tag/Execution/paths/~1executions/get)
|
||||
|
||||
### Features
|
||||
|
||||
| Feature | Supported?\(Yes/No\) | Notes |
|
||||
| :---------------- | :------------------- | :---- |
|
||||
| Full Refresh Sync | Yes | |
|
||||
| Incremental Sync | No | |
|
||||
|
||||
## Getting started
|
||||
|
||||
You need a n8n instance or use cloud version
|
||||
|
||||
### Create an API key
|
||||
|
||||
- Log in to n8n.
|
||||
- Go to Settings > API.
|
||||
- Select Create an API key.
|
||||
|
||||
## Changelog
|
||||
|
||||
| Version | Date | Pull Request | Subject |
|
||||
| :------ | :--- | :----------- | :------ |
|
||||
Reference in New Issue
Block a user