How to write Python method with dictionary choices? - python

I am writting simple API manager and I have problem with using dictionary in method here is what I wrote so far:
class BnManager():
def __init__(self, api_key, api_secret):
self.api_key = api_key
self.api_secret = api_secret
self.client = Client(api_key, api_secret)
def get_candles(self, symbol, interval):
self.symbol = symbol
self.interval = interval
choice = {
'1m' : Client.KLINE_INTERVAL_1MINUTE,
'3m' : Client.KLINE_INTERVAL_3MINUTE,
'5m' : Client.KLINE_INTERVAL_5MINUTE,
'15m' : Client.KLINE_INTERVAL_15MINUTE,
'30m' : Client.KLINE_INTERVAL_30MINUTE,
'1h' : Client.KLINE_INTERVAL_1HOUR,
'2h' : Client.KLINE_INTERVAL_2HOUR,
'4h' : Client.KLINE_INTERVAL_4HOUR,
'6h' : Client.KLINE_INTERVAL_6HOUR,
'8h' : Client.KLINE_INTERVAL_8HOUR,
'12h' : Client.KLINE_INTERVAL_12HOUR,
'1d' : Client.KLINE_INTERVAL_1DAY,
'3d' : Client.KLINE_INTERVAL_3DAY,
'1w' : Client.KLINE_INTERVAL_1WEEK,
'1m' : Client.KLINE_INTERVAL_1MONTH,
}
self.klines = self.client.get_klines(
self.symbol, choice[self.interval])
self.df = pd.DataFrame(self.klines, columns=[
'Date', 'Open', 'High', 'Low', 'Close', 'Volume',
'x', 'x1', 'x2', 'x3', 'x4', 'x5'])
self.df.drop(labels=['x', 'x1', 'x2', 'x3', 'x4', 'x5'],
axis=1, inplace=True).astype(float)
self.df['Date'] = date2num(pd.to_datetime(df.Date, unit='ms'))
self.df['Change'] = df['Close'].diff()
Problem appears when I try to execute get_candles method.
For example when I write manager.get_candles('BTCUSDT', '1m') I am getting:
self.symbol, choice[self.interval] TypeError: get_candles() takes 1
positional argument but 3 were given
I know this is probably trivial question but I really do not see where the problem is. And my second question: how to write it without using dict . I mean I would like to achieve something like :
self.klines = self.client.get_klines(
self.symbol, Client.KLINE_INTERVAL_+interval)

For the rewriting question you could look into Programmatic access to enumeration members and their attributes. Basically the documentation explains that you can use strings as keys for Enums.
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color['RED']) # output: <Color.RED: 1>

Related

batch_write_item using dynamodb.client() to write large csv to dynamodb table in python

I am trying to insert a large csv file (5M records) to dynamodb using dynamodb_client.batch_write_item().
When I insert using dynamodb_client.put_item(), it works fine but I need to be able to use it with batch_write_item() too.
Here is my code snippet for few records (more than 1):
import json
import boto3
import csv
import pandas as pd
from datetime import datetime
roleARN = 'arn:aws:iam::123:role/xyz_role'
boto3.setup_default_session(profile_name='test_profile')
client = boto3.client('sts')
response = client.assume_role(RoleArn=roleARN,
RoleSessionName='RoleSessionName',
DurationSeconds=1800)
dynamodb_client = boto3.client('dynamodb', region_name='ap-south-1',
aws_access_key_id=response['Credentials']['AccessKeyId'],
aws_secret_access_key=response['Credentials']['SecretAccessKey'],
aws_session_token = response['Credentials']['SessionToken'])
#Fetching time for population
current_time = datetime.utcnow().isoformat()[:-3] + 'Z'
def convert_csv_to_json_list(file):
items = []
with open(file) as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
data = {}
data['col1'] = row['col1']
data['col2'] = int(row['col2'])
data['col3'] = int(row['col3'])
data['Row_Created'] = current_time
data['col4'] = row['col4']
data['col5'] = int(row['col5'])
data['Row_Updated'] = current_time
items.append(data)
return items
def batch_write(items):
table = "sample_table"
#writing batch
try:
print(type(items))
dynamodb_client.batch_write_item(RequestItems = {
table: [{'PutRequest':
{
'Item' : items
}}]
})
print(f'resource, specify all types : write succeeded.')
except Exception as e:
print(f'resource, specify all types : write failed: {e}')
inp_file = "sample_mapping.csv"
json_data = convert_csv_to_json_list(inp_file)
batch_write(json_data)
I keep getting :
<class 'list'>
resource, specify all types : write failed: Parameter validation failed:
Invalid type for parameter RequestItems.sample_table[0][{'col1': 'abc', 'col2': 59, 'col3': 0
, 'Row_Created': '2021-10-08T04:36:04.787Z', 'col4': 'dfrwfr', 'col5': 1, 'Row_Updated': '2021-10-08T04:36:04.787Z'}, {'col1': 'sffr', 'col2': 45, 'col3': 0
, 'Row_Created': '2021-10-08T04:36:04.787Z', 'col4': 'gty7u', 'col5': 1, 'Row_Updated': '2021-10-08T04:36:04.787Z'}], type: <class 'list'>, valid types: <class
'dict'>
Can someone help me where I am going wrong with batch insertion, tried looking up the documentation too.
Each item should be in a separate PutRequest key.
RequestItems = {
table: [
{'PutRequest': {'Item': {}}},
{'PutRequest': {'Item': {}}}
]
}
There are certain limitations with using batch_write_item, such as there cannot be more than 25 items in the request.

