fivetran-connector-sdk 1.3.4__tar.gz → 1.4.0__tar.gz
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-1.3.4 → fivetran_connector_sdk-1.4.0}/PKG-INFO +1 -1
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/__init__.py +58 -22
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk.egg-info/PKG-INFO +1 -1
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/README.md +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/pyproject.toml +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/setup.cfg +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/protos/__init__.py +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/protos/common_pb2.py +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/protos/common_pb2.pyi +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/protos/common_pb2_grpc.py +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/protos/connector_sdk_pb2.py +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/protos/connector_sdk_pb2.pyi +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/protos/connector_sdk_pb2_grpc.py +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk.egg-info/SOURCES.txt +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk.egg-info/dependency_links.txt +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk.egg-info/entry_points.txt +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk.egg-info/requires.txt +0 -0
- {fivetran_connector_sdk-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fivetran_connector_sdk
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.4.0
|
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-1.3.4 → fivetran_connector_sdk-1.4.0}/src/fivetran_connector_sdk/__init__.py
RENAMED
@@ -32,7 +32,7 @@ from fivetran_connector_sdk.protos import connector_sdk_pb2_grpc
|
|
32
32
|
|
33
33
|
# Version format: <major_version>.<minor_version>.<patch_version>
|
34
34
|
# (where Major Version = 1 for GA, Minor Version is incremental MM from Jan 25 onwards, Patch Version is incremental within a month)
|
35
|
-
__version__ = "1.
|
35
|
+
__version__ = "1.4.0"
|
36
36
|
|
37
37
|
MAC_OS = "mac"
|
38
38
|
WIN_OS = "windows"
|
@@ -110,12 +110,24 @@ class Logging:
|
|
110
110
|
if DEBUGGING:
|
111
111
|
current_time = datetime.now().strftime("%b %d, %Y %I:%M:%S %p")
|
112
112
|
escaped_message = json.dumps(message).strip('"')
|
113
|
-
print(f"{current_time} {level.name}: {escaped_message}")
|
113
|
+
print(f"{Logging._get_color(level)}{current_time} {level.name}: {escaped_message} {Logging._reset_color()}")
|
114
114
|
else:
|
115
115
|
escaped_message = json.dumps(message)
|
116
116
|
log_message = f'{{"level":"{level.name}", "message": {escaped_message}, "message_origin": "connector_sdk"}}'
|
117
117
|
print(log_message)
|
118
118
|
|
119
|
+
@staticmethod
|
120
|
+
def _get_color(level):
|
121
|
+
if level == Logging.Level.WARNING:
|
122
|
+
return "\033[93m" # Yellow
|
123
|
+
elif level == Logging.Level.SEVERE:
|
124
|
+
return "\033[91m" # Red
|
125
|
+
return ""
|
126
|
+
|
127
|
+
@staticmethod
|
128
|
+
def _reset_color():
|
129
|
+
return "\033[0m"
|
130
|
+
|
119
131
|
@staticmethod
|
120
132
|
def fine(message: str):
|
121
133
|
"""Logs a fine-level message.
|
@@ -313,7 +325,7 @@ def check_newer_version():
|
|
313
325
|
latest_version = data["info"]["version"]
|
314
326
|
if __version__ < latest_version:
|
315
327
|
print_library_log(f"[notice] A new release of 'fivetran-connector-sdk' is available: {latest_version}\n" +
|
316
|
-
|
328
|
+
"[notice] To update, run: pip install --upgrade fivetran-connector-sdk\n")
|
317
329
|
|
318
330
|
with open(last_check_file_path, 'w', encoding=UTF_8) as f_out:
|
319
331
|
f_out.write(f"{int(time.time())}")
|
@@ -573,7 +585,7 @@ def print_library_log(message: str, level: Logging.Level = Logging.Level.INFO):
|
|
573
585
|
if DEBUGGING or EXECUTED_VIA_CLI:
|
574
586
|
current_time = datetime.now().strftime("%b %d, %Y %I:%M:%S %p")
|
575
587
|
escaped_message = json.dumps(message).strip('"')
|
576
|
-
print(f"{current_time} {level.name} {LOGGING_PREFIX}: {escaped_message}")
|
588
|
+
print(f"{Logging._get_color(level)}{current_time} {level.name} {LOGGING_PREFIX}: {escaped_message} {Logging._reset_color()}")
|
577
589
|
else:
|
578
590
|
escaped_message = json.dumps(LOGGING_PREFIX + LOGGING_DELIMITER + message)
|
579
591
|
log_message = f'{{"level":"{level.name}", "message": {escaped_message}, "message_origin": "library"}}'
|
@@ -794,6 +806,8 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer):
|
|
794
806
|
|
795
807
|
# tmp_requirements is only generated when pipreqs command is successful
|
796
808
|
tmp_requirements_file_path = os.path.join(project_path, 'tmp_requirements.txt')
|
809
|
+
# copying packages of requirements file to tmp file to handle pipreqs fail use-case
|
810
|
+
self.copy_requirements_file_to_tmp_requirements_file(os.path.join(project_path, REQUIREMENTS_TXT), tmp_requirements_file_path)
|
797
811
|
# Run the pipreqs command and capture stderr
|
798
812
|
attempt = 0
|
799
813
|
while attempt < MAX_RETRIES:
|
@@ -815,13 +829,11 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer):
|
|
815
829
|
time.sleep(retry_after)
|
816
830
|
else:
|
817
831
|
print_library_log(f"pipreqs failed after {MAX_RETRIES} attempts with:", Logging.Level.SEVERE)
|
818
|
-
|
819
|
-
|
832
|
+
print_library_log(result.stderr, Logging.Level.SEVERE)
|
833
|
+
print_library_log(f"Skipping validation of requirements.txt due to error connecting to PyPI (Python Package Index) APIs. Continuing with {'deploy' if is_deploy else 'debug'}...", Logging.Level.SEVERE)
|
820
834
|
|
821
835
|
tmp_requirements = self.fetch_requirements_as_dict(self, tmp_requirements_file_path)
|
822
|
-
|
823
|
-
if tmp_requirements.get('requests') is not None:
|
824
|
-
tmp_requirements.pop("requests")
|
836
|
+
self.remove_unwanted_packages(tmp_requirements)
|
825
837
|
os.remove(tmp_requirements_file_path)
|
826
838
|
|
827
839
|
# remove corrupt requirements listed by pipreqs
|
@@ -894,7 +906,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer):
|
|
894
906
|
if 'requests' in unused_deps:
|
895
907
|
log_unused_deps_error("requests", "2.32.3")
|
896
908
|
print_library_log("The following dependencies are not needed, "
|
897
|
-
f"they are not used or already installed. Please remove them from {REQUIREMENTS_TXT}:")
|
909
|
+
f"they are not used or already installed. Please remove them from {REQUIREMENTS_TXT}:", Logging.Level.WARNING)
|
898
910
|
print(*unused_deps)
|
899
911
|
|
900
912
|
def handle_missing_deps(self, missing_deps):
|
@@ -915,6 +927,19 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer):
|
|
915
927
|
print_library_log("Adding `requirements.txt` file to your project folder.", Logging.Level.WARNING)
|
916
928
|
return requirements
|
917
929
|
|
930
|
+
def copy_requirements_file_to_tmp_requirements_file(self, requirements_file_path: str, tmp_requirements_file_path):
|
931
|
+
requirements_file_content = self.fetch_requirements_from_file(requirements_file_path)
|
932
|
+
with open(tmp_requirements_file_path, 'w') as file:
|
933
|
+
file.write("\n".join(requirements_file_content))
|
934
|
+
|
935
|
+
@staticmethod
|
936
|
+
def remove_unwanted_packages(requirements: dict):
|
937
|
+
# remove the `fivetran_connector_sdk` and `requests` packages from requirements as we already pre-installed them.
|
938
|
+
if requirements.get("fivetran_connector_sdk") is not None:
|
939
|
+
requirements.pop("fivetran_connector_sdk")
|
940
|
+
if requirements.get('requests') is not None:
|
941
|
+
requirements.pop("requests")
|
942
|
+
|
918
943
|
# Call this method to deploy the connector to Fivetran platform
|
919
944
|
def deploy(self, args: dict, deploy_key: str, group: str, connection: str, hd_agent_id: str, configuration: dict = None):
|
920
945
|
"""Deploys the connector to the Fivetran platform.
|
@@ -1188,7 +1213,7 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer):
|
|
1188
1213
|
if INSTALLATION_SCRIPT in files:
|
1189
1214
|
custom_driver_installation_script_exists = True
|
1190
1215
|
for file in files:
|
1191
|
-
if file ==
|
1216
|
+
if file == ROOT_FILENAME:
|
1192
1217
|
connector_file_exists = True
|
1193
1218
|
file_path = os.path.join(root, file)
|
1194
1219
|
arcname = os.path.relpath(file_path, project_path)
|
@@ -1542,10 +1567,10 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer):
|
|
1542
1567
|
|
1543
1568
|
popen = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
|
1544
1569
|
for line in Connector.process_stream(popen.stderr):
|
1545
|
-
yield line
|
1570
|
+
yield Connector._maybe_colorize_jar_output(line)
|
1546
1571
|
|
1547
1572
|
for line in Connector.process_stream(popen.stdout):
|
1548
|
-
yield line
|
1573
|
+
yield Connector._maybe_colorize_jar_output(line)
|
1549
1574
|
popen.stdout.close()
|
1550
1575
|
return_code = popen.wait()
|
1551
1576
|
if return_code:
|
@@ -1726,19 +1751,30 @@ class Connector(connector_sdk_pb2_grpc.ConnectorServicer):
|
|
1726
1751
|
print_library_log(error_message, Logging.Level.SEVERE)
|
1727
1752
|
raise RuntimeError(error_message) from e
|
1728
1753
|
|
1754
|
+
@staticmethod
|
1755
|
+
def _maybe_colorize_jar_output(line: str) -> str:
|
1756
|
+
if not DEBUGGING:
|
1757
|
+
return line
|
1758
|
+
|
1759
|
+
if "SEVERE" in line or "ERROR" in line or "Exception" in line or "FAILED" in line:
|
1760
|
+
return f"\033[91m{line}\033[0m" # Red
|
1761
|
+
elif "WARN" in line or "WARNING" in line:
|
1762
|
+
return f"\033[93m{line}\033[0m" # Yellow
|
1763
|
+
return line
|
1764
|
+
|
1729
1765
|
|
1730
|
-
def find_connector_object(project_path) -> Connector:
|
1766
|
+
def find_connector_object(project_path) -> Optional[Connector]:
|
1731
1767
|
"""Finds the connector object in the given project path.
|
1732
1768
|
Args:
|
1733
1769
|
project_path (str): The path to the project.
|
1734
1770
|
|
1735
1771
|
Returns:
|
1736
|
-
|
1772
|
+
Optional[Connector]: The connector object or None if not found.
|
1737
1773
|
"""
|
1738
1774
|
|
1739
1775
|
sys.path.append(project_path) # Allows python interpreter to search for modules in this path
|
1740
1776
|
module_name = "connector_connector_code"
|
1741
|
-
connector_py = os.path.join(project_path,
|
1777
|
+
connector_py = os.path.join(project_path, ROOT_FILENAME)
|
1742
1778
|
try:
|
1743
1779
|
spec = importlib.util.spec_from_file_location(module_name, connector_py)
|
1744
1780
|
module = importlib.util.module_from_spec(spec)
|
@@ -1752,11 +1788,11 @@ def find_connector_object(project_path) -> Connector:
|
|
1752
1788
|
except FileNotFoundError:
|
1753
1789
|
print_library_log(
|
1754
1790
|
"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)
|
1755
|
-
return
|
1791
|
+
return None
|
1756
1792
|
|
1757
1793
|
print_library_log(
|
1758
1794
|
"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)
|
1759
|
-
return
|
1795
|
+
return None
|
1760
1796
|
|
1761
1797
|
|
1762
1798
|
def suggest_correct_command(input_command: str) -> bool:
|
@@ -1782,9 +1818,9 @@ def suggest_correct_command(input_command: str) -> bool:
|
|
1782
1818
|
|
1783
1819
|
|
1784
1820
|
def print_suggested_command_message(valid_command: str, input_command: str) -> None:
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1821
|
+
print_library_log(f"`fivetran {input_command}` is not a valid command.", Logging.Level.SEVERE)
|
1822
|
+
print_library_log(f"Did you mean `fivetran {valid_command}`?", Logging.Level.SEVERE)
|
1823
|
+
print_library_log("Use `fivetran --help` for more details.", Logging.Level.SEVERE)
|
1788
1824
|
|
1789
1825
|
|
1790
1826
|
def edit_distance(first_string: str, second_string: str) -> int:
|
@@ -1829,7 +1865,7 @@ def get_input_from_cli(prompt : str, default_value: str) -> str:
|
|
1829
1865
|
|
1830
1866
|
if not value:
|
1831
1867
|
raise ValueError("Missing required input: Expected a value but received None")
|
1832
|
-
return value
|
1868
|
+
return value
|
1833
1869
|
|
1834
1870
|
|
1835
1871
|
def main():
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: fivetran_connector_sdk
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.4.0
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|