-
Notifications
You must be signed in to change notification settings - Fork 13
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
[TDL-15656] Added Support for dev mode #41
base: master
Are you sure you want to change the base?
Changes from all commits
cccfc1b
d586f25
2581588
4ad0dac
1481ba4
e6ee98b
9099b0b
5b0690b
eddf3ba
2ae8cb3
39c9754
59c5b74
330d464
264e0d0
cb905b0
31de7b0
e02e8a1
d75aac7
53ff291
5269472
475dff9
6021e28
13bcef3
e1cbe5b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,28 +1,28 @@ | ||||||||||||||
import json | ||||||||||||||
from datetime import datetime, timedelta | ||||||||||||||
from datetime import timedelta | ||||||||||||||
|
||||||||||||||
import backoff | ||||||||||||||
import requests | ||||||||||||||
from requests.exceptions import ConnectionError | ||||||||||||||
from singer import metrics | ||||||||||||||
from singer import metrics,get_logger | ||||||||||||||
from singer.utils import strptime_to_utc,now,strftime | ||||||||||||||
from .utils import write_config | ||||||||||||||
LOGGER = get_logger() | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
class Server5xxError(Exception): | ||||||||||||||
pass | ||||||||||||||
|
||||||||||||||
|
||||||||||||||
class EloquaClient(object): | ||||||||||||||
def __init__(self, | ||||||||||||||
config_path, | ||||||||||||||
client_id, | ||||||||||||||
client_secret, | ||||||||||||||
refresh_token, | ||||||||||||||
redirect_uri, | ||||||||||||||
user_agent): | ||||||||||||||
def __init__(self,config_path, config, dev_mode=False): | ||||||||||||||
self.__config_path = config_path | ||||||||||||||
self.__client_id = client_id | ||||||||||||||
self.__client_secret = client_secret | ||||||||||||||
self.__refresh_token = refresh_token | ||||||||||||||
self.__redirect_uri = redirect_uri | ||||||||||||||
self.__user_agent = user_agent | ||||||||||||||
self.config = config | ||||||||||||||
self.__client_id = config["client_id"] | ||||||||||||||
self.__client_secret = config["client_secret"] | ||||||||||||||
self.__refresh_token = config["refresh_token"] | ||||||||||||||
self.__redirect_uri = config["redirect_uri"] | ||||||||||||||
self.__user_agent = config.get("user_agent","") | ||||||||||||||
self.dev_mode = dev_mode | ||||||||||||||
self.__access_token = None | ||||||||||||||
self.__expires = None | ||||||||||||||
self.__session = requests.Session() | ||||||||||||||
|
@@ -40,7 +40,16 @@ def __exit__(self, type, value, traceback): | |||||||||||||
max_tries=5, | ||||||||||||||
factor=2) | ||||||||||||||
def get_access_token(self): | ||||||||||||||
if self.__access_token is not None and self.__expires > datetime.utcnow(): | ||||||||||||||
if self.dev_mode: | ||||||||||||||
try: | ||||||||||||||
self.__access_token = self.config['access_token'] | ||||||||||||||
self.__expires=strptime_to_utc(self.config['expires_in']) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
except KeyError as ex: | ||||||||||||||
raise Exception("Unable to locate key in config") from ex | ||||||||||||||
if not self.__access_token or self.__expires < now(): | ||||||||||||||
raise Exception("Access Token in config is expired, unable to authenticate in dev mode") | ||||||||||||||
|
||||||||||||||
if self.__access_token and self.__expires > now(): | ||||||||||||||
return | ||||||||||||||
|
||||||||||||||
headers = {} | ||||||||||||||
|
@@ -63,31 +72,25 @@ def get_access_token(self): | |||||||||||||
|
||||||||||||||
if response.status_code != 200: | ||||||||||||||
eloqua_response = response.json() | ||||||||||||||
eloqua_response.update( | ||||||||||||||
{'status': response.status_code}) | ||||||||||||||
raise Exception( | ||||||||||||||
'Unable to authenticate (Eloqua response: `{}`)'.format( | ||||||||||||||
eloqua_response)) | ||||||||||||||
eloqua_response.update({'status': response.status_code}) | ||||||||||||||
raise Exception('Unable to authenticate (Eloqua response: `{}`)'.format(eloqua_response)) | ||||||||||||||
|
||||||||||||||
data = response.json() | ||||||||||||||
|
||||||||||||||
self.__access_token = data['access_token'] | ||||||||||||||
self.__refresh_token = data['refresh_token'] | ||||||||||||||
expires_in_seconds = data['expires_in'] - 10 # pad by 10 seconds | ||||||||||||||
self.__expires = now() + timedelta(seconds=expires_in_seconds) | ||||||||||||||
|
||||||||||||||
## refresh_token rotates on every reauth | ||||||||||||||
with open(self.__config_path) as file: | ||||||||||||||
config = json.load(file) | ||||||||||||||
config['refresh_token'] = data['refresh_token'] | ||||||||||||||
with open(self.__config_path, 'w') as file: | ||||||||||||||
json.dump(config, file, indent=2) | ||||||||||||||
|
||||||||||||||
expires_seconds = data['expires_in'] - 10 # pad by 10 seconds | ||||||||||||||
self.__expires = datetime.utcnow() + timedelta(seconds=expires_seconds) | ||||||||||||||
if not self.dev_mode: | ||||||||||||||
update_config_keys = { | ||||||||||||||
"refresh_token":self.__refresh_token, | ||||||||||||||
"access_token":self.__access_token, | ||||||||||||||
"expires_in": strftime(self.__expires) | ||||||||||||||
Comment on lines
+86
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
} | ||||||||||||||
self.config = write_config(self.__config_path,update_config_keys) | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
||||||||||||||
def get_base_urls(self): | ||||||||||||||
data = self.request('GET', | ||||||||||||||
url='https://login.eloqua.com/id', | ||||||||||||||
endpoint='base_url') | ||||||||||||||
data = self.request('GET',url='https://login.eloqua.com/id',endpoint='base_url') | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
self.__base_url = data['urls']['base'] | ||||||||||||||
|
||||||||||||||
@backoff.on_exception(backoff.expo, | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -173,8 +173,8 @@ def sync_bulk_obj(client, catalog, state, start_date, stream_name, bulk_page_siz | |
bulk_page_size, | ||
last_date, | ||
offset=last_offset) | ||
except HTTPError as e: | ||
if e.response.status_code in [404, 410]: | ||
except HTTPError as ex: | ||
if ex.response.status_code in [404, 410]: | ||
LOGGER.info('{} - Previous export expired: {}'.format(stream_name, last_sync_id)) | ||
else: | ||
raise | ||
|
@@ -377,12 +377,12 @@ def sync_activity_stream(client, | |
activity_type): | ||
finished = False | ||
sync_start = pendulum.now('UTC') | ||
end_date = sync_start | ||
end_date, last_sync_date = sync_start, None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these changes in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And if these are required changes then update the description on this PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RushiT0122 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure this is a problem in other languages, but not python >>> for i in range(3):
... try:
... print("About to initialize `my_variable`")
... my_variable = i
... print(f"my_variable: {my_variable}")
... raise RuntimeError(f"Problem occured with {my_variable}")
... except Exception as err:
... print(f"Caught {type(err)} with message {str(err)}")
... print(f"Current value of my_variable {my_variable}")
...
About to initialize `my_variable`
my_variable: 0
Caught <class 'RuntimeError'> with message Problem occured with 0
Current value of my_variable 0
About to initialize `my_variable`
my_variable: 1
Caught <class 'RuntimeError'> with message Problem occured with 1
Current value of my_variable 1
About to initialize `my_variable`
my_variable: 2
Caught <class 'RuntimeError'> with message Problem occured with 2
Current value of my_variable 2 |
||
while not finished: | ||
try: | ||
# Get latest bookmark to adjust time window from, if needed | ||
last_date_raw = get_bulk_bookmark(state, stream_name).get('datetime', start_date) | ||
last_date = pendulum.parse(last_date_raw) | ||
last_sync_date = pendulum.parse(last_date_raw) | ||
|
||
update_current_stream(state, stream_name) | ||
sync_bulk_obj(client, | ||
|
@@ -399,12 +399,14 @@ def sync_activity_stream(client, | |
# If not done, sync again to now() | ||
end_date = sync_start | ||
except ActivityExportTooLarge as ex: | ||
LOGGER.warn(ex) | ||
end_date = last_date.add(seconds=(end_date - last_date).total_seconds() / 2) | ||
LOGGER.warning(ex) | ||
end_date = last_sync_date.add(seconds=(end_date - last_sync_date).total_seconds() / 2) | ||
if end_date > sync_start: | ||
end_date = sync_start | ||
|
||
def sync(client, catalog, state, start_date, bulk_page_size): | ||
def sync(client, catalog, state, config): | ||
start_date = config['start_date'] | ||
bulk_page_size = int(config.get('bulk_page_size', 5000)) | ||
selected_streams = get_selected_streams(catalog) | ||
|
||
if not selected_streams: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from typing import Dict | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is unused |
||
import json | ||
from singer import get_logger | ||
|
||
LOGGER = get_logger() | ||
|
||
|
||
def write_config(config_path,data) : | ||
""" | ||
Updates the provided filepath with json format of the `data` object | ||
does a safe write by performing a read before write, updates only specific keys, does not rewrite. | ||
""" | ||
with open(config_path,'r') as tap_config: | ||
config = json.load(tap_config) | ||
config.update(data) | ||
with open(config_path,'w') as tap_config: | ||
json.dump(config, tap_config, indent=2) | ||
return config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use the standard list of disables?