fivetran-connector-sdk 0.12.17.1__py3-none-any.whl → 0.13.10.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fivetran_connector_sdk/__init__.py +62 -20
- {fivetran_connector_sdk-0.12.17.1.dist-info → fivetran_connector_sdk-0.13.10.1.dist-info}/METADATA +2 -2
- {fivetran_connector_sdk-0.12.17.1.dist-info → fivetran_connector_sdk-0.13.10.1.dist-info}/RECORD +6 -6
- {fivetran_connector_sdk-0.12.17.1.dist-info → fivetran_connector_sdk-0.13.10.1.dist-info}/WHEEL +1 -1
- {fivetran_connector_sdk-0.12.17.1.dist-info → fivetran_connector_sdk-0.13.10.1.dist-info}/entry_points.txt +0 -0
- {fivetran_connector_sdk-0.12.17.1.dist-info → fivetran_connector_sdk-0.13.10.1.dist-info}/top_level.txt +0 -0
| @@ -26,7 +26,8 @@ from fivetran_connector_sdk.protos import common_pb2 | |
| 26 26 | 
             
            from fivetran_connector_sdk.protos import connector_sdk_pb2
         | 
| 27 27 | 
             
            from fivetran_connector_sdk.protos import connector_sdk_pb2_grpc
         | 
| 28 28 |  | 
| 29 | 
            -
             | 
| 29 | 
            +
            # Version format: <major_version>.<MM>.<DD>.<iteration> (where MM is incremental value from Jan 2024)
         | 
| 30 | 
            +
            __version__ = "0.13.10.1"
         | 
| 30 31 |  | 
| 31 32 | 
             
            MAC_OS = "mac"
         | 
| 32 33 | 
             
            WIN_OS = "windows"
         | 
| @@ -465,7 +466,6 @@ def log_unused_deps_error(package_name: str, version: str): | |
| 465 466 | 
             
                print_library_log(f"Please remove `{package_name}` from requirements.txt."
         | 
| 466 467 | 
             
                      f" The latest version of `{package_name}` is always available when executing your code."
         | 
| 467 468 | 
             
                      f" Current version: {version}", Logging.Level.SEVERE)
         | 
| 468 | 
            -
                os._exit(1)
         | 
| 469 469 |  | 
| 470 470 |  | 
| 471 471 | 
             
            def validate_deploy_parameters(connection, deploy_key):
         | 
| @@ -574,7 +574,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 574 574 | 
             
                            print_library_log(f"Invalid requirement format: '{requirement}'", Logging.Level.SEVERE)
         | 
| 575 575 | 
             
                    return requirements_dict
         | 
| 576 576 |  | 
| 577 | 
            -
                def validate_requirements_file(self, project_path: str, is_deploy: bool):
         | 
| 577 | 
            +
                def validate_requirements_file(self, project_path: str, is_deploy: bool, force: bool = False):
         | 
| 578 578 | 
             
                    """Validates the `requirements.txt` file against the project's actual dependencies.
         | 
| 579 579 |  | 
| 580 580 | 
             
                    This method generates a temporary requirements file using `pipreqs`, compares
         | 
| @@ -585,10 +585,22 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 585 585 | 
             
                    Args:
         | 
| 586 586 | 
             
                        project_path (str): The path to the project directory containing the `requirements.txt`.
         | 
| 587 587 | 
             
                        is_deploy (bool): If `True`, the method will exit the process on critical errors.
         | 
| 588 | 
            +
                        force (bool): Force update an existing connection.
         | 
| 588 589 |  | 
| 589 590 | 
             
                    """
         | 
| 590 | 
            -
                     | 
| 591 | 
            -
             | 
| 591 | 
            +
                    # Run the pipreqs command and capture stderr
         | 
| 592 | 
            +
                    result = subprocess.run(
         | 
| 593 | 
            +
                        ["pipreqs", "--savepath", "tmp_requirements.txt", "--ignore"] + EXCLUDED_PIPREQS_DIRS,
         | 
| 594 | 
            +
                        stderr=subprocess.PIPE,
         | 
| 595 | 
            +
                        text=True  # Ensures output is in string format
         | 
| 596 | 
            +
                    )
         | 
