Skip to content

Commit

Permalink
Source Shopify #4841 - improving according to PR review
Browse files Browse the repository at this point in the history
  • Loading branch information
vitaliizazmic committed Aug 17, 2021
1 parent de53799 commit 5aae64b
Showing 1 changed file with 17 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, shop: str, start_date: str, api_password: str, **kwargs):
self.api_password = api_password

@staticmethod
def _get_json_types(value_type) -> str:
def _get_json_types(value_type) -> List[str]:
json_types = {
str: ["string"],
int: ["integer", "number"],
Expand All @@ -68,10 +68,8 @@ def _get_json_types(value_type) -> str:
return json_types.get(value_type)

@staticmethod
def _convert(value: Any, convert_type: str):
if convert_type == "number":
value = Decimal(value)
return value
def _transform_number(value: Any, convert_type: str):
return Decimal(value)

@staticmethod
def _find_schema_type(schema_types: List[str]) -> str:
Expand All @@ -80,16 +78,19 @@ def _find_schema_type(schema_types: List[str]) -> str:
not_null_types.remove("null")
return not_null_types[0]

def _transform_array(self, array: List[Any], item_properties: Mapping[str, Any]):
def _transform_array(self, array: List[Any], item_properties: MutableMapping[str, Any]):
# iterate over items in array, compare schema types and convert if necessary.
item_types = item_properties.get("type", [])
if item_types:
schema_type = self._find_schema_type(item_types)
nested_properties = item_properties.get("properties", {})
for item in array:
if schema_type == "object":
self._transform_object(item, nested_properties)
yield item

def _transform_object(self, transform_object: Mapping[str, Any], properties: Mapping[str, Any]):
def _transform_object(self, transform_object: Mapping[str, Any], properties: MutableMapping[str, Any]):
# compare schema types and convert if necessary.
for object_property, value in transform_object.items():
if not value:
continue
Expand All @@ -104,19 +105,19 @@ def _transform_object(self, transform_object: Mapping[str, Any], properties: Map
schema_type = self._find_schema_type(schema_types)
if not any(value_json_type in schema_types for value_json_type in value_json_types):
if schema_type == "number":
transform_object[object_property] = self._convert(value, schema_type)
transform_object[object_property] = self._transform_number(value, schema_type)
if schema_type == "object":
nested_properties = object_properties.get("properties", {})
self._transform_object(value, nested_properties)
if schema_type == "array":
item_properties = object_properties.get("items", {})
self._transform_array(value, item_properties)

def _transform(self, records: List[Mapping[str, Any]]) -> List[Mapping[str, Any]]:
stream_properties = self._schema.get("properties", {})
for record in records:
self._transform_object(record, stream_properties)
return records
def _transform(self, records: List[MutableMapping[str, Any]]) -> Iterable[Mapping]:
# Shopify API returns array of objects
# It's need to compare records values with schemas
stream_properties = {"type": ["null", "object"], "properties": self._schema.get("properties", {})}
yield from self._transform_array(records, stream_properties)

@property
def url_base(self) -> str:
Expand All @@ -142,6 +143,9 @@ def request_params(self, next_page_token: Mapping[str, Any] = None, **kwargs) ->
def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]:
json_response = response.json()
records = json_response.get(self.data_field, []) if self.data_field is not None else json_response
# transform method was implemented according to issue 4841
# Shopify API returns price fields as a string and it should be converted to number
# this solution designed to convert string into number, but in future can be modified for general purpose
yield from self._transform(records)

@property
Expand Down

0 comments on commit 5aae64b

Please sign in to comment.