Search code examples
python-3.xapirestful-authentication

CDON API RESTful Api GET request


I'm currently working on fetching customer data from cdon, it's an e-commerce platform. They have their API documentation here:

CDON Api Docu

First let me show you my code:

myToken = '<token here>'
myUrl = 'https://admin.marketplace.cdon.com/api/reports/d8578ef8-723d-46cb-bb08-af8c9b5cca4c'
head = {'Authorization': 'token {}'.format(myToken),
'Status':'Online',
'format':'json'}
filters = '?filter={"Status":["Online"],"format": ["json"] }}'
response = requests.get(myUrl + filters, headers=head)
report = response.json()
print(report.products)

This is returning only the parameters. like for example at at this JSON: CDON Github

Status has a value Online this online is a group of itemsthat I only want to get.

What I'm trying to get is a response like this:

{

  "Products": [

    {

      "SKU": "322352",

      "Title": "Fabric Cover",

      "GTIN": "532523626",

      "ManufacturerArticleNumber": "",

      "StatusCDON": "Online",

      "ExposeStatusCDON": "Buyable",

      "InStock": 0,

      "InStockCDON": 0,

      "CurrentPriceSE": null,

      "OrdinaryPriceSE": null,

      "CurrentPriceCDONSE": 299.0000,

      "OrdinaryPriceCDONSE": null,

      "CurrentPriceDK": null,

      "OrdinaryPriceDK": null,

      "CurrentPriceCDONDK": null,

      "OrdinaryPriceCDONDK": null,

      "CurrentPriceNO": null,

      "OrdinaryPriceNO": null,

      "CurrentPriceCDONNO": null,

      "OrdinaryPriceCDONNO": null,

      "CurrentPriceFI": null,

      "OrdinaryPriceFI": null,

      "CurrentPriceCDONFI": null,

      "OrdinaryPriceCDONFI": null

    },

Which means the full list of the items that are Online

How should I put this... among all the API's I tried this one is very confusing, is this even RestFul? If I can achieve the python equivalent of this C# sample code:

public string Post(Guid repordId, string path)
{
  var filter = new JavaScriptSerializer().Serialize(new
  {
         States = new[] { "0" } // Pending state
  });

  var content = new FormUrlEncodedContent(new[]
  {
         new KeyValuePair("ReportId", repordId.ToString()),
         new KeyValuePair("format", "json"),
         new KeyValuePair("filter", filter)
  });

  var httpClient = new HttpClient() { BaseAddress = new Uri("https://admin.marketplace.cdon.com/") };
  httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("api", ApiKey);
  var response = httpClient.PostAsync(path, content).Result;
  response.EnsureSuccessStatusCode();

  return response.Content.ReadAsStringAsync().Result;
}

I may be able to undestand how this API works, the response that I got was taken manually from their report function in JSON format.

Image

I made many attempts and at that code ( my code ) I stopped, being on this for 4 hours made me give up and ask. Trust that I have searched as many references as I could. It's really confusing.

How do I get the response that I want? Filtering via url? or via header? is this even restful? Help T_T


Solution

  • The documentation states in the first line, emphasis mine:

    In order to generate a report you perform a POST call to the reports API with the parameters you wish to use for the report.

    Your Python code does not make a POST request, you are trying a GET request. The documentation goes on

    [...] to filter on Swedish orders you set the CountryCodes attribute to “Sweden” and to get returned and cancelled orders you set the States attribute to 2 and 3. So in the end the filter would look like this:

    {
        "CountryCodes": [ "Sweden" ],
        "States": ["2", "3"]
    }
    

    So you need to prepare a filter object (a dictionary in Python) with the filters you want. Luckily the Python syntax for dictionaries is equivalent (Python is flexible and also allows single-quoted strings):

    filter = {
        'CountryCodes': [ 'Sweden' ],
        'States': [ '0' ]
    }
    

    The documentation goes on

    You then post the parameters as form data (content-type: application/x-www-form-urlencoded) so the request body would look like this:

    ReportId=d4ea173d-bfbc-48f5-b121-60f1a5d35a34&format=json&filter={"CountryCodes":["Sweden"],"States":["2","3"]}
    

    application/x-www-form-urlencoded is the default for HTTP post, the requests module knows that and does this for you automatically. All you need to do is to prepare a data dict which will contain the data you want to post.

    data = {
        'ReportId': 'd4ea173d-bfbc-48f5-b121-60f1a5d35a34',
        'format': 'json'
        'filter': json.dumps(filter)
    }
    

    The filter parameter is supposed to be in JSON format. You must encode that yourself via json.dumps().

    import json
    
    head = { ... as above }
    filter = { ... as above }
    data = { ... as above }
    
    response = requests.post(url, data, header=head)
    

    I'll leave figuring out setting the Authorization header properly as an exercise for you. Partly because it isn't hard, partly because I have no intention of creating an API key with this website just for testing this and partly because it's entirely possible that your current header already works.