| 597 | 
            +
             | 
| 598 | 
            +
                    if result.returncode != 0:
         | 
| 599 | 
            +
                        print_library_log("pipreqs failed with:", Logging.Level.SEVERE)
         | 
| 600 | 
            +
                        print(result.stderr)
         | 
| 601 | 
            +
                        sys.exit(1)
         | 
| 602 | 
            +
             | 
| 603 | 
            +
                    # tmp_requirements is only generated when pipreqs command is successful
         | 
| 592 604 | 
             
                    tmp_requirements_file_path = os.path.join(project_path, 'tmp_requirements.txt')
         | 
| 593 605 |  | 
| 594 606 | 
             
                    tmp_requirements = self.fetch_requirements_as_dict(self, tmp_requirements_file_path)
         | 
| @@ -597,6 +609,11 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 597 609 | 
             
                        tmp_requirements.pop("requests")
         | 
| 598 610 | 
             
                    os.remove(tmp_requirements_file_path)
         | 
| 599 611 |  | 
| 612 | 
            +
                    # remove corrupt requirements listed by pipreqs
         | 
| 613 | 
            +
                    corrupt_requirements = [key for key in tmp_requirements if key.startswith("~")]
         | 
| 614 | 
            +
                    for requirement in corrupt_requirements:
         | 
| 615 | 
            +
                        del tmp_requirements[requirement]
         | 
| 616 | 
            +
             | 
| 600 617 | 
             
                    if len(tmp_requirements) > 0:
         | 
| 601 618 | 
             
                        requirements = self.load_or_add_requirements_file(project_path)
         | 
| 602 619 |  | 
| @@ -609,11 +626,26 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 609 626 |  | 
| 610 627 | 
             
                        missing_deps = {key: tmp_requirements[key] for key in (tmp_requirements.keys() - requirements.keys())}
         | 
| 611 628 | 
             
                        if missing_deps:
         | 
