Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎉 New Source: Paypal Transaction #4240

Merged
merged 69 commits into from
Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
9fb95ec
Added spec.json
midavadim May 31, 2021
1fb7d36
Initialization
midavadim May 31, 2021
311f3d4
added oauth2 autorization
midavadim May 31, 2021
30d0c40
added spec, check, discover + catalogs/configurared_catalogs
midavadim Jun 3, 2021
ecd06af
updated request_params
midavadim Jun 4, 2021
51078e3
added paging, slicing (1d)
midavadim Jun 7, 2021
496d605
Use oath2 for paypal
midavadim Jun 7, 2021
a4b40e9
incremental sync, acceptance test
midavadim Jun 10, 2021
24feba6
incremental sync, acceptance test
midavadim Jun 10, 2021
4b2bcab
Added spec.json
midavadim May 31, 2021
3e8da8e
Initialization
midavadim May 31, 2021
cc241c2
added oauth2 autorization
midavadim May 31, 2021
54649a8
added spec, check, discover + catalogs/configurared_catalogs
midavadim Jun 3, 2021
8710936
updated request_params
midavadim Jun 4, 2021
b1df469
added paging, slicing (1d)
midavadim Jun 7, 2021
c36bc78
Use oath2 for paypal
midavadim Jun 7, 2021
8019d83
incremental sync, acceptance test
midavadim Jun 10, 2021
ce98c15
incremental sync, acceptance test
midavadim Jun 10, 2021
fbeb3a3
Added spec.json
midavadim May 31, 2021
aec3b9d
Initialization
midavadim May 31, 2021
14a1927
added oauth2 autorization
midavadim May 31, 2021
a71ca37
added spec, check, discover + catalogs/configurared_catalogs
midavadim Jun 3, 2021
cf3d74d
updated request_params
midavadim Jun 4, 2021
647e538
added paging, slicing (1d)
midavadim Jun 7, 2021
3aabc39
Use oath2 for paypal
midavadim Jun 7, 2021
f7a6d82
incremental sync, acceptance test
midavadim Jun 10, 2021
f21cf64
updated slices and api limits, added validation for input dates
midavadim Jun 13, 2021
99f8b2d
added tests, fixed cursor related information in schemas and configur…
midavadim Jun 14, 2021
a74542a
added input param 'env' to support production and sandbox envs
midavadim Jun 17, 2021
e404aa8
added support for sandbox option, updated pattern for optional end da…
midavadim Jun 18, 2021
b48683e
Merge remote-tracking branch 'origin/midavadim/1640-paypal-transactio…
midavadim Jun 18, 2021
cc7c6fc
added github secrets
midavadim Jun 18, 2021
3416eba
added support for sandbox option, updated pattern for optional end da…
midavadim Jun 20, 2021
bf30273
Merge branch 'master' into midavadim/1640-paypal-transaction
midavadim Jun 20, 2021
b6acfbf
fixed Copyright date, removed debug mesages
midavadim Jun 21, 2021
3e6565c
added docs
midavadim Jun 21, 2021
845170c
fix for test failure - The sync should produce at least one STATE mes…
midavadim Jun 21, 2021
97b803e
removed optional parameter 'end_date'
midavadim Jun 21, 2021
1435531
removed detailed info about balances schema
midavadim Jun 21, 2021
6b4761c
Delete employees.json
midavadim Jun 21, 2021
f62ef39
Delete customers.json
midavadim Jun 21, 2021
e238db6
Merge remote-tracking branch 'origin/midavadim/1640-paypal-transactio…
midavadim Jun 21, 2021
3e94f2f
Added requests_per_minute rate limit
midavadim Jun 22, 2021
9a98bb3
added unit tests, added custom backoff
midavadim Jun 24, 2021
82fd276
added test for stream slices with stream state
midavadim Jun 24, 2021
e7e09d0
removed comments
midavadim Jun 24, 2021
52c7285
updated docs pages
midavadim Jun 24, 2021
641d6e1
Merge branch 'master' into midavadim/1640-paypal-transaction
midavadim Jun 24, 2021
7ccd91c
fixed format for json files
midavadim Jun 24, 2021
d409e68
fixed types in schemas and link to the schema. fixed primary key for …
midavadim Jun 25, 2021
e740f13
updated stream slices
midavadim Jun 26, 2021
ab97188
Updated tests, unified stream_slices for both streams, all instance v…
midavadim Jun 29, 2021
20832d7
added CHANGELOG.md
midavadim Jun 29, 2021
1bd1973
Merge branch 'master' into midavadim/1640-paypal-transaction
midavadim Jun 30, 2021
d98fe45
Added build seeds
midavadim Jun 30, 2021
27af53d
fixed closing double quotation mark
midavadim Jun 30, 2021
2115ff2
added paypal entry in builds.md
midavadim Jul 5, 2021
22173dc
add fixture helper
sherifnada Jul 5, 2021
e614e60
Merge branch 'midavadim/1640-paypal-transaction' of github.com:airbyt…
sherifnada Jul 5, 2021
0d7a939
added paypal transaction generator script
midavadim Jul 5, 2021
d502265
Merge remote-tracking branch 'origin/midavadim/1640-paypal-transactio…
midavadim Jul 5, 2021
e0cf3c3
fixed styling
midavadim Jul 7, 2021
506c02a
maximum allowed start_date is extracted from API response now.
midavadim Jul 7, 2021
45bdae5
fixed schemas
midavadim Jul 7, 2021
2f33cd3
Merge branch 'master' into midavadim/1640-paypal-transaction
midavadim Jul 7, 2021
290bb94
fixed schemas - removed datetime
midavadim Jul 7, 2021
4a30c26
now maximum_allowed_start_date is identified by last_refreshed_dateti…
midavadim Jul 8, 2021
0915ceb
Merge branch 'master' into midavadim/1640-paypal-transaction
midavadim Jul 8, 2021
2a43d62
added possibility to specify additional properties
midavadim Jul 8, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/publish-command.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ jobs:
MICROSOFT_TEAMS_TEST_CREDS: ${{ secrets.MICROSOFT_TEAMS_TEST_CREDS }}
MIXPANEL_INTEGRATION_TEST_CREDS: ${{ secrets.MIXPANEL_INTEGRATION_TEST_CREDS }}
MSSQL_RDS_TEST_CREDS: ${{ secrets.MSSQL_RDS_TEST_CREDS }}
PAYPAL_TRANSACTION_CREDS: ${{ secrets.SOURCE_PAYPAL_TRANSACTION_CREDS }}
POSTHOG_TEST_CREDS: ${{ secrets.POSTHOG_TEST_CREDS }}
RECHARGE_INTEGRATION_TEST_CREDS: ${{ secrets.RECHARGE_INTEGRATION_TEST_CREDS }}
QUICKBOOKS_TEST_CREDS: ${{ secrets.QUICKBOOKS_TEST_CREDS }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/test-command.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ jobs:
MICROSOFT_TEAMS_TEST_CREDS: ${{ secrets.MICROSOFT_TEAMS_TEST_CREDS }}
MIXPANEL_INTEGRATION_TEST_CREDS: ${{ secrets.MIXPANEL_INTEGRATION_TEST_CREDS }}
MSSQL_RDS_TEST_CREDS: ${{ secrets.MSSQL_RDS_TEST_CREDS }}
PAYPAL_TRANSACTION_CREDS: ${{ secrets.SOURCE_PAYPAL_TRANSACTION_CREDS }}
POSTHOG_TEST_CREDS: ${{ secrets.POSTHOG_TEST_CREDS }}
RECHARGE_INTEGRATION_TEST_CREDS: ${{ secrets.RECHARGE_INTEGRATION_TEST_CREDS }}
QUICKBOOKS_TEST_CREDS: ${{ secrets.QUICKBOOKS_TEST_CREDS }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"sourceDefinitionId": "d913b0f2-cc51-4e55-a44c-8ba1697b9239",
"name": "Paypal Transaction",
"dockerRepository": "airbyte/source-paypal-transaction",
"dockerImageTag": "0.1.0",
"documentationUrl": "https://docs.airbyte.io/integrations/sources/paypal-transaction"
}
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,8 @@
dockerRepository: airbyte/source-square
dockerImageTag: 0.1.0
documentationUrl: https://docs.airbyte.io/integrations/sources/square
- sourceDefinitionId: d913b0f2-cc51-4e55-a44c-8ba1697b9239
name: Paypal Transaction
dockerRepository: airbyte/source-paypal-transaction
dockerImageTag: 0.1.0
documentationUrl: https://docs.airbyte.io/integrations/sources/paypal-transaction
2 changes: 2 additions & 0 deletions airbyte-integrations/builds.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@

Oracle DB [![source-oracle](https://img.shields.io/endpoint?url=https%3A%2F%2Fstatus-api.airbyte.io%2Ftests%2Fsummary%2Fsource-oracle%2Fbadge.json)](https://status-api.airbyte.io/tests/summary/source-oracle)

Paypal Transaction [![paypal-transaction](https://img.shields.io/endpoint?url=https%3A%2F%2Fstatus-api.airbyte.io%2Ftests%2Fsummary%2Fsource-paypal-transaction%2Fbadge.json)](https://status-api.airbyte.io/tests/summary/source-paypal-transaction)

Plaid [![source-plaid](https://img.shields.io/endpoint?url=https%3A%2F%2Fstatus-api.airbyte.io%2Ftests%2Fsummary%2Fsource-plaid%2Fbadge.json)](https://status-api.airbyte.io/tests/summary/source-plaid)

Postgres [![source-postgres](https://img.shields.io/endpoint?url=https%3A%2F%2Fstatus-api.airbyte.io%2Ftests%2Fsummary%2Fsource-postgres%2Fbadge.json)](https://status-api.airbyte.io/tests/summary/source-postgres)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*
!Dockerfile
!Dockerfile.test
!main.py
!source_paypal_transaction
!setup.py
!secrets
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Changelog

## 0.1.0
Source implementation with support of Transactions and Balances streams
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM python:3.7-slim

# Bash is installed for more convenient debugging.
RUN apt-get update && apt-get install -y bash && rm -rf /var/lib/apt/lists/*

WORKDIR /airbyte/integration_code
COPY source_paypal_transaction ./source_paypal_transaction
COPY main.py ./
COPY setup.py ./
RUN pip install .

ENTRYPOINT ["python", "/airbyte/integration_code/main.py"]

LABEL io.airbyte.version=0.1.0
LABEL io.airbyte.name=airbyte/source-paypal-transaction
129 changes: 129 additions & 0 deletions airbyte-integrations/connectors/source-paypal-transaction/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Paypal Transaction Source

This is the repository for the Paypal Transaction source connector, written in Python.
For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.io/integrations/sources/paypal-transaction).

## Local development

### Prerequisites
**To iterate on this connector, make sure to complete this prerequisites section.**

#### Build & Activate Virtual Environment and install dependencies
From this connector directory, create a virtual environment:
```
python -m venv .venv
```

This will generate a virtualenv for this module in `.venv/`. Make sure this venv is active in your
development environment of choice. To activate it from the terminal, run:
```
source .venv/bin/activate
pip install -r requirements.txt
```
If you are in an IDE, follow your IDE's instructions to activate the virtualenv.

Note that while we are installing dependencies from `requirements.txt`, you should only edit `setup.py` for your dependencies. `requirements.txt` is
used for editable installs (`pip install -e`) to pull in Python dependencies from the monorepo and will call `setup.py`.
If this is mumbo jumbo to you, don't worry about it, just put your deps in `setup.py` but install using `pip install -r requirements.txt` and everything
should work as you expect.

#### 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-paypal-transaction:build
```

#### Create credentials
**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.io/integrations/sources/paypal-transaction)
to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_paypal_transaction/spec.json` 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 paypal-transaction test creds`
and place them into `secrets/config.json`.

### Locally running the connector
```
python main.py spec
python main.py check --config secrets/config.json
python main.py discover --config secrets/config.json
python main.py read --config secrets/config.json --catalog integration_tests/configured_catalog.json
```

### Locally running the connector docker image

#### Build
First, make sure you build the latest Docker image:
```
docker build . -t airbyte/source-paypal-transaction:dev
```

You can also build the connector image via Gradle:
```
./gradlew :airbyte-integrations:connectors:source-paypal-transaction: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-paypal-transaction:dev spec
docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-paypal-transaction:dev check --config /secrets/config.json
docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-paypal-transaction:dev discover --config /secrets/config.json
docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-paypal-transaction:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json
```
## Testing
Make sure to familiarize yourself with [pytest test discovery](https://docs.pytest.org/en/latest/goodpractices.html#test-discovery) to know how your test files and methods should be named.
First install test dependencies into your virtual environment:
```
pip install .[tests]
```
### Unit Tests
To run unit tests locally, from the connector directory run:
```
python -m pytest unit_tests
```

### Integration Tests
There are two types of integration tests: Acceptance Tests (Airbyte's test suite for all source connectors) and custom integration tests (which are specific to this connector).
#### Custom Integration tests
Place custom tests inside `integration_tests/` folder, then, from the connector root, run
```
python -m pytest integration_tests
```
#### Acceptance Tests
Customize `acceptance-test-config.yml` file to configure tests. See [Source Acceptance Tests](source-acceptance-tests.md) 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 acceptance tests, from the connector root, run
```
python -m pytest integration_tests -p integration_tests.acceptance
```
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-paypal-transaction:unitTest
```
To run acceptance and custom integration tests:
```
./gradlew :airbyte-integrations:connectors:source-paypal-transaction: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.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# See [Source Acceptance Tests](https://docs.airbyte.io/contributing-to-airbyte/building-new-connector/source-acceptance-tests.md)
# for more information about how to configure these tests
connector_image: airbyte/source-paypal-transaction:dev
tests:
spec:
- spec_path: "source_paypal_transaction/spec.json"
connection:
- config_path: "secrets/config.json"
status: "succeed"
- config_path: "integration_tests/invalid_config.json"
status: "failed"
discovery:
- config_path: "secrets/config.json"
basic_read:
# Sometimes test could fail (on weekends) because transactions could temporary disappear from Paypal Sandbox account
- config_path: "secrets/config.json"
configured_catalog_path: "integration_tests/configured_catalog.json"
validate_output_from_all_streams: yes
full_refresh:
- config_path: "secrets/config.json"
configured_catalog_path: "integration_tests/configured_catalog.json"
incremental:
# Only "Transactions" stream is tested here because "Balances" stream always return
# at least one message (and causes test failure)
- config_path: "secrets/config.json"
configured_catalog_path: "integration_tests/configured_catalog_transactions.json"
future_state_path: "integration_tests/abnormal_state.json"
cursor_paths:
transactions: ["date"]

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env sh
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#
# MIT License
#
# Copyright (c) 2020 Airbyte
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#

import logging
from pprint import pprint

# %%
import requests

logging.basicConfig(level=logging.DEBUG)

# %%
specification = {
"client_id": "REPLACE_ME",
"secret": "REPLACE_ME",
"start_date": "2021-06-01T00:00:00+00:00",
"end_date": "2021-06-30T00:00:00+00:00",
"is_sandbox": True,
}

# %% READ <client_id> and <secret>

client_id = specification.get("client_id")
secret = specification.get("secret")

# %% GET API_TOKEN

token_refresh_endpoint = "https://api-m.sandbox.paypal.com/v1/oauth2/token"
data = "grant_type=client_credentials"
headers = {
"Accept": "application/json",
"Accept-Language": "en_US",
}

response = requests.request(
method="POST",
url=token_refresh_endpoint,
data=data,
headers=headers,
auth=(client_id, secret),
)
response_json = response.json()
print(response_json)
API_TOKEN = response_json["access_token"]

# CREATE TRANSACTIONS
# for i in range(1000):
# create_response = requests.post(
# "https://api-m.sandbox.paypal.com/v2/checkout/orders",
# headers={'content-type': 'application/json', 'authorization': f'Bearer {API_TOKEN}', "prefer": "return=representation"},
# json={
# "intent": "CAPTURE",
# "purchase_units": [
# {
# "amount": {
# "currency_code": "USD",
# "value": f"{float(i)}"
# }
# }
# ]
# }
# )
#
# print(create_response.json())

# %% LIST TRANSACTIONS

url = "https://api-m.sandbox.paypal.com/v1/reporting/transactions"

params = {
"start_date": "2021-06-20T00:00:00+00:00",
"end_date": "2021-07-10T07:19:45Z",
"fields": "all",
"page_size": "100",
"page": "1",
}

headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json",
}
response = requests.get(
url,
headers=headers,
params=params,
)

pprint(response.json())
Loading