cit-pydata 0.0.1.dev0__tar.gz → 0.0.1.dev2__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.
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/PKG-INFO +1 -1
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/pyproject.toml +8 -8
- cit-pydata-0.0.1.dev2/src/cit_pydata/__init__.py +9 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/marketo/api.py +15 -19
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/salesforce/api.py +16 -21
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/sftp/api.py +6 -8
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/sql/api.py +11 -17
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/util/api.py +18 -21
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata.egg-info/PKG-INFO +1 -1
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata.egg-info/requires.txt +10 -10
- cit-pydata-0.0.1.dev0/src/cit_pydata/__init__.py +0 -9
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/LICENSE +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/README.md +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/setup.cfg +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/aws/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/aws/api.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/box/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/box/api.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/joblog/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/joblog/api.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/marketo/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/salesforce/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/sfsync/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/sfsync/api.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/sftp/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/sql/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata/util/__init__.py +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata.egg-info/SOURCES.txt +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata.egg-info/dependency_links.txt +0 -0
- {cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cit-pydata
|
|
3
|
-
Version: 0.0.1.
|
|
3
|
+
Version: 0.0.1.dev2
|
|
4
4
|
Summary: Python clients for commonly used api services including Salesforce, SQL, Marketo, Box, SFSync*, and JobLog*
|
|
5
5
|
Author-email: Dionis Wang <dwang@eab.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/EAB-IT-DEV/cit-pydata
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cit-pydata"
|
|
7
|
-
version = "0.0.1.
|
|
7
|
+
version = "0.0.1.dev2"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Dionis Wang", email="dwang@eab.com" },
|
|
10
10
|
]
|
|
@@ -26,11 +26,11 @@ box = ["boxsdk"]
|
|
|
26
26
|
joblog = ["marketorestpython"]
|
|
27
27
|
salesforce = ["simple_salesforce","pyforce"]
|
|
28
28
|
sftp = ["paramiko"]
|
|
29
|
-
sql = ["SQLAlchemy
|
|
30
|
-
sql-pyodbc = ["SQLAlchemy
|
|
31
|
-
sql-pymssql = ["SQLAlchemy
|
|
32
|
-
sql-psycopg2 = ["SQLAlchemy
|
|
33
|
-
sql-mssql = ["SQLAlchemy
|
|
34
|
-
sql-postgres = ["SQLAlchemy
|
|
29
|
+
sql = ["SQLAlchemy<2.0", "numpy", "pandas"]
|
|
30
|
+
sql-pyodbc = ["SQLAlchemy<2.0", "pyodbc", "numpy", "pandas"]
|
|
31
|
+
sql-pymssql = ["SQLAlchemy<2.0", "pymssql", "numpy", "pandas"]
|
|
32
|
+
sql-psycopg2 = ["SQLAlchemy<2.0", "psycopg2-binary", "numpy", "pandas"]
|
|
33
|
+
sql-mssql = ["SQLAlchemy<2.0", "pymssql", "numpy", "pandas"]
|
|
34
|
+
sql-postgres = ["SQLAlchemy<2.0", "psycopg2-binary", "numpy", "pandas"]
|
|
35
35
|
local = ["python-dotenv", "boto3"]
|
|
36
|
-
all = ["aws-lambda-powertools","pandas","boxsdk","marketorestpython","simple_salesforce","pyforce","paramiko","SQLAlchemy
|
|
36
|
+
all = ["aws-lambda-powertools","pandas","boxsdk","marketorestpython","simple_salesforce","pyforce","paramiko","SQLAlchemy<2.0", "pyodbc","pymssql", "numpy", "pandas","psycopg2-binary","python-dotenv", "boto3"]
|
|
@@ -48,6 +48,8 @@ class MarketoClient:
|
|
|
48
48
|
]
|
|
49
49
|
|
|
50
50
|
def _authenticate(self):
|
|
51
|
+
from marketorestpython.client import MarketoClient as marketorestpython
|
|
52
|
+
|
|
51
53
|
if self.marketo is None:
|
|
52
54
|
try:
|
|
53
55
|
aws_ssm_client = aws_api.SSMClient(
|
|
@@ -109,8 +111,6 @@ class MarketoClient:
|
|
|
109
111
|
|
|
110
112
|
api_limit = None
|
|
111
113
|
max_retry_time = None
|
|
112
|
-
if not "marketorestpython" in sys.modules:
|
|
113
|
-
from marketorestpython.client import MarketoClient as marketorestpython
|
|
114
114
|
self.marketo = marketorestpython(
|
|
115
115
|
munchkin_id=munchkin_id,
|
|
116
116
|
client_id=client_id,
|
|
@@ -134,6 +134,8 @@ class MarketoClient:
|
|
|
134
134
|
return response
|
|
135
135
|
|
|
136
136
|
def execute_api_call(self, method, endpoint, *args, **kwargs):
|
|
137
|
+
import json
|
|
138
|
+
|
|
137
139
|
self._authenticate()
|
|
138
140
|
self.marketo.authenticate()
|
|
139
141
|
|
|
@@ -143,9 +145,6 @@ class MarketoClient:
|
|
|
143
145
|
|
|
144
146
|
data = kwargs.get("body", None)
|
|
145
147
|
|
|
146
|
-
if "json" not in sys.modules:
|
|
147
|
-
import json
|
|
148
|
-
|
|
149
148
|
self.logger.info(f"Sending API Call {str(method).upper()}: {endpoint} ")
|
|
150
149
|
self.logger.info(f"\tParams: {json.dumps(api_args)} ")
|
|
151
150
|
# self.logger.debug(f'\tBody: {json.dumps(data)} ')
|
|
@@ -168,8 +167,8 @@ class MarketoClient:
|
|
|
168
167
|
return True, result
|
|
169
168
|
|
|
170
169
|
def submit_form(self, form_payload: dict):
|
|
171
|
-
|
|
172
|
-
|
|
170
|
+
import requests
|
|
171
|
+
|
|
173
172
|
self._authenticate()
|
|
174
173
|
self.marketo.authenticate()
|
|
175
174
|
self.logger.debug(self.marketo.token)
|
|
@@ -183,10 +182,9 @@ class MarketoClient:
|
|
|
183
182
|
self.logger.debug(request.text)
|
|
184
183
|
|
|
185
184
|
def get_program(self, program_id):
|
|
186
|
-
|
|
185
|
+
import json
|
|
187
186
|
|
|
188
|
-
|
|
189
|
-
import json
|
|
187
|
+
self._authenticate()
|
|
190
188
|
|
|
191
189
|
try:
|
|
192
190
|
lead = self.client.execute(method="get_program_by_id", id=program_id)
|
|
@@ -208,12 +206,11 @@ class MarketoClient:
|
|
|
208
206
|
return result["result"]
|
|
209
207
|
|
|
210
208
|
def get_lead_fields2(self):
|
|
209
|
+
import json
|
|
210
|
+
|
|
211
211
|
self._authenticate()
|
|
212
212
|
lead = self.marketo.execute(method="describe2")
|
|
213
213
|
|
|
214
|
-
if "json" not in sys.modules:
|
|
215
|
-
import json
|
|
216
|
-
|
|
217
214
|
file_path = "src/core/marketo/data/out/marketo_lead_describe2.json"
|
|
218
215
|
util_api.remove_file(file_path)
|
|
219
216
|
with open(file_path, "w") as json_file:
|
|
@@ -226,8 +223,8 @@ class MarketoClient:
|
|
|
226
223
|
"""
|
|
227
224
|
Returns DataFrame of Custom Object records based on filter criteria
|
|
228
225
|
"""
|
|
229
|
-
|
|
230
|
-
|
|
226
|
+
import pandas as pd
|
|
227
|
+
|
|
231
228
|
batch_size = 300
|
|
232
229
|
field_list = self.CUSTOM_OBJECT_STANDARD_FIELDS
|
|
233
230
|
for field in custom_field_list:
|
|
@@ -346,8 +343,8 @@ class MarketoClient:
|
|
|
346
343
|
"""
|
|
347
344
|
Deletes Marketo custom object records with filter_list and delete_by arguments.
|
|
348
345
|
"""
|
|
349
|
-
|
|
350
|
-
|
|
346
|
+
import pandas as pd
|
|
347
|
+
|
|
351
348
|
self.logger.info(
|
|
352
349
|
f"Deleting {len(filter_list)} {custom_object_name} custom object records"
|
|
353
350
|
)
|
|
@@ -409,6 +406,7 @@ class MarketoClient:
|
|
|
409
406
|
In order to delete CO records in Marketo first we get all Marketo leads/contacts that shouldn't have any CO records and we delete those.
|
|
410
407
|
Next for leads/contacts that have at least one CO records, we compare existing CO records to all CO records and filter out good records
|
|
411
408
|
"""
|
|
409
|
+
import pandas as pd
|
|
412
410
|
|
|
413
411
|
# this dict contains the sql queries for fetching the lead counter ids in order to interrogate
|
|
414
412
|
# the Marketo custom object records and search for records to delete
|
|
@@ -448,8 +446,6 @@ class MarketoClient:
|
|
|
448
446
|
f"Checking Custom Object {custom_object_name} for records to delete"
|
|
449
447
|
)
|
|
450
448
|
|
|
451
|
-
if "pandas" not in sys.modules:
|
|
452
|
-
import pandas as pd
|
|
453
449
|
# init DataFrame
|
|
454
450
|
co_records_delete_df = pd.DataFrame()
|
|
455
451
|
|
|
@@ -65,6 +65,8 @@ class SalesforceClient:
|
|
|
65
65
|
'signature': 'zzz'
|
|
66
66
|
}
|
|
67
67
|
"""
|
|
68
|
+
import requests
|
|
69
|
+
|
|
68
70
|
if self.sf_token is None:
|
|
69
71
|
try:
|
|
70
72
|
aws_ssm_client = aws_api.SSMClient(
|
|
@@ -168,8 +170,6 @@ class SalesforceClient:
|
|
|
168
170
|
"username": sf_username,
|
|
169
171
|
"password": sf_password + sf_security_token,
|
|
170
172
|
}
|
|
171
|
-
if "requests" not in sys.modules:
|
|
172
|
-
import requests
|
|
173
173
|
# Get OAuth access token
|
|
174
174
|
with requests.Session() as session:
|
|
175
175
|
# headers={'Content-Type': 'application/json'}
|
|
@@ -204,12 +204,11 @@ class SalesforceClient:
|
|
|
204
204
|
"""
|
|
205
205
|
Creates and returns a simple-salesforce object
|
|
206
206
|
"""
|
|
207
|
+
from simple_salesforce import Salesforce
|
|
208
|
+
|
|
207
209
|
if self.sf_token is None:
|
|
208
210
|
self._authenticate()
|
|
209
211
|
|
|
210
|
-
if "simple_salesforce" not in sys.modules:
|
|
211
|
-
from simple_salesforce import Salesforce
|
|
212
|
-
|
|
213
212
|
_instance_url = self.get_instance_url()
|
|
214
213
|
_access_token = self.get_access_token()
|
|
215
214
|
|
|
@@ -262,8 +261,7 @@ class SalesforceClient:
|
|
|
262
261
|
"""Returns DataFrame from Object and Record Id query
|
|
263
262
|
TODO finish dev
|
|
264
263
|
"""
|
|
265
|
-
|
|
266
|
-
import pandas
|
|
264
|
+
import pandas
|
|
267
265
|
|
|
268
266
|
self._get_simple_sf()
|
|
269
267
|
|
|
@@ -326,11 +324,10 @@ class SalesforceClient:
|
|
|
326
324
|
return None
|
|
327
325
|
|
|
328
326
|
def get_replicatable_objects(self, is_refresh_from_sf=None):
|
|
327
|
+
from collections import OrderedDict
|
|
328
|
+
import json
|
|
329
|
+
|
|
329
330
|
self._authenticate()
|
|
330
|
-
if "collections" not in sys.modules:
|
|
331
|
-
from collections import OrderedDict
|
|
332
|
-
if "json" not in sys.modules:
|
|
333
|
-
import json
|
|
334
331
|
|
|
335
332
|
if is_refresh_from_sf == True:
|
|
336
333
|
# Get All Salesforce Object Metadata
|
|
@@ -393,14 +390,12 @@ class SalesforceClient:
|
|
|
393
390
|
"""
|
|
394
391
|
Returns dataframe from SOQL query
|
|
395
392
|
"""
|
|
396
|
-
|
|
397
|
-
|
|
393
|
+
import pandas
|
|
394
|
+
import requests
|
|
398
395
|
|
|
399
396
|
self._authenticate()
|
|
400
397
|
|
|
401
398
|
self.logger.debug("SOQL Query: {}".format(soql_query))
|
|
402
|
-
if "requests" not in sys.modules:
|
|
403
|
-
import requests
|
|
404
399
|
with requests.Session() as session:
|
|
405
400
|
ssf = self._get_simple_sf(session)
|
|
406
401
|
sf_result_dict = ssf.query_all(soql_query)
|
|
@@ -414,12 +409,12 @@ class SalesforceClient:
|
|
|
414
409
|
return df
|
|
415
410
|
|
|
416
411
|
def update_record(self, object_api_name, record_id, data_dict):
|
|
412
|
+
import requests
|
|
413
|
+
|
|
417
414
|
self._authenticate()
|
|
418
415
|
self.logger.info(
|
|
419
416
|
f'Update - {object_api_name}. Id:{record_id}, data_dict: "{data_dict}"'
|
|
420
417
|
)
|
|
421
|
-
if "requests" not in sys.modules:
|
|
422
|
-
import requests
|
|
423
418
|
with requests.Session() as session:
|
|
424
419
|
ssf = self._get_simple_sf(session)
|
|
425
420
|
sf_load_object_result = getattr(ssf, object_api_name).update(
|
|
@@ -429,9 +424,9 @@ class SalesforceClient:
|
|
|
429
424
|
return sf_load_object_result
|
|
430
425
|
|
|
431
426
|
def execute_apex(self, operation, method, payload):
|
|
427
|
+
import requests
|
|
428
|
+
|
|
432
429
|
self._authenticate()
|
|
433
|
-
if "requests" not in sys.modules:
|
|
434
|
-
import requests
|
|
435
430
|
with requests.Session() as session:
|
|
436
431
|
ssf = self._get_simple_sf(session)
|
|
437
432
|
self.logger.info(f"Executing Apex: {operation} {method}")
|
|
@@ -494,8 +489,8 @@ class SalesforceSOAPClient:
|
|
|
494
489
|
'signature': 'zzz'
|
|
495
490
|
}
|
|
496
491
|
"""
|
|
497
|
-
|
|
498
|
-
|
|
492
|
+
import pyforce
|
|
493
|
+
|
|
499
494
|
if self.sf_token is None:
|
|
500
495
|
try:
|
|
501
496
|
aws_ssm_client = aws_api.SSMClient(
|
|
@@ -38,8 +38,8 @@ class SFTPClient:
|
|
|
38
38
|
def _connect(self):
|
|
39
39
|
"""Method for connecting to SFTP Server
|
|
40
40
|
Called from all loading/downloading methods"""
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
import paramiko
|
|
42
|
+
|
|
43
43
|
try:
|
|
44
44
|
aws_ssm_client = aws_api.SSMClient(
|
|
45
45
|
environment=self.aws_environment,
|
|
@@ -152,8 +152,7 @@ class SFTPClient:
|
|
|
152
152
|
with an optional archive_suffix in the filename.
|
|
153
153
|
Returns True if the file transfer is successful, False otherwise.
|
|
154
154
|
Default behavior is to automatically close the connection after load"""
|
|
155
|
-
|
|
156
|
-
from datetime import datetime
|
|
155
|
+
from datetime import datetime
|
|
157
156
|
|
|
158
157
|
if self.sftp_session is None:
|
|
159
158
|
connected = self._connect()
|
|
@@ -247,6 +246,9 @@ class SFTPClient:
|
|
|
247
246
|
to the archive folder with an optional archive_suffix in the filename.
|
|
248
247
|
Returns True if the file download is successful, False otherwise.
|
|
249
248
|
Default behavior is to automatically close the connection after download."""
|
|
249
|
+
import shutil
|
|
250
|
+
from datetime import datetime
|
|
251
|
+
|
|
250
252
|
if self.sftp_session is None:
|
|
251
253
|
connected = self._connect()
|
|
252
254
|
if not connected:
|
|
@@ -307,10 +309,6 @@ class SFTPClient:
|
|
|
307
309
|
)
|
|
308
310
|
return True
|
|
309
311
|
else:
|
|
310
|
-
if "shutil" not in sys.modules:
|
|
311
|
-
import shutil
|
|
312
|
-
if "datetime" not in sys.modules:
|
|
313
|
-
from datetime import datetime
|
|
314
312
|
# Archive the existing file
|
|
315
313
|
archive_suffix = archive_suffix or datetime.now().strftime(
|
|
316
314
|
"%Y%m%d"
|
|
@@ -55,10 +55,8 @@ class SQLClient:
|
|
|
55
55
|
|
|
56
56
|
This method will use the AWS IAM credentials defined in the local .env file to get the AWS SSM parameters defining SQL authentication details
|
|
57
57
|
"""
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if "urllib.parse" not in sys.modules:
|
|
61
|
-
from urllib.parse import quote
|
|
58
|
+
import re
|
|
59
|
+
from urllib.parse import quote
|
|
62
60
|
|
|
63
61
|
try:
|
|
64
62
|
_aws_environment = None
|
|
@@ -263,8 +261,8 @@ class SQLClient:
|
|
|
263
261
|
def execute_stored_procedure(
|
|
264
262
|
self, stored_procedure_name, param_list, skip_transaction: bool = False
|
|
265
263
|
):
|
|
266
|
-
|
|
267
|
-
|
|
264
|
+
import re
|
|
265
|
+
|
|
268
266
|
_param_markers_list = ",".join(["?" for param in param_list])
|
|
269
267
|
|
|
270
268
|
if self.dialect == "pymssql":
|
|
@@ -346,8 +344,8 @@ class SQLClient:
|
|
|
346
344
|
return True
|
|
347
345
|
|
|
348
346
|
def __split_df(self, df, chunksize):
|
|
349
|
-
|
|
350
|
-
|
|
347
|
+
from math import ceil
|
|
348
|
+
|
|
351
349
|
chunk_count = int(ceil(df.size / chunksize))
|
|
352
350
|
return np.array_split(df, chunk_count)
|
|
353
351
|
|
|
@@ -452,8 +450,7 @@ class SQLClient:
|
|
|
452
450
|
return dataframe
|
|
453
451
|
|
|
454
452
|
def get_dataframe_table(self, table_name, chunk_count=None, **kwargs):
|
|
455
|
-
|
|
456
|
-
from itertools import islice
|
|
453
|
+
from itertools import islice
|
|
457
454
|
|
|
458
455
|
s = time.time()
|
|
459
456
|
if "chunksize" not in kwargs.keys():
|
|
@@ -666,11 +663,8 @@ class SQLClient:
|
|
|
666
663
|
data_iter : Iterable that iterates the values to be inserted
|
|
667
664
|
"""
|
|
668
665
|
# gets a DBAPI connection that can provide a cursor
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
if "io" not in sys.modules:
|
|
673
|
-
from io import StringIO
|
|
666
|
+
import csv
|
|
667
|
+
from io import StringIO
|
|
674
668
|
|
|
675
669
|
dbapi_conn = conn.connection
|
|
676
670
|
with dbapi_conn.cursor() as cur:
|
|
@@ -697,8 +691,8 @@ class SQLClient:
|
|
|
697
691
|
|
|
698
692
|
#### HAS NOT BEEN TESTED YET MAY NOT WORK####
|
|
699
693
|
def postgres_quickexport_df(self, table_name):
|
|
700
|
-
|
|
701
|
-
|
|
694
|
+
from io import StringIO
|
|
695
|
+
|
|
702
696
|
if self.dialect != "psycopg2":
|
|
703
697
|
self.logger.error(f"unsupported dialect for upsert {self.dialect}")
|
|
704
698
|
dbapi_conn = self._get_sql_engine.connect()
|
|
@@ -11,9 +11,10 @@ def encode_base64(value: str):
|
|
|
11
11
|
"""
|
|
12
12
|
Returns base64 encoded value for the input string parameter
|
|
13
13
|
"""
|
|
14
|
+
import base64
|
|
15
|
+
|
|
14
16
|
binary_value = value.encode("ascii")
|
|
15
|
-
|
|
16
|
-
import base64
|
|
17
|
+
|
|
17
18
|
return base64.b64encode(binary_value)
|
|
18
19
|
|
|
19
20
|
|
|
@@ -31,12 +32,12 @@ def multireplace(string, replacements, ignore_case=False):
|
|
|
31
32
|
"""
|
|
32
33
|
# Source: https://gist.github.com/bgusach/a967e0587d6e01e889fd1d776c5f3729
|
|
33
34
|
|
|
35
|
+
import re
|
|
36
|
+
|
|
34
37
|
if not replacements:
|
|
35
38
|
# Edge case that'd produce a funny regex and cause a KeyError
|
|
36
39
|
return string
|
|
37
40
|
|
|
38
|
-
if not "re" in sys.modules:
|
|
39
|
-
import re
|
|
40
41
|
# If case insensitive, we need to normalize the old string so that later a replacement
|
|
41
42
|
# can be found. For instance with {"HEY": "lol"} we should match and find a replacement for "hey",
|
|
42
43
|
# "HEY", "hEy", etc.
|
|
@@ -76,6 +77,8 @@ def list_dict_to_csv(file_path, file_name, data_list, column_list=None):
|
|
|
76
77
|
dictionary should be column_name:value format
|
|
77
78
|
|
|
78
79
|
"""
|
|
80
|
+
import csv
|
|
81
|
+
|
|
79
82
|
if type(data_list) != list:
|
|
80
83
|
return False
|
|
81
84
|
|
|
@@ -93,8 +96,6 @@ def list_dict_to_csv(file_path, file_name, data_list, column_list=None):
|
|
|
93
96
|
if not os.path.exists(file_path):
|
|
94
97
|
os.makedirs(file_path)
|
|
95
98
|
|
|
96
|
-
if "csv" not in sys.modules:
|
|
97
|
-
import csv
|
|
98
99
|
with open(full_file_path, "w+", newline="") as csv_file:
|
|
99
100
|
csv_writer = csv.DictWriter(csv_file, fieldnames=column_list)
|
|
100
101
|
csv_writer.writeheader()
|
|
@@ -104,9 +105,9 @@ def list_dict_to_csv(file_path, file_name, data_list, column_list=None):
|
|
|
104
105
|
|
|
105
106
|
|
|
106
107
|
def json_to_file(json_object, file_path):
|
|
108
|
+
import json
|
|
109
|
+
|
|
107
110
|
remove_file(file_path)
|
|
108
|
-
if "json" not in sys.modules:
|
|
109
|
-
import json
|
|
110
111
|
with open(file_path, "w") as json_file:
|
|
111
112
|
json.dump(json_object, json_file)
|
|
112
113
|
|
|
@@ -130,8 +131,7 @@ def get_environment_variable(
|
|
|
130
131
|
)
|
|
131
132
|
return None
|
|
132
133
|
|
|
133
|
-
|
|
134
|
-
from dotenv import dotenv_values
|
|
134
|
+
from dotenv import dotenv_values
|
|
135
135
|
|
|
136
136
|
_path_to_env_file = None
|
|
137
137
|
|
|
@@ -195,6 +195,7 @@ def get_logger(
|
|
|
195
195
|
"""
|
|
196
196
|
if not ON_AWS and log_type in ("console", "file"):
|
|
197
197
|
import logging
|
|
198
|
+
import re
|
|
198
199
|
|
|
199
200
|
logger = logging.getLogger(logger_name)
|
|
200
201
|
|
|
@@ -266,8 +267,6 @@ def get_logger(
|
|
|
266
267
|
and type(cleanup_policy) == dict
|
|
267
268
|
and "retain_last_n" in cleanup_policy.keys()
|
|
268
269
|
):
|
|
269
|
-
if not "re" in sys.modules:
|
|
270
|
-
import re
|
|
271
270
|
log_file_regex = re.compile(f"^{base_file_name}.*\.log$")
|
|
272
271
|
# try catch to prevent failure from affecting actual job
|
|
273
272
|
try:
|
|
@@ -324,8 +323,8 @@ def cleanup_logs(
|
|
|
324
323
|
Returns:
|
|
325
324
|
number of files that were attempted to be deleted: int
|
|
326
325
|
"""
|
|
327
|
-
|
|
328
|
-
|
|
326
|
+
import re
|
|
327
|
+
|
|
329
328
|
remove_counter = 0
|
|
330
329
|
|
|
331
330
|
# determine cutoff_time
|
|
@@ -359,7 +358,7 @@ def get_log_level(path_to_env=PATH_TO_ENV):
|
|
|
359
358
|
path_to_env_file=path_to_env, variable_name="log_level"
|
|
360
359
|
)
|
|
361
360
|
elif ON_AWS:
|
|
362
|
-
_log_level = os.getenv("POWERTOOLS_LOG_LEVEL")
|
|
361
|
+
_log_level = os.getenv("POWERTOOLS_LOG_LEVEL", _log_level)
|
|
363
362
|
return _log_level
|
|
364
363
|
|
|
365
364
|
|
|
@@ -368,10 +367,9 @@ def find_text_in_files(root_path, text_regex):
|
|
|
368
367
|
Searches .py files line by line matching on regex pattern
|
|
369
368
|
Files are recursively searched starting in root_path
|
|
370
369
|
"""
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
import pprint
|
|
370
|
+
import re
|
|
371
|
+
import pprint
|
|
372
|
+
|
|
375
373
|
os.listdir()
|
|
376
374
|
file_list = []
|
|
377
375
|
for dirpath, dirnames, filenames in os.walk(root_path):
|
|
@@ -408,10 +406,9 @@ def find_text_in_files(root_path, text_regex):
|
|
|
408
406
|
|
|
409
407
|
def get_core_conn(folder_path) -> dict:
|
|
410
408
|
"""Retrieves the connection configuration to the core systems"""
|
|
409
|
+
import json
|
|
411
410
|
|
|
412
411
|
file_path = os.path.join(folder_path, "core_conn.json")
|
|
413
|
-
if "json" not in sys.modules:
|
|
414
|
-
import json
|
|
415
412
|
with open(file_path, "r") as f:
|
|
416
413
|
conn_dict = json.load(f)
|
|
417
414
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cit-pydata
|
|
3
|
-
Version: 0.0.1.
|
|
3
|
+
Version: 0.0.1.dev2
|
|
4
4
|
Summary: Python clients for commonly used api services including Salesforce, SQL, Marketo, Box, SFSync*, and JobLog*
|
|
5
5
|
Author-email: Dionis Wang <dwang@eab.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/EAB-IT-DEV/cit-pydata
|
|
@@ -7,11 +7,11 @@ marketorestpython
|
|
|
7
7
|
simple_salesforce
|
|
8
8
|
pyforce
|
|
9
9
|
paramiko
|
|
10
|
-
SQLAlchemy
|
|
10
|
+
SQLAlchemy<2.0
|
|
11
11
|
pyodbc
|
|
12
12
|
pymssql
|
|
13
13
|
numpy
|
|
14
|
-
psycopg2-binary
|
|
14
|
+
psycopg2-binary
|
|
15
15
|
python-dotenv
|
|
16
16
|
boto3
|
|
17
17
|
|
|
@@ -36,36 +36,36 @@ pyforce
|
|
|
36
36
|
paramiko
|
|
37
37
|
|
|
38
38
|
[sql]
|
|
39
|
-
SQLAlchemy
|
|
39
|
+
SQLAlchemy<2.0
|
|
40
40
|
numpy
|
|
41
41
|
pandas
|
|
42
42
|
|
|
43
43
|
[sql-mssql]
|
|
44
|
-
SQLAlchemy
|
|
44
|
+
SQLAlchemy<2.0
|
|
45
45
|
pymssql
|
|
46
46
|
numpy
|
|
47
47
|
pandas
|
|
48
48
|
|
|
49
49
|
[sql-postgres]
|
|
50
|
-
SQLAlchemy
|
|
51
|
-
psycopg2-binary
|
|
50
|
+
SQLAlchemy<2.0
|
|
51
|
+
psycopg2-binary
|
|
52
52
|
numpy
|
|
53
53
|
pandas
|
|
54
54
|
|
|
55
55
|
[sql-psycopg2]
|
|
56
|
-
SQLAlchemy
|
|
57
|
-
psycopg2-binary
|
|
56
|
+
SQLAlchemy<2.0
|
|
57
|
+
psycopg2-binary
|
|
58
58
|
numpy
|
|
59
59
|
pandas
|
|
60
60
|
|
|
61
61
|
[sql-pymssql]
|
|
62
|
-
SQLAlchemy
|
|
62
|
+
SQLAlchemy<2.0
|
|
63
63
|
pymssql
|
|
64
64
|
numpy
|
|
65
65
|
pandas
|
|
66
66
|
|
|
67
67
|
[sql-pyodbc]
|
|
68
|
-
SQLAlchemy
|
|
68
|
+
SQLAlchemy<2.0
|
|
69
69
|
pyodbc
|
|
70
70
|
numpy
|
|
71
71
|
pandas
|
|
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
|
|
File without changes
|
|
File without changes
|
{cit-pydata-0.0.1.dev0 → cit-pydata-0.0.1.dev2}/src/cit_pydata.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|