timotheus / ebaysdk-python

eBay API SDK for Python
https://developer.ebay.com/tools/sdks
Other
808 stars 326 forks source link

The SDK doesn't generate proper XML for the 'VariationSpecificSet' when adding a variation listing type. #288

Open mgeorge3 opened 5 years ago

mgeorge3 commented 5 years ago

When creating a variation listing the SDK does not generate the expected XML for Ebay which results in a Duplicate name-value pair error.

XML Currently Generated

<VariationSpecificsSet>
   <NameValueList>
           <Name>Style</Name>
           <Value>Zuma</Value>
   </NameValueList>
   <NameValueList>
            <Name>Style</Name>
            <Value>Rocky</Value>
   </NameValueList>
   <NameValueList>
            <Name>Style</Name>
            <Value>Chase</Value></NameValueList>
</VariationSpecificsSet>

Correct XML (Avoids Duplicate name-value pairs), since the Name 'Style' has three types.

<VariationSpecificsSet>
  <NameValueList>
     <Name>Style</Name>
     <Value>Zuma</Value>
     <Value>Rocky</Value>
     <Value>Chase</Value>
   </NameValueList>
</VariationSpecificsSet>

The Python looks like this:

carList = [ 'Zuma, 'Rocky', 'Chase' ]
'VariationSpecificsSet': {
                    "NameValueList": [
                        {"Name": "Style", "Value": carList},
                    ],
                },

If someone could give me a little help on navigating where to fix this in the SDK, I could probably do it, or maybe I am not setting up the dictionary correctly.

Thank you for your help!

TimSC commented 2 years ago

It looks like this has been fixed. I'm testing with ebaysdk 2.2.0. Your code now converts to XML as expected:

<VariationSpecificsSet>
   <NameValueList>
      <Name>Style</Name>
      <Value>Zuma</Value>
      <Value>Rocky</Value>
      <Value>Chase</Value>
   </NameValueList>
</VariationSpecificsSet>

My approach to automatically generate VariationSpecificsSet:


def RegisterVariant(codes, name, value):
    if name not in codes:
        codes[name] = set([value,])
    else:
        codes[name].add(value,)

def GenerateVariations(variations):
    codes = {}
    for var in variations:
        specifics = var['VariationSpecifics']['NameValueList']
        if isinstance(specifics, list):
            for specific in specifics:
                RegisterVariant(codes, specific['Name'], specific['Value'])
        else:
            RegisterVariant(codes, specifics['Name'], specifics['Value'])

    vss = []
    for k, v in codes.items():
        vss.append({'Name': k, 'Value': list(v)})
    return vss

itemData = {}
variations = [{'StartPrice': '1.7', 'Quantity': '20', 'VariationSpecifics': {'NameValueList': {'Name': 'size', 'Value': '10cm / 4inches'}}}, 
    {'StartPrice': '1.9', 'Quantity': '20', 'VariationSpecifics': {'NameValueList': {'Name': 'size', 'Value': '14cm / 5.5inches'}}}]

itemData['Variations'] = {'Variation': variations}

vss = GenerateVariations(variations)
itemData['Variations']['VariationSpecificsSet'] = {'NameValueList': vss}

print (itemData['Variations'])

which results in:

{
   'Variation': [
      {'StartPrice': '1.7', 'Quantity': '20', 'VariationSpecifics': {'NameValueList': {'Name': 'size', 'Value': '10cm / 4inches'}}}, 
      {'StartPrice': '1.9', 'Quantity': '20', 'VariationSpecifics': {'NameValueList': {'Name': 'size', 'Value': '14cm / 5.5inches'}}}
   ], 
   'VariationSpecificsSet': {'NameValueList': [{'Name': 'size', 'Value': ['14cm / 5.5inches', '10cm / 4inches']}]}
}

which gets converted to XML:

<Variations>
   <Variation>
      <Quantity>20</Quantity>
      <StartPrice>1.7</StartPrice>
      <VariationSpecifics>
         <NameValueList>
            <Name>size</Name>
            <Value>10cm / 4inches</Value>
         </NameValueList>
      </VariationSpecifics>
   </Variation>
   <Variation>
      <Quantity>20</Quantity>
      <StartPrice>1.9</StartPrice>
      <VariationSpecifics>
         <NameValueList>
            <Name>size</Name>
            <Value>14cm / 5.5inches</Value>
         </NameValueList>
      </VariationSpecifics>
   </Variation>
   <VariationSpecificsSet>
      <NameValueList>
         <Name>size</Name>
         <Value>10cm / 4inches</Value>
         <Value>14cm / 5.5inches</Value>
      </NameValueList>
   </VariationSpecificsSet>
</Variations>

It seems that a list in ebaysdk is interpreted as a repeated key.