| 612 | 
            -
                            self.handle_missing_deps( | 
| 629 | 
            +
                            self.handle_missing_deps(missing_deps)
         | 
| 613 630 |  | 
| 614 631 | 
             
                        unused_deps = list(requirements.keys() - tmp_requirements.keys())
         | 
| 615 632 | 
             
                        if unused_deps:
         | 
| 616 633 | 
             
                            self.handle_unused_deps(unused_deps)
         | 
| 634 | 
            +
             | 
| 635 | 
            +
                        if is_deploy and (version_mismatch_deps or missing_deps or unused_deps):
         | 
| 636 | 
            +
                            if force:
         | 
| 637 | 
            +
                                confirm = "y"
         | 
| 638 | 
            +
                            else:
         | 
| 639 | 
            +
                                confirm = input("We detected issues in your requirements.txt. "
         | 
| 640 | 
            +
                                                "Would you like us to update it to reflect the necessary changes? (Y/N):")
         | 
| 641 | 
            +
                            if confirm.lower() == "y":
         | 
| 642 | 
            +
                                with open(REQUIREMENTS_TXT, "w") as file:
         | 
| 643 | 
            +
                                    file.write("\n".join(tmp_requirements.values()))
         | 
| 644 | 
            +
                                print_library_log(f"`{REQUIREMENTS_TXT}` has been updated successfully")
         | 
| 645 | 
            +
                            else:
         | 
| 646 | 
            +
                                if missing_deps or 'fivetran_connector_sdk' in unused_deps or 'requests' in unused_deps:
         | 
| 647 | 
            +
                                    print_library_log(f"Please fix your {REQUIREMENTS_TXT} file to proceed with deployment.")
         | 
| 648 | 
            +
                                    os._exit(1)
         | 
| 617 649 | 
             
                    else:
         | 
| 618 650 | 
             
                        if os.path.exists(REQUIREMENTS_TXT):
         | 
| 619 651 | 
             
                            print_library_log("`requirements.txt` is not required as no additional "
         | 
| @@ -632,15 +664,13 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 632 664 | 
             
                              "they are not used or already installed. Please remove them from requirements.txt:")
         | 
| 633 665 | 
             
                        print(*unused_deps)
         | 
| 634 666 |  | 
| 635 | 
            -
                def handle_missing_deps(self,  | 
| 667 | 
            +
                def handle_missing_deps(self, missing_deps):
         | 
| 636 668 | 
             
                    print_library_log("Please include the following dependency libraries in requirements.txt, to be used by "
         | 
| 637 669 | 
             
                          "Fivetran production. "
         | 
| 638 670 | 
             
                          "For more information, please visit: "
         | 
| 639 671 | 
             
                          "https://fivetran.com/docs/connectors/connector-sdk/detailed-guide"
         | 
| 640 672 | 
             
                          "#workingwithrequirementstxtfile", Logging.Level.SEVERE)
         | 
| 641 673 | 
             
                    print(*list(missing_deps.values()))
         | 
| 642 | 
            -
                    if is_deploy:
         | 
| 643 | 
            -
                        os._exit(1)
         | 
| 644 674 |  | 
| 645 675 | 
             
                def load_or_add_requirements_file(self, project_path):
         | 
| 646 676 | 
             
                    if os.path.exists(REQUIREMENTS_TXT):
         | 
| @@ -685,7 +715,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 685 715 | 
             
                        "custom_payloads": [],
         | 
| 686 716 | 
             
                    }
         | 
| 687 717 |  | 
| 688 | 
            -
                    self.validate_requirements_file(project_path, True)
         | 
| 718 | 
            +
                    self.validate_requirements_file(project_path, True, force)
         | 
| 689 719 |  | 
| 690 720 | 
             
                    group_id, group_name = self.__get_group_info(group, deploy_key)
         | 
| 691 721 | 
             
                    connection_id, service = self.__get_connection_id(connection, group, group_id, deploy_key) or (None, None)
         | 
| @@ -1253,6 +1283,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 1253 1283 | 
             
                    else:
         | 
| 1254 1284 | 
             
                        try:
         | 
| 1255 1285 | 
             
                            configuration = self.configuration if self.configuration else request.configuration
         | 
| 1286 | 
            +
                            print_library_log("Initiating the 'schema' method call...", Logging.Level.WARNING)
         | 
| 1256 1287 | 
             
                            response = self.schema_method(configuration)
         | 
| 1257 1288 | 
             
                            self.process_tables(response)
         | 
| 1258 1289 | 
             
                            return connector_sdk_pb2.SchemaResponse(without_schema=common_pb2.TableList(tables=TABLES.values()))
         | 
| @@ -1260,6 +1291,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 1260 1291 | 
             
                        except Exception as e:
         | 
| 1261 1292 | 
             
                            tb = traceback.format_exc()
         | 
| 1262 1293 | 
             
                            error_message = f"Error: {str(e)}\n{tb}"
         | 
| 1294 | 
            +
                            print_library_log(error_message, Logging.Level.SEVERE)
         | 
| 1263 1295 | 
             
                            raise RuntimeError(error_message) from e
         | 
| 1264 1296 |  | 
| 1265 1297 | 
             
                def process_tables(self, response):
         | 
| @@ -1358,6 +1390,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 1358 1390 | 
             
                    state = self.state if self.state else json.loads(request.state_json)
         | 
| 1359 1391 |  | 
| 1360 1392 | 
             
                    try:
         | 
| 1393 | 
            +
                        print_library_log("Initiating the 'update' method call...", Logging.Level.WARNING)
         | 
| 1361 1394 | 
             
                        for resp in self.update_method(configuration=configuration, state=state):
         | 
| 1362 1395 | 
             
                            if isinstance(resp, list):
         | 
| 1363 1396 | 
             
                                for r in resp:
         | 
| @@ -1372,6 +1405,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer): | |
| 1372 1405 | 
             
                    except Exception as e:
         | 
