Skip to content

Source Amazon Seller Partner: add stream FbaReplacementsReports #9789

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

Conversation

monai
Copy link
Contributor

@monai monai commented Jan 25, 2022

What

This PR adds stream FbaReplacementsReports (GET_FBA_FULFILLMENT_CUSTOMER_SHIPMENT_REPLACEMENT_DATA).

In addition, the PR updates report generation status handling according to (ProcessingStatuses)[https://developer-docs.amazon.com/sp-api/docs/reports-api-v2020-09-01-reference#processingstatuses] enum as follows:

CANCELED - log a warning message
FAILED - throw an exception

Before this PR, FAILED reports log warning messages and pretend that the report has 0 entries. Meanwhile, the documentation explicitly states that report wasn't generated:

FATAL The report was aborted due to a fatal error.

How

Describe the solution

Recommended reading order

  1. streams.py

🚨 User Impact 🚨

The connector will throw an error for FATAL processing status while previously, the error was silently ignored.

Community member or Airbyter

  • Grant edit access to maintainers (instructions)
  • Secrets in the connector's spec are annotated with airbyte_secret
  • Unit & integration tests added and passing. Community members, please provide proof of success locally e.g: screenshot or copy-paste unit, integration, and acceptance test output. To run acceptance tests for a Python connector, follow instructions in the README. For java connectors run ./gradlew :airbyte-integrations:connectors:<name>:integrationTest.
  • Code reviews completed
  • Documentation updated
    • Connector's README.md
    • Connector's bootstrap.md. See description and examples
    • Changelog updated in docs/integrations/<source or destination>/<name>.md including changelog. See changelog example
  • PR name follows PR naming conventions

Airbyter

If this is a community PR, the Airbyte engineer reviewing this PR is responsible for the below items.

  • Create a non-forked branch based on this PR and test the below items on it
  • Build is successful
  • Credentials added to Github CI. Instructions.
  • /test connector=connectors/<name> command is passing.
  • New Connector version released on Dockerhub by running the /publish command described here
  • After the new connector version is published, connector version bumped in the seed directory as described here
  • Seed specs have been re-generated by building the platform and committing the changes to the seed spec files, as described here

@github-actions github-actions bot added the area/connectors Connector related issues label Jan 25, 2022
@github-actions github-actions bot added the area/documentation Improvements or additions to documentation label Jan 25, 2022
@marcosmarxm
Copy link
Member

The code looks great @monai can you share the output from ./gradlew airbyte-integrations:connectors:source-amazon-sp:integrationTest? You can disable the other reports and only run the one you'd added.

@marcosmarxm marcosmarxm self-assigned this Jan 26, 2022
@monai
Copy link
Contributor Author

monai commented Jan 26, 2022

connector_image: airbyte/source-amazon-seller-partner:dev
tests:
  spec:
    - spec_path: "source_amazon_seller_partner/spec.json"
  connection:
    # - config_path: "secrets/config.json"
    #   status: "succeed"
    #   timeout_seconds: 60
    - config_path: "integration_tests/invalid_config.json"
      status: "failed"
      timeout_seconds: 60
  discovery:
    - config_path: "secrets/config.json"
# TODO: uncomment when at least one record exist
  basic_read:
#    - config_path: "secrets/config.json"
#      configured_catalog_path: "integration_tests/configured_catalog.json"
#      empty_streams:
#        [
#          "Orders",
#          "GET_FLAT_FILE_ALL_ORDERS_DATA_BY_ORDER_DATE_GENERAL",
#          "GET_MERCHANT_LISTINGS_ALL_DATA",
#          "GET_FBA_INVENTORY_AGED_DATA",
#          "GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL",
#          "GET_FLAT_FILE_OPEN_LISTINGS_DATA",
#          "GET_FBA_FULFILLMENT_REMOVAL_ORDER_DETAIL_DATA",
#          "GET_FBA_FULFILLMENT_REMOVAL_SHIPMENT_DETAIL_DATA",
#          "GET_VENDOR_INVENTORY_HEALTH_AND_PLANNING_REPORT",
#          "VendorDirectFulfillmentShipping",
#        ]
#    - config_path: "secrets/config.json"
#      configured_catalog_path: "integration_tests/configured_catalog_brand_analytics_alternate_purchase.json"
#    - config_path: "secrets/config.json"
#      configured_catalog_path: "integration_tests/configured_catalog_brand_analytics_item_comparison.json"
#    - config_path: "secrets/config.json"
#      configured_catalog_path: "integration_tests/configured_catalog_brand_analytics_market_basket.json"
#    - config_path: "secrets/config.json"
#      configured_catalog_path: "integration_tests/configured_catalog_brand_analytics_repeat_purchase.json.json"
#    - config_path: "secrets/config.json"
#      configured_catalog_path: "integration_tests/configured_catalog_brand_analytics_search_terms.json"
    - config_path: "secrets/config.json"
      configured_catalog_path: "integration_tests/configured_catalog_fba_fulfillment_customer_shipment_replacement_data.json"
# TODO: uncomment when Orders (or any other incremental) stream is filled with data
#  incremental:
#   - config_path: "secrets/config.json"
#     configured_catalog_path: "integration_tests/configured_catalog.json"
#     future_state_path: "integration_tests/future_state.json"
#     cursor_paths:
#       Orders: ["LastUpdateDate"]
#  full_refresh:
#   - config_path: "secrets/config.json"
#     configured_catalog_path: "integration_tests/configured_catalog.json"
Test session starts (platform: darwin, Python 3.9.10, pytest 6.1.2, pytest-sugar 0.9.4)
cachedir: .pytest_cache
rootdir: /Users/juozas/projects/lt/airbyte, configfile: pytest.ini
plugins: cov-2.12.1, sugar-0.9.4, mock-3.6.1, timeout-1.4.2
collecting ...
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_match_expected[inputs0] ✓                                                                                                8% ▉
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_required[inputs0] ✓                                                                                                     17% █▋
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_optional[inputs0] ✓                                                                                                     25% ██▌
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_has_secret[inputs0] ✓                                                                                                   33% ███▍
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_secret_never_in_the_output[inputs0] ✓                                                                                   42% ████▎
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_defined_refs_exist_in_json_spec_file[inputs0] ✓                                                                         50% █████
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_oauth_flow_parameters[inputs0] ✓                                                                                        58% █████▉
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestConnection.test_check[inputs0] ✓                                                                                                  67% ██████▋
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_discover[inputs0] ✓                                                                                                75% ███████▌
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_defined_cursors_exist_in_schema[inputs0] ✓                                                                         83% ████████▍
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_defined_refs_exist_in_schema[inputs0] ✓                                                                            92% █████████▎
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestBasicRead.test_read[inputs0] ✓                                                                                                   100% ██████████
============================================================================================================ short test summary info =============================================================================================================
SKIPPED [1] ../../bases/source-acceptance-test/source_acceptance_test/plugin.py:56: Skipping TestFullRefresh.test_sequential_reads because not found in the config
SKIPPED [1] ../../bases/source-acceptance-test/source_acceptance_test/plugin.py:56: Skipping TestIncremental.test_two_sequential_reads because not found in the config

Results (72.48s):
      12 passed

@alafanechere alafanechere mentioned this pull request Feb 3, 2022
@alafanechere
Copy link
Contributor

Hi @monai, the acceptance tests are failing because of some missing modules: https://github.com/airbytehq/airbyte/actions/runs/1791101084

@monai
Copy link
Contributor Author

monai commented Feb 8, 2022

@alafanechere I've just merged master into this branch, recreated virtualenv, and run unit tests locally. Everything is fine. I guess this issue is related to CI environment.

However, it looks like #9768 broke the acceptance tests. See attached log. The PR was merged 12 days ago, and the line in question is five months old.

~/projects/lt/airbyte/airbyte-integrations/connectors/source-amazon-seller-partner (amazon-sp-GET_FBA_FULFILLMENT_CUSTOMER_SHIPMENT_REPLACEMENT_DATA) [m] python -m pytest -p integration_tests.acceptance        [.venv]
Test session starts (platform: darwin, Python 3.9.9, pytest 6.2.5, pytest-sugar 0.9.4)
cachedir: .pytest_cache
rootdir: /Users/juozas/projects/lt/airbyte, configfile: pytest.ini
plugins: sugar-0.9.4, mock-3.7.0, timeout-1.4.2
collecting ...
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_config_match_spec[inputs0] ✓                                                                     6% ▋
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_match_expected[inputs0] ✓                                                                       12% █▎
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_docker_env[inputs0] ✓                                                                           18% █▊
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_oneof_usage[inputs0] ✓                                                                          24% ██▍
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_required[inputs0] ✓                                                                             29% ██▉
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_optional[inputs0] ✓                                                                             35% ███▌
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_has_secret[inputs0] ✓                                                                           41% ████▎
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_secret_never_in_the_output[inputs0] ✓                                                           47% ████▊
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_defined_refs_exist_in_json_spec_file[inputs0] ✓                                                 53% █████▍
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestSpec.test_oauth_flow_parameters[inputs0] ✓                                                                59% █████▉
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestConnection.test_check[inputs0] ✓                                                                          65% ██████▌
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_discover[inputs0] ✓                                                                        71% ███████▏
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_defined_cursors_exist_in_schema[inputs0] ✓                                                 76% ███████▋
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_defined_refs_exist_in_schema[inputs0] ✓                                                    82% ████████▎
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_defined_keyword_exist_in_schema[inputs0-allOf] ✓                                           88% ████████▉
 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_defined_keyword_exist_in_schema[inputs0-not] ✓                                             94% █████████▌

―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― TestDiscovery.test_primary_keys_exist_in_schema[inputs0] ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――

self = <source_acceptance_test.tests.test_core.TestDiscovery object at 0x112dc6430>
discovered_catalog = {'GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL': AirbyteStream(name='GET_AMAZON_FULFILLED_SHIPMENTS_DATA_GENERAL', json...fresh'>], source_defined_cursor=None, default_cursor_field=None, source_defined_primary_key=None, namespace=None), ...}

    def test_primary_keys_exist_in_schema(self, discovered_catalog: Mapping[str, Any]):
        """Check that all primary keys are present in catalog."""
        for stream_name, stream in discovered_catalog.items():
            for pk in stream.source_defined_primary_key or []:
                schema = stream.json_schema
                pk_path = "/properties/".join(pk)
                pk_field_location = dpath.util.search(schema["properties"], pk_path)
>               assert pk_field_location, f"One of the PKs ({pk}) is not specified in discover schema for {stream_name} stream"
E               AssertionError: One of the PKs (['labelData', 'packageIdentifier']) is not specified in discover schema for VendorDirectFulfillmentShipping stream
E               assert {}

../../bases/source-acceptance-test/source_acceptance_test/tests/test_core.py:218: AssertionError

 airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery.test_primary_keys_exist_in_schema[inputs0] ⨯                                                   100% ██████████
================================================================================================ short test summary info =================================================================================================
SKIPPED [1] ../../bases/source-acceptance-test/source_acceptance_test/plugin.py:56: Skipping TestBasicRead.test_read because not found in the config
SKIPPED [1] ../../bases/source-acceptance-test/source_acceptance_test/plugin.py:56: Skipping TestFullRefresh.test_sequential_reads because not found in the config
SKIPPED [1] ../../bases/source-acceptance-test/source_acceptance_test/plugin.py:56: Skipping TestIncremental.test_two_sequential_reads because not found in the config
FAILED ../../bases/source-acceptance-test/source_acceptance_test/tests/test_core.py::TestDiscovery::test_primary_keys_exist_in_schema[inputs0] - AssertionError: One of the PKs (['labelData', 'packageIdentifier']) is...

Results (13.75s):
      16 passed
       1 failed
         - airbyte-integrations/bases/source-acceptance-test/source_acceptance_test/tests/test_core.py:211 TestDiscovery.test_primary_keys_exist_in_schema[inputs0]

@marcosmarxm
Copy link
Member

@monai this error looks from a nested cursor field. We need to fix it.

@monai
Copy link
Contributor Author

monai commented Feb 14, 2022

It turns out the current primary_key property in the stream VendorDirectFulfillmentShipping is flawed. It point's to a key of an object in an array of objects. It doesn't make any sense. So I fixed the error by setting the primary_key = None. In addition, the source data object ShippingLabel doesn't appear to have any uniquely identifying property, and the stream is full refresh, so primary_key isn't used at all.

@monai
Copy link
Contributor Author

monai commented Feb 17, 2022

@alafanechere the PR is ready for review.

@alafanechere alafanechere temporarily deployed to more-secrets February 21, 2022 20:48 Inactive
@octavia-squidington-iii octavia-squidington-iii temporarily deployed to more-secrets February 21, 2022 20:49 Inactive
@octavia-squidington-iii octavia-squidington-iii temporarily deployed to more-secrets February 22, 2022 21:33 Inactive
@alafanechere
Copy link
Contributor

@monai, thanks again for this quality contribution! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/connectors Connector related issues area/documentation Improvements or additions to documentation community
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants