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
|