| 1373 1406 | 
             
                        tb = traceback.format_exc()
         | 
| 1374 1407 | 
             
                        error_message = f"Error: {str(e)}\n{tb}"
         | 
| 1408 | 
            +
                        print_library_log(error_message, Logging.Level.SEVERE)
         | 
| 1375 1409 | 
             
                        raise RuntimeError(error_message) from e
         | 
| 1376 1410 |  | 
| 1377 1411 |  | 
| @@ -1387,19 +1421,24 @@ def find_connector_object(project_path) -> Connector: | |
| 1387 1421 | 
             
                sys.path.append(project_path) # Allows python interpreter to search for modules in this path
         | 
| 1388 1422 | 
             
                module_name = "connector_connector_code"
         | 
| 1389 1423 | 
             
                connector_py = os.path.join(project_path, "connector.py")
         | 
| 1390 | 
            -
                 | 
| 1391 | 
            -
             | 
| 1392 | 
            -
             | 
| 1393 | 
            -
             | 
| 1394 | 
            -
             | 
| 1395 | 
            -
                     | 
| 1396 | 
            -
                         | 
| 1397 | 
            -
             | 
| 1398 | 
            -
                             | 
| 1424 | 
            +
                try:
         | 
| 1425 | 
            +
                    spec = importlib.util.spec_from_file_location(module_name, connector_py)
         | 
| 1426 | 
            +
                    module = importlib.util.module_from_spec(spec)
         | 
| 1427 | 
            +
                    sys.modules[module_name] = module
         | 
| 1428 | 
            +
                    spec.loader.exec_module(module)
         | 
| 1429 | 
            +
                    for obj in dir(module):
         | 
| 1430 | 
            +
                        if not obj.startswith('__'):  # Exclude built-in attributes
         | 
| 1431 | 
            +
                            obj_attr = getattr(module, obj)
         | 
| 1432 | 
            +
                            if '<fivetran_connector_sdk.Connector object at' in str(obj_attr):
         | 
| 1433 | 
            +
                                return obj_attr
         | 
| 1434 | 
            +
                except FileNotFoundError:
         | 
| 1435 | 
            +
                    print_library_log(
         | 
| 1436 | 
            +
                        "The connector object is missing in the current directory. Please ensure that you are running the command from correct directory or that you have defined a connector object using the correct syntax in your `connector.py` file. Reference: https://fivetran.com/docs/connectors/connector-sdk/technical-reference#technicaldetailsrequiredobjectconnector", Logging.Level.SEVERE)
         | 
| 1437 | 
            +
                    return
         | 
| 1399 1438 |  | 
| 1400 1439 | 
             
                print_library_log(
         | 
| 1401 1440 | 
             
                    "The connector object is missing. Please ensure that you have defined a connector object using the correct syntax in your `connector.py` file. Reference: https://fivetran.com/docs/connectors/connector-sdk/technical-reference#technicaldetailsrequiredobjectconnector", Logging.Level.SEVERE)
         | 
| 1402 | 
            -
                 | 
| 1441 | 
            +
                return
         | 
| 1403 1442 |  | 
| 1404 1443 |  | 
| 1405 1444 | 
             
            def suggest_correct_command(input_command: str) -> bool:
         | 
| @@ -1490,6 +1529,9 @@ def main(): | |
| 1490 1529 |  | 
| 1491 1530 | 
             
                connector_object = find_connector_object(args.project_path)
         | 
| 1492 1531 |  | 
| 1532 | 
            +
                if not connector_object:
         | 
| 1533 | 
            +
                    sys.exit(1)
         | 
| 1534 | 
            +
             | 
| 1493 1535 | 
             
                # Process optional args
         | 
| 1494 1536 | 
             
                ft_group = args.destination if args.destination else os.getenv('FIVETRAN_DESTINATION_NAME', None)
         | 
| 1495 1537 | 
             
                ft_connection = args.connection if args.connection else os.getenv('FIVETRAN_CONNECTION_NAME', None)
         | 
    
        {fivetran_connector_sdk-0.12.17.1.dist-info → fivetran_connector_sdk-0.13.10.1.dist-info}/METADATA
    RENAMED
    
    | @@ -1,6 +1,6 @@ | |
| 1 | 
            -
            Metadata-Version: 2. | 
| 1 | 
            +
            Metadata-Version: 2.2
         | 
| 2 2 | 
             
            Name: fivetran_connector_sdk
         | 
| 3 | 
            -
            Version: 0. | 
| 3 | 
            +
            Version: 0.13.10.1
         | 
| 4 4 | 
             
            Summary: Build custom connectors on Fivetran platform
         | 
| 5 5 | 
             
            Author-email: Fivetran <developers@fivetran.com>
         | 
| 6 6 | 
             
            Project-URL: Homepage, https://fivetran.com/docs/connectors/connector-sdk
         | 
    
        {fivetran_connector_sdk-0.12.17.1.dist-info → fivetran_connector_sdk-0.13.10.1.dist-info}/RECORD
    RENAMED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            fivetran_connector_sdk/__init__.py,sha256= | 
| 1 | 
            +
            fivetran_connector_sdk/__init__.py,sha256=aNnhjs8yhMMKuUuHSHmX8_eLIazUoZ3xvh2RKBt87lw,66462
         | 
| 2 2 | 
             
            fivetran_connector_sdk/protos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
         | 
| 3 3 | 
             
            fivetran_connector_sdk/protos/common_pb2.py,sha256=kUwVcyZHgLigNR-KnHZn7dHrlxaMnUXqzprsRx6T72M,6831
         | 
| 4 4 | 
             
            fivetran_connector_sdk/protos/common_pb2.pyi,sha256=S0hdIzoXyyOKD5cjiGeDDLYpQ9J3LjAvu4rCj1JvJWE,9038
         | 
| @@ -6,8 +6,8 @@ fivetran_connector_sdk/protos/common_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXH | |
| 6 6 | 
             
            fivetran_connector_sdk/protos/connector_sdk_pb2.py,sha256=9Ke_Ti1s0vAeXapfXT-EryrT2-TSGQb8mhs4gxTpUMk,7732
         | 
| 7 7 | 
             
            fivetran_connector_sdk/protos/connector_sdk_pb2.pyi,sha256=FWYxRgshEF3QDYAE0TM_mv4N2gGvkxCH_uPpxnMc4oA,8406
         | 
| 8 8 | 
             
            fivetran_connector_sdk/protos/connector_sdk_pb2_grpc.py,sha256=ZfJLp4DW7uP4pFOZ74s_wQ6tD3eIPi-08UfnLwe4tzo,7163
         | 
| 9 | 
            -
            fivetran_connector_sdk-0. | 
| 10 | 
            -
            fivetran_connector_sdk-0. | 
| 11 | 
            -
            fivetran_connector_sdk-0. | 
| 12 | 
            -
            fivetran_connector_sdk-0. | 
| 13 | 
            -
            fivetran_connector_sdk-0. | 
| 9 | 
            +
            fivetran_connector_sdk-0.13.10.1.dist-info/METADATA,sha256=0XxsMpZ7hQhZLZhu905A9rqzoMkYi6DbWYg10BsZh6U,2939
         | 
| 10 | 
            +
            fivetran_connector_sdk-0.13.10.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
         | 
| 11 | 
            +
            fivetran_connector_sdk-0.13.10.1.dist-info/entry_points.txt,sha256=uQn0KPnFlQmXJfxlk0tifdNsSXWfVlnAFzNqjXZM_xM,57
         | 
| 12 | 
            +
            fivetran_connector_sdk-0.13.10.1.dist-info/top_level.txt,sha256=-_xk2MFY4psIh7jw1lJePMzFb5-vask8_ZtX-UzYWUI,23
         | 
| 13 | 
            +
            fivetran_connector_sdk-0.13.10.1.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         |