How to create dependent dropdowns using Jupyter Widgets to get data from dict?

I am trying to assign two variables with values using Jupyter Dropdowns where the first dropdown is a data center, and the second is a site available within this data center so that I can use these variables further in the code.
I tried multiple examples from different articles, but I cannot find what I am missing.
I have the following Dict:
data_center_environments = {
'US': {
'data_center': 'us..com',
'api_keys': {
'sandbox' : '3_EV',
'dev_parent' : '3_hK',
'stage' :'3_GE',
'prod' : '3_NL',
}
},
'RU': {
'data_center': 'ru..com',
'api_keys': {
'stage_parent' : '3_sN',
'prod_parent' : '3_R9',
}
},
'CN': {
'data_center': 'cn..cn',
'api_keys': {
'stage_parent' : '3_3k',
'prod_parent' : '3_MH',
}
},
'EU': {
'data_center': 'eu..com',
'api_keys': {
'sandbox' : '3_7h',
}
},
}
I created two functions to get datacenter and site:
def get_dc(dc_select=None):
dc = data_center_environments.get(dc_select)['data_center']
return dc
def get_site_api_key(dc_select=None, site_select=None):
site_api_key = data_center_environments[dc_select]['api_keys'][site_select]
return site_api_key
Here I describe two dropdowns:
dc_s = widgets.Dropdown(
options = data_center_environments.keys(),
description = 'Data Center:',
disabled = False,
)
site_s = widgets.Dropdown(
options=list(data_center_environments[dc_s.value]['api_keys']),
description = 'API Key:',
disabled = False,
)
def on_value_change(change):
dc = change.new
site_s.options = data_center_environments[dc_s.value]['api_keys']
dc_s.observe(on_value_change, 'value')
This is how I invoke them on a Jupyter Notebook page:
domain = interactive(get_dc, dc_select = dc_s)
site = interactive(get_site_api_key, dc_select = dc_s, site_select = site_s)
display(domain)
display(site)
Issues:
0. I have 3 dropdowns instead of two
1. I am getting an exception when I change datacenter value
2. When I am trying to print "domain", "domain.value" I am getting "None" as an output
What I am trying to achieve:
In:
domain =
site =
print(domain, site)
Out:
Select Datacenter [Drop Down: 'US', 'CN', 'RU', etc] -> pick 'US'
Select Site [Dropdown 'US': 'prod', 'stage', 'dev_parent', 'sandbox'] -> select 'prod'
'us..com' , '3_NL'
What am I doing wrong? How to change my code to make it work?
Thank you!
I end up writing a function that returns a dict, and I just get values from it.
The code below is a textbook example from the Widgets Guide.
Solution:
dc = 'US'
domain = widgets.Dropdown(
options = list(data_center_environments),
description = 'Data Center:',
disabled = False,
)
site = widgets.Dropdown(
options=list(data_center_environments[dc]['api_keys']),
description = 'API Key:',
disabled = False,
)
def on_value_change(change):
dc = change.new
site.options = data_center_environments[dc]['api_keys']
domain.observe(on_value_change, 'value')
def creds(data_center, api_key, use_secret):
data_center = data_center_environments[domain.value]['data_center']
api_key = site.value
creds = dict()
creds['data_center'] = data_center
creds['api_key'] = api_key
return creds

pydocumentdb CosmosDb Python - How to add several entries to the same document

