Skip to content

Commit d3a0985

Browse files
Jgerardopinegirardaalafanechere
authored andcommitted
✨ Source Paypal Transactions: Siver Certification (airbytehq#34510)
Co-authored-by: Alexandre Girard <[email protected]> Co-authored-by: alafanechere <[email protected]> Co-authored-by: Augustin <[email protected]>
1 parent 1cb5521 commit d3a0985

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+4471
-248
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[run]
2+
omit =
3+
source_paypal_transaction/run.py

airbyte-integrations/connectors/source-paypal-transaction/CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@
22

33
## 0.1.0
44
Source implementation with support of Transactions and Balances streams
5+
6+
## 1.0.0
7+
Mark Client ID and Client Secret as required files
8+
9+
## 2.1.0
10+
Migration to Low code
11+
12+
## 2.3.0
13+
Adding New Streams - Payments, Disputes, Invoices, Product Catalog

airbyte-integrations/connectors/source-paypal-transaction/README.md

+130-8
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,89 @@
11
# Paypal-Transaction source connector
22

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

76
## Local development
87

9-
### Prerequisites
10-
* Python (~=3.9)
11-
* Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation)
128

9+
#### Prerequisites
10+
* Python (~=3.9)
11+
* Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation)
12+
* Paypal Client ID and Client Secret
13+
* If you are going to use the data generator scripts you need to setup yourPaypal Sandbox and a Buyer user in your sandbox, to simulate the data. YOu cna get that information in the [Apps & Credentials page](https://developer.paypal.com/dashboard/applications/live).
14+
* Buyer Username
15+
* Buyer Password
16+
* Payer ID (Account ID)
1317

1418
### Installing the connector
19+
1520
From this connector directory, run:
1621
```bash
1722
poetry install --with dev
1823
```
1924

20-
2125
### Create credentials
26+
2227
**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/paypal-transaction)
2328
to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_paypal_transaction/spec.yaml` file.
2429
Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information.
2530
See `sample_files/sample_config.json` for a sample config file.
2631

32+
* You must have created your credentials under the `secrets/` folder
33+
* For the read command, you can create separate catalogs to test the streams individually. All catalogs are under the folder `integration_tests`. Select the one you want to test with the read command.
34+
2735

2836
### Locally running the connector
37+
2938
```
3039
poetry run source-paypal-transaction spec
3140
poetry run source-paypal-transaction check --config secrets/config.json
3241
poetry run source-paypal-transaction discover --config secrets/config.json
33-
poetry run source-paypal-transaction read --config secrets/config.json --catalog sample_files/configured_catalog.json
42+
#Example with list_payments catalog and the debug flag
43+
poetry run source-paypal-transaction read --config secrets/config.json --catalog integration_tests/configured_catalog_list_payments.json --debug
3444
```
3545

3646
### Running unit tests
3747
To run unit tests locally, from the connector directory run:
48+
3849
```
3950
poetry run pytest unit_tests
4051
```
4152

4253
### Building the docker image
54+
4355
1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md)
4456
2. Run the following command to build the docker image:
57+
58+
59+
### Installing the connector
60+
From this connector directory, run:
4561
```bash
46-
airbyte-ci connectors --name=source-paypal-transaction build
62+
poetry install --with dev
63+
```
64+
65+
##### Customizing our build process
66+
When contributing on our connector you might need to customize the build process to add a system dependency or set an env var.
67+
You can customize our build process by adding a `build_customization.py` module to your connector.
68+
This module should contain a `pre_connector_install` and `post_connector_install` async function that will mutate the base image and the connector container respectively.
69+
It will be imported at runtime by our build process and the functions will be called if they exist.
70+
71+
Here is an example of a `build_customization.py` module:
72+
```python
73+
from __future__ import annotations
74+
75+
from typing import TYPE_CHECKING
76+
77+
if TYPE_CHECKING:
78+
# Feel free to check the dagger documentation for more information on the Container object and its methods.
79+
# https://dagger-io.readthedocs.io/en/sdk-python-v0.6.4/
80+
from dagger import Container
4781
```
4882

4983
An image will be available on your host with the tag `airbyte/source-paypal-transaction:dev`.
5084

5185

86+
5287
### Running as a docker container
5388
Then run any of the connector commands as follows:
5489
```
@@ -58,23 +93,110 @@ docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-paypal-transaction:dev
5893
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
5994
```
6095

96+
6197
### Running our CI test suite
98+
6299
You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md):
100+
63101
```bash
64102
airbyte-ci connectors --name=source-paypal-transaction test
65103
```
66104

105+
If you are testing locally, you can use your local credentials (config.json file) by using `--use-local-secrets`
106+
107+
```bash
108+
airbyte-ci connectors --name source-paypal-transaction --use-local-secrets test
109+
```
110+
67111
### Customizing acceptance Tests
68112
Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information.
69113
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.
70114

71-
### Dependency Management
115+
116+
## Running Unit tests locally
117+
118+
To run unit tests locally, form the root `source_paypal_transaction` directory run:
119+
120+
```bash
121+
python -m pytest unit_test
122+
```
123+
124+
## Test changes in the sandbox
125+
126+
If you have a [Paypal Sandbox](https://developer.paypal.com/tools/sandbox/accounts/) you will be able to use some APIs to create new data and test how data is being created in your destinaiton and choose the best syn strategy that suits better your use case.
127+
Some endpoints will require special permissions on the sandbox to update and change some values.
128+
129+
In the `bin` folder you will find several data generator scripts:
130+
131+
* **disputes_generator.py:**
132+
* Update dispute: Uses the _PATCH_ method of the `https://api-m.paypal.com/v1/customer/disputes/{dispute_id}` endpoint. You need the ID and create a payload to pass it as an argument. See more information [here](https://developer.paypal.com/docs/api/customer-disputes/v1/#disputes_patch).
133+
134+
```bash
135+
python disputes_generator.py update DISPUTE_ID ''[{"op": "replace", "path": "/reason", "value": "The new reason"}]'
136+
```
137+
138+
* Update Evidence status: Uses the _POST_ method of the `https://api-m.paypal.com/v1/customer/disputes/{dispute_id}/require-evidence` endpoint. You need the ID and select an option to pass it as an argument. See more information [here](https://developer.paypal.com/docs/api/customer-disputes/v1/#disputes_require-evidence)
139+
```bash
140+
python update_dispute.py require-evidence DISPUTE_ID SELLER_EVIDENCE
141+
```
142+
143+
* **invoices.py:**
144+
* Create draft invoice: Uses the _POST_ method of the `https://api-m.sandbox.paypal.com/v2/invoicing/invoices` endpoint. It will automatically generate an invoice (no need to pass any parameters). See more information [here](https://developer.paypal.com/docs/api/invoicing/v2/#invoices_create).
145+
146+
```bash
147+
python invoices.py create_draft
148+
```
149+
150+
* Send a Draft Invoice: Uses the _POST_ method of the `https://api-m.sandbox.paypal.com/v2/invoicing/invoices/{invoice_id}/send` endpoint. You need the Invoice ID, a subject and a note (just to have something to update) and an email as an argument. See more information [here](https://developer.paypal.com/docs/api/invoicing/v2/#invoices_send)
151+
```bash
152+
python invoices.py send_draft --invoice_id "INV2-XXXX-XXXX-XXXX-XXXX" --subject "Your Invoice Subject" --note "Your custom note" --additional_recipients [email protected]
153+
```
154+
155+
* **payments_generator.py:**
156+
* Partially update payment: Uses the _PATCH_ method of the `https://api-m.paypal.com/v1/payments/payment/{payment_id}` endpoint. You need the payment ID and a payload with new values. (no need to pass any parameters). See more information [here](https://developer.paypal.com/docs/api/invoicing/v2/#invoices_create).
157+
158+
```bash
159+
python script_name.py update PAYMENT_ID '[{"op": "replace", "path": "/transactions/0/amount", "value": {"total": "50.00", "currency": "USD"}}]'
160+
```
161+
162+
* **paypal_transaction_generator.py:**
163+
Make sure you have the `buyer_username`, `buyer_password` and `payer_id` in your config file. You can get the sample configuratin in the `sample_config.json`.
164+
165+
* Generate transactions: This uses Selenium, so you will be prompted to your account to simulate the complete transaction flow. You can add a number at the end of the command to do more than one transaction. By default the script runs 3 transactions.
166+
167+
**NOTE: Be midnfu of the number of transactions, as it will be interacting with your machine, and you may not be able to use it while creating the transactions**
168+
169+
```bash
170+
python paypal_transaction_generator.py [NUMBER_OF_DESIRED_TRANSACTIONS]
171+
```
172+
173+
* **product_catalog.py:**
174+
* Create a product: Uses the _POST_ method of the `https://api-m.sandbox.paypal.com/v1/catalogs/products` endpoint. You need to add the description and the category in the command line. For the proper category see more information [here](https://developer.paypal.com/docs/api/catalog-products/v1/#products_create).
175+
176+
```bash
177+
python product_catalog.py --action create --description "YOUR DESCRIPTION" --category PAYPAL_CATEGORY
178+
```
179+
180+
* Update a product: Uses the _PATCH_ method of the `https://developer.paypal.com/docs/api/catalog-products/v1/#products_patch` endpoint. You need the product ID, a description and the Category as an argument. See more information [here](https://developer.paypal.com/docs/api/catalog-products/v1/#products_patch)
181+
```bash
182+
python product_catalog.py --action update --product_id PRODUCT_ID --update_payload '[{"op": "replace", "path": "/description", "value": "My Update. Does it changes it?"}]'
183+
```
184+
185+
## Dependency Management
186+
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.
187+
We split dependencies between two groups, dependencies that are:
188+
* required for your connector to work need to go to `MAIN_REQUIREMENTS` list.
189+
* required for the testing need to go to `TEST_REQUIREMENTS` list
190+
191+
72192
All of your dependencies should be managed via Poetry.
193+
73194
To add a new dependency, run:
74195
```bash
75196
poetry add <package-name>
76197
```
77198
199+
78200
Please commit the changes to `pyproject.toml` and `poetry.lock` files.
79201
80202
## Publishing a new version of the connector
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,84 @@
11
# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference)
22
# for more information about how to configure these tests
3+
# Make sure the paths you have in each path matches with your data.
4+
#For multiple env testing, you can duplicate the tests and change the path to the proper credentials file
35
connector_image: airbyte/source-paypal-transaction:dev
46
test_strictness_level: high
57
acceptance_tests:
68
spec:
79
tests:
10+
#Test with Prod credentials (Make sure you purt the right ones)
811
- spec_path: "source_paypal_transaction/spec.yaml"
9-
config_path: secrets/config_oauth.json
12+
config_path: secrets/config.json
1013
backward_compatibility_tests_config:
1114
disable_for_version: "0.1.13"
1215
connection:
1316
tests:
14-
- config_path: secrets/config_oauth.json
17+
#Test With Prod Credentials
18+
- config_path: secrets/config.json
1519
status: succeed
16-
- config_path: secrets/config_oauth_sandbox.json
17-
status: succeed
18-
- config_path: integration_tests/invalid_config.json
19-
status: failed
20-
- config_path: integration_tests/invalid_config_oauth.json
20+
#Test with Invalid Credentials
21+
- config_path: integration_tests/sample_files/invalid_config.json
2122
status: failed
23+
#Test with Sandbox Credentials
24+
# - config_path: secrets/config_sandbox.json
25+
# status: succeed
2226
discovery:
2327
tests:
24-
- config_path: secrets/config_oauth.json
28+
- config_path: secrets/config.json
29+
# - config_path: secrets/config_sandbox.json
2530
backward_compatibility_tests_config:
2631
disable_for_version: "2.0.0" # Change in cursor field for transactions stream
2732
basic_read:
2833
tests:
29-
- config_path: secrets/config_oauth.json
30-
ignored_fields:
31-
balances:
32-
- name: last_refresh_time
33-
bypass_reason: "field changes during every read"
34+
#Test Prod Environment - Uncomment and change according to your prod setup
35+
#Change the expected records, remember to align them with the timeframe you have selected
36+
#Do not select streams that take more than 5 mins to load data as that can lead to timeouts
37+
#You can comment the lines if you are sure you have data for the below streams.
38+
- config_path: secrets/config.json
39+
# - config_path: secrets/config_sandbox.json
3440
empty_streams:
35-
- name: transactions
36-
bypass_reason: "can not populate"
37-
timeout_seconds: 1200
38-
expect_records:
39-
path: "integration_tests/expected_records.jsonl"
40-
extra_fields: no
41-
exact_order: no
42-
extra_records: yes
43-
- config_path: secrets/config_oauth_sandbox.json
41+
- name: show_product_details
42+
bypass_reason: "Products may not exist"
43+
- name: list_products
44+
bypass_reason: "Product List may be too big causing timeout errors"
45+
- name: search_invoices
46+
bypass_reason: "Order makes the diff fail."
47+
#Have to add for testing PR CI.
48+
- name: list_disputes
49+
bypass_reason: "Disputes may not exist."
4450
ignored_fields:
4551
balances:
4652
- name: last_refresh_time
4753
bypass_reason: "field changes during every read"
48-
timeout_seconds: 1200
54+
list_products:
55+
- name: description
56+
bypass_reason: "Sometimes it is not contained in the response"
57+
timeout_seconds: 3200
4958
expect_records:
50-
path: "integration_tests/expected_records_sandbox.jsonl"
51-
extra_fields: no
52-
exact_order: no
53-
extra_records: yes
54-
fail_on_extra_columns: false
59+
path: "integration_tests/sample_files/expected_records_sandbox.jsonl"
60+
#path: "integration_tests/sample_files/expected_records.jsonl"
61+
extra_fields: yes
62+
exact_order: yes
63+
extra_records: no
64+
fail_on_extra_columns: False
5565
incremental:
5666
tests:
57-
- config_path: secrets/config_oauth.json
58-
configured_catalog_path: integration_tests/configured_catalog.json
67+
- config_path: secrets/config.json
68+
# - config_path: secrets/config_sandbox.json
69+
configured_catalog_path: integration_tests/incremental_catalog.json
5970
future_state:
60-
future_state_path: integration_tests/abnormal_state.json
71+
future_state_path: integration_tests/sample_files/abnormal_state.json
6172
skip_comprehensive_incremental_tests: true
6273
full_refresh:
6374
tests:
64-
- config_path: secrets/config_oauth.json
75+
- config_path: secrets/config.json
76+
# - config_path: secrets/config_sandbox.json
77+
configured_catalog_path: integration_tests/full_refresh_catalog.json
6578
ignored_fields:
6679
balances:
6780
- name: last_refresh_time
6881
bypass_reason: "field changes during every read"
69-
configured_catalog_path: integration_tests/configured_catalog.json
82+
list_products:
83+
- name: description
84+
bypass_reason: "Sometimes it is not contained in the response"

0 commit comments

Comments
 (0)