We are developing a custom source connector for Airbytewhere we are pulling data from its API's. The connector has an API to pull data for each form_id. We can pass different form_ids in our connector as an array of form_id initially so it can pull data from different forms. For every form, we create a new stream with the name of the form_id.
class SurveyStream(HttpStream, ABC):
def __init__(self, config: Mapping[str, Any], form_id, **kwargs):
super().__init__()
self.server_name = config['server_name']
self.form_id = form_id
self.start_date = config['start_date']
#base64 encode username and password as auth token
user_name_password = f"{config['username']}:{config['password']}"
self.auth_token = self._base64_encode(user_name_password)
@property
def url_base(self) -> str:
return f"https://{self.server_name}.surveycto.com/api/v2/forms/data/wide/json/"
def _base64_encode(self,string:str) -> str:
return base64.b64encode(string.encode("ascii")).decode("ascii")
def request_params(
self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, any] = None, next_page_token: Mapping[str, Any] = None
) -> MutableMapping[str, Any]:
return {}
class SurveyctoStream(SurveyStream):
primary_key = 'KEY'
date_format = '%b %d, %Y %H:%M:%S %p'
dateformat = '%Y-%m-%dT%H:%M:%S'
cursor_field = 'CompletionDate'
_cursor_value = None
@property
def name(self) -> str:
return self.form_id
def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
return None
# def _base64_encode(self,string:str) -> str:
# return base64.b64encode(string.encode("ascii")).decode("ascii")
def get_json_schema(self):
json_schema = {}
return {
"$schema": "http://json-schema.org/draft-07/schema#",
"additionalProperties": True,
"type": "object",
"properties": json_schema,
}
def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str:
return self.form_id
@property
def state(self) -> Mapping[str, Any]:
initial_date = datetime.strptime(self.start_date, self.date_format)
if self._cursor_value:
return {self.cursor_field: self._cursor_value}
else:
return {self.cursor_field: initial_date}
@state.setter
def state(self, value: Mapping[str, Any]):
self._cursor_value = datetime.strptime(value[self.cursor_field], self.dateformat)
def request_params(
self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, any] = None, next_page_token: Mapping[str, Any] = None
) -> MutableMapping[str, Any]:
ix = self.state[self.cursor_field]
return {'date': ix.strftime(self.date_format)}
def request_headers(
self, stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None
) -> Mapping[str, Any]:
return {'Authorization': 'Basic ' self.auth_token }
def parse_response(
self,
response: requests.Response,
stream_state: Mapping[str, Any],
stream_slice: Mapping[str, Any] = None,
next_page_token: Mapping[str, Any] = None,
) -> Iterable[Mapping]:
response_json = response.json()
for data in response_json:
try:
yield data
except Exception as e:
msg = f"""Encountered an exception parsing schema"""
self.logger.exception(msg)
raise e
So here I have two class. We initialize the SurveyStream class with some config that it needs. Then we are using the same class in SurveyCtoStream. Which pulls the data from the api and in parse_response
function I get the json.
basically here I get an array of dictionaries
response_json = response.json()
I need to use this variable in get_json_schema function. So is it possible or do we havee to create another class and then pull the data and then on top of it we can do the transformation?
CodePudding user response:
If I understand your question correctly, you may self.response_json = response.json() and use json_schema = self.response_json in get_json_schema.