I try to add several entries tho the same document in Cosmo Db with Python using the library pydocumentdb
I thought that was possible with the function CreateDocuments
Creation of the Document with one entry works
def GetSalesOrder(document_id):
# notice new fields have been added to the sales order
order2 = {'id' : document_id,
'account_number' : 'Account2',
'purchase_order_number' : 'PO15428132599',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
return order2
coll_link = database_link + '/colls/sales'
print('\n1.2 Creating collection\n')
collection = client.CreateCollection(database_link,
{ 'id': "sales" })
print('\n1.2 Creating document\n')
sales_order = DocumentManagement.GetSalesOrder("SalesOrder")
client.CreateDocument(coll_link, sales_order)
Then i try to reuse this code with a different entry into the same document but my program fails with :
Top level Error: args:('document is None.',), message:N/A
Thanks for your help
The complete code that fails
import pydocumentdb.documents as documents
import pydocumentdb.document_client as document_client
import pydocumentdb.errors as errors
import datetime
import config as cfg
HOST = cfg.settings['host']
MASTER_KEY = cfg.settings['master_rw_key']
DATABASE_ID = cfg.settings['database_id']
COLLECTION_ID = cfg.settings['collection_id']
database_link = 'dbs/' + DATABASE_ID
collection_link = database_link + '/colls/' + COLLECTION_ID
class IDisposable:
""" A context manager to automatically close an object with a close method
in a with statement. """
def __init__(self, obj):
self.obj = obj
def __enter__(self):
return self.obj # bound to target
def __exit__(self, exception_type, exception_val, trace):
# extra cleanup in here
self = None
class DocumentManagement:
#staticmethod
def CreateDocuments(client):
coll_link = database_link + '/colls/sales'
print('\n1.2 Creating collection\n')
collection = client.CreateCollection(database_link,
{ 'id': "sales" })
print('\n1.2 Creating document\n')
sales_order = DocumentManagement.GetSalesOrder("SalesOrder")
client.CreateDocument(coll_link, sales_order)
#staticmethod
def AddEntry(client):
coll_link = database_link + '/colls/sales' #+ '/docs/SalesOrder'
print('\n1.2 Creating row\n')
sales_order = DocumentManagement.GetSalesOrder2("SalesOrder")
client.CreateDocument(coll_link, sales_order)
#staticmethod
def CreateStoredProcedure(client):
coll_link = database_link + '/colls/sales'
sproc1 = {
'id': 'countDocuments',
'body': (
'function () {' +
' var collection = getContext().getCollection(); ' +
' collection.queryDocuments(' +
' collection.getSelfLink(),' +
' \'SELECT VALUE COUNT(SalesOrder.id) FROM SalesOrder\',' +
' function(error, result) {' +
' if (error) throw error;' +
' var count = result[0];' +
' getContext().getResponse().setBody(count);' +
' }' +
' );' +
' }'
)
}
print('\n1.2 Creating sproc\n')
retrieved_sproc = client.CreateStoredProcedure(coll_link, sproc1)
#staticmethod
def CountEntries(client):
coll_link = database_link + '/colls/sales'
sproc_link = coll_link + '/sprocs/countDocuments'
print('\n1.2 Counting rows\n')
#sales_order = DocumentManagement.getSalesOrder2("SalesOrder")
#client.CreateDocument(coll_link, sales_order)
params = {}
options = {}
options['enableCrossPartitionQuery'] = True
result = client.ExecuteStoredProcedure(sproc_link, params, options)
print(result)
#staticmethod
def DeleteCollection(client):
coll_link = database_link + '/colls/sales'
print('\n1.2 Delete collection\n')
client.DeleteCollection(coll_link)
#staticmethod
def DeleteDocument(client, doc_id):
coll_link = database_link + '/colls/sales'
print('\n1.2 Deleting Document by Id\n')
doc_link = coll_link + '/docs/' + doc_id
client.DeleteDocument(doc_link)
#staticmethod
def GetSalesOrder(document_id):
# notice new fields have been added to the sales order
order2 = {'id' : document_id,
'account_number' : 'Account2',
'purchase_order_number' : 'PO15428132599',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
return order2
#staticmethod
def GetSalesOrder2(document_id):
order = {'id' : document_id, 'account_number' : 'Account3',#
'purchase_order_number' : 'PO15428132601',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
def run_sample():
with IDisposable(document_client.DocumentClient(HOST, {'masterKey': MASTER_KEY} )) as client:
try:
DocumentManagement.CreateDocuments(client)
DocumentManagement.CreateStoredProcedure(client)
DocumentManagement.CountEntries(client)
DocumentManagement.AddEntry(client)
DocumentManagement.CountEntries(client)
DocumentManagement.DeleteDocument(client,'SalesOrder')
DocumentManagement.DeleteCollection(client)
except errors.HTTPFailure as e:
print('\nrun_sample has caught an error. {0}'.format(e.message))
finally:
print("\nrun_sample done")
if __name__ == '__main__':
try:
run_sample()
except Exception as e:
print("Top level Error: args:{0}, message:N/A".format(e.args))
The reason your code is failing is because your GetSalesOrder2 method is not returning anything (or in other words returning an undefined object). If you look closely it is missing return statement. Please change this method to something like:
def GetSalesOrder2(document_id):
order = {'id' : document_id, 'account_number' : 'Account3',#
'purchase_order_number' : 'PO15428132601',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
return order
Also, each document in a collection need to have a unique id so please define a different id for this document.

Python - append to dictionary by name with multilevels 1, 1.1, 1.1.1, 1.1.2 (hierarchical)

I use openpyxl to read data from excel files to provide a json file at the end. The problem is that I cannot figure out an algorithm to do a hierarchical organisation of the json (or python dictionary).
The data form is like the following:
The output should be like this:
{
'id' : '1',
'name' : 'first',
'value' : 10,
'children': [ {
'id' : '1.1',
'name' : 'ab',
'value': 25,
'children' : [
{
'id' : '1.1.1',
'name' : 'abc' ,
'value': 16,
'children' : []
}
]
},
{
'id' : '1.2',
...
]
}
Here is what I have come up with, but i can't go beyond '1.1' because '1.1.1' and '1.1.1.1' and so on will be at the same level as 1.1.
from openpyxl import load_workbook
import re
from json import dumps
wb = load_workbook('resources.xlsx')
sheet = wb.get_sheet_by_name(wb.get_sheet_names()[0])
resources = {}
prev_dict = {}
list_rows = [ row for row in sheet.rows ]
for nrow in range(list_rows.__len__()):
id = str(list_rows[nrow][0].value)
val = {
'id' : id,
'name' : list_rows[nrow][1].value ,
'value' : list_rows[nrow][2].value ,
'children' : []
}
if id[:-2] == str(list_rows[nrow-1][0].value):
prev_dict['children'].append(val)
else:
resources[nrow] = val
prev_dict = resources[nrow]
print dumps(resources)
You need to access your data by ID, so first step is to create a dictionary where the IDs are the keys. For easier data manipulation, string "1.2.3" is converted to ("1","2","3") tuple. (Lists are not allowed as dict keys). This makes the computation of a parent key very easy (key[:-1]).
With this preparation, we could simply populate the children list of each item's parent. But before doing that a special ROOT element needs to be added. It is the parent of top-level items.
That's all. The code is below.
Note #1: It expects that every item has a parent. That's why 1.2.2 was added to the test data. If it is not the case, handle the KeyError where noted.
Note #2: The result is a list.
import json
testdata="""
1 first 20
1.1 ab 25
1.1.1 abc 16
1.2 cb 18
1.2.1 cbd 16
1.2.1.1 xyz 19
1.2.2 NEW -1
1.2.2.1 poz 40
1.2.2.2 pos 98
2 second 90
2.1 ezr 99
"""
datalist = [line.split() for line in testdata.split('\n') if line]
datadict = {tuple(item[0].split('.')): {
'id': item[0],
'name': item[1],
'value': item[2],
'children': []}
for item in datalist}
ROOT = ()
datadict[ROOT] = {'children': []}
for key, value in datadict.items():
if key != ROOT:
datadict[key[:-1]]['children'].append(value)
# KeyError = parent does not exist
result = datadict[ROOT]['children']
print(json.dumps(result, indent=4))

Possible Parser for Unknown String Format(soup?) from SUDS.client

I am using suds package to query a API from a website, the data returned from their website looks like this,:
(1). Can anyone tell me what kind of format is this?
(2). If so, what will be the easiest way to parse the data looks like this? I have dealt quite a lot with HTML/XML format using BeautifulSoup but before I lift my finger to write regular expressions for this type of format. I am curious is this some type of 'popular format' and there are actually some beautiful parser already written. Thanks.
# Below are the header and tail of the response..
(DetailResult)
{
status = (Status){ message = None code = "0" }
searchArgument = (DetailSearchArgument){ reqPartNumber = "BQ" reqMfg = "T" reqCpn = None }
detailsDto[] = (DetailsDto){
summaryDto = (SummaryDto){ PartNumber = "BQ" seMfg = "T" description = "Fast" }
packageDto[] =
(PackageDto){ fetName = "a" fetValue = "b" },
(PackageDto){ fetName = "c" fetValue = "d" },
(PackageDto){ fetName = "d" fetValue = "z" },
(PackageDto){ fetName = "f" fetValue = "Sq" },
(PackageDto){ fetName = "g" fetValue = "p" },
additionalDetailsDto = (AdditionalDetailsDto){ cr = None pOptions = None inv = None pcns = None }
partImageDto = None
riskDto = (RiskDto){ life= "Low" lStage = "Mature" yteol = "10" Date = "2023"}
partOptionsDto[] = (ReplacementDto){ partNumber = "BQ2" manufacturer = "T" type = "Reel" },
inventoryDto[] =
(InventoryDto){ distributor = "V" quantity = "88" buyNowLink = "https://www..." },
(InventoryDto){ distributor = "R" quantity = "7" buyNowLink = "http://www.r." },
(InventoryDto){ distributor = "RS" quantity = "2" buyNowLink = "http://www.rs.." },
},
}
This looks like some kind of nested repr output, similar to JSON but with
structure or object name information ("a Status contains a message and a code").
If it's nested, regexes alone won't do the job. Here is a rough pass at a pyparsing
parser
sample = """
... given sample text ...
"""
from pyparsing import *
# punctuation
LPAR,RPAR,LBRACE,RBRACE,LBRACK,RBRACK,COMMA,EQ = map(Suppress,"(){}[],=")
identifier = Word(alphas,alphanums+"_")
# define some types that can get converted to Python types
# (parse actions will do conversion at parse time)
NONE = Keyword("None").setParseAction(replaceWith(None))
integer = Word(nums).setParseAction(lambda t:int(t[0]))
quotedString.setParseAction(removeQuotes)
# define a placeholder for a nested object definition (since objDefn
# will be referenced within its own definition)
objDefn = Forward()
objType = Combine(LPAR + identifier + RPAR)
objval = quotedString | NONE | integer | Group(objDefn)
objattr = Group(identifier + EQ + objval)
arrayattr = Group(identifier + LBRACK + RBRACK + EQ + Group(OneOrMore(Group(objDefn)+COMMA)) )
# use '<<' operator to assign content to previously declared Forward
objDefn << objType + LBRACE + ZeroOrMore((arrayattr | objattr) + Optional(COMMA)) + RBRACE
# parse sample text
result = objDefn.parseString(sample)
# use pprint to list out indented parsed data
import pprint
pprint.pprint(result.asList())
Prints:
['DetailResult',
['status', ['Status', ['message', None], ['code', '0']]],
['searchArgument',
['DetailSearchArgument',
['reqPartNumber', 'BQ'],
['reqMfg', 'T'],
['reqCpn', None]]],
['detailsDto',
[['DetailsDto',
['summaryDto',
['SummaryDto',
['PartNumber', 'BQ'],
['seMfg', 'T'],
['description', 'Fast']]],
['packageDto',
[['PackageDto', ['fetName', 'a'], ['fetValue', 'b']],
['PackageDto', ['fetName', 'c'], ['fetValue', 'd']],
['PackageDto', ['fetName', 'd'], ['fetValue', 'z']],
['PackageDto', ['fetName', 'f'], ['fetValue', 'Sq']],
['PackageDto', ['fetName', 'g'], ['fetValue', 'p']]]],
['additionalDetailsDto',
['AdditionalDetailsDto',
['cr', None],
['pOptions', None],
['inv', None],
['pcns', None]]],
['partImageDto', None],
['riskDto',
['RiskDto',
['life', 'Low'],
['lStage', 'Mature'],
['yteol', '10'],
['Date', '2023']]],
['partOptionsDto',
[['ReplacementDto',
['partNumber', 'BQ2'],
['manufacturer', 'T'],
['type', 'Reel']]]],
['inventoryDto',
[['InventoryDto',
['distributor', 'V'],
['quantity', '88'],
['buyNowLink', 'https://www...']],
['InventoryDto',
['distributor', 'R'],
['quantity', '7'],
['buyNowLink', 'http://www.r.']],
['InventoryDto',
['distributor', 'RS'],
['quantity', '2'],
['buyNowLink', 'http://www.rs..']]]]]]]]

Categories

Resources