-1

I do not know how exactly to ask this question, as I can't share API access. If someone could help with the correct way of asking, will appreciate it.

I have a code which works perfectly fine and executes what I need, BUT when I use this API request code inside the DEF function, it returns with nothing or error...

The error is simple that I cannot get the output, or return with 0 values

This is the code:

def sm_main_data():


    #DATA PROCESSING - Impression|Engagements|VideoViews
    urlMain = "https://api.simplymeasured.com/v1/analytics/" + key.accountId + "/posts/metrics?\
    filter=analytics.timeseries_key.gte(" + config.start + ").lte(" + config.end + ")&\
    filter=channel.eq(" + config.which_social_media + ")&\
    metrics=analytics.engagement_total,analytics.video.views_count,analytics.impressions&\
    dimensions=data_source_id,channel,analytics.timeseries_key.by(" + config.per_what + ")"

    headers = {'content-type': 'application/json',
            'Authorization': 'Bearer ' + key.token}

    #Receive data from SM (main data) / modified it and save as JSON file
    responseMain = requests.get(urlMain, headers=headers).json()
    pprint.pprint(responseMain)
    pass

sm_main_data()

I have tried to print variables inside def:

print(key.accountId)
print(config.start)
print(config.end)
print(config.which_social_media)
print(config.per_what)

Which all printed correctly.

Currently I'm lost... and cannot get an even theoretical idea about what could go wrong. Why this code does not work inside def function???

Edit 1.0

Error

{u'errors': [{u'detail': u'`    filter` parameter is not supported.,`    metrics` parameter is not supported.,`    dimensions` parameter is not supported.',
              u'status': u'422',
              u'title': u'Unprocessable Entity'}]}

Edit 1.1

Code without def

#DATA PROCESSING - Impression|Engagements|VideoViews
urlMain = "https://api.simplymeasured.com/v1/analytics/" + key.accountId + "/posts/metrics?\
filter=analytics.timeseries_key.gte(" + config.start + ").lte(" + config.end + ")&\
filter=channel.eq(" + config.which_social_media + ")&\
metrics=analytics.engagement_total,analytics.video.views_count,analytics.impressions&\
dimensions=data_source_id,channel,analytics.timeseries_key.by(" + config.per_what + ")"

headers = {'content-type': 'application/json',
    'Authorization': 'Bearer ' + key.token}

#Receive data from SM (main data) / modified it and save as JSON file
responseMain = requests.get(urlMain, headers=headers).json()
pprint.pprint(responseMain)
11
  • You'll have to, at the very least, share the error you are getting. Commented Jul 17, 2018 at 16:55
  • @MartijnPieters Done Commented Jul 17, 2018 at 16:56
  • @MartijnPieters but when i remove def, everything is working perfectly. Commented Jul 17, 2018 at 16:56
  • @MartijnPieters you see the problem is, that I can't give you access to API, that someone can test it, so I assumed maybe anyone will know why it could happen, that I can test it. Commented Jul 17, 2018 at 16:59
  • 1
    Ah, your strings are indented, so now the extra whitespace is included in the string. Commented Jul 17, 2018 at 17:04

1 Answer 1

3

The error shows you are trying to send parameters with extra spaces before them to the server:

`    filter` parameter is not supported.
`    metrics` parameter is not supported.

Those extra spaces before the names are part of the parameter name, because you included those in your string:

def sm_main_data():
    # ...
    urlMain = "https://api.simplymeasured.com/v1/analytics/" + key.accountId + "/posts/metrics?\
    filter=analytics.timeseries_key.gte(" + config.start + ").lte(" + config.end + ")&\
    filter=channel.eq(" + config.which_social_media + ")&\
    metrics=analytics.engagement_total,analytics.video.views_count,analytics.impressions&\
    dimensions=data_source_id,channel,analytics.timeseries_key.by(" + config.per_what + ")"

# ^^^ those lines are indented but the whitespace is part of the string

You would get the same problem if you had indented the urlMain string definition for any other reason, like for a if statement or a try...except statement, not just a function. You'd have to not indent those parts that are inside a string literal.

Rather than use \ continuations in the string, you could use separate string literals to create one long string, or end the string literal with a closing " followed by a + and a " opening quote on the next line:

urlMain = (
    "https://api.simplymeasured.com/v1/analytics/" + 
    key.accountId + "/posts/metrics?" +
    "filter=analytics.timeseries_key.gte(" + config.start + ").lte(" + config.end + ")&" +
    "filter=channel.eq(" + config.which_social_media + ")&" +
    "metrics=analytics.engagement_total,analytics.video.views_count,analytics.impressions&" +
    "dimensions=data_source_id,channel,analytics.timeseries_key.by(" + config.per_what + ")"
)

All those + concatenations are not very readable, you should really use string formatting to insert values into a string.

However, you do not need to build a string like that anyway, as requests can do this for you when you give it a dictionary as the params argument. Use lists to pass in multiple values for a given parameter name:

url = "https://api.simplymeasured.com/v1/analytics/{k.accountId}/posts/metrics".format(
    k=key)
params = {
    'filter': [  # a list for multiple entries: filter=...&filter=...
        'analytics.timeseries_key.gte({c.start}).lte({c.end})'.format(c=config),
        'channel.eq({c.which_social_media})'.format(c=config),
    ],
    'metrics': (
        'analytics.engagement_total,analytics.video.views_count,'
        'analytics.impressions'),
    'dimensions':
        'data_source_id,channel,'
        'analytics.timeseries_key.by({c.per_what})'.format(c=config),
}
headers = {'Authorization': 'Bearer {k.token}'.format(k=key)}
responseMain = requests.get(urlMain, params=params, headers=headers).json()

Here I used str.format() to insert values from the config and key objects; note that the placeholders pull out the attributes

Note: I removed the Content-Type header, as that header doesn't apply to a GET request (which doesn't have content, the request body is always empty).

Sign up to request clarification or add additional context in comments.

2 Comments

That's works!! But have an extra question, how to modify my code, to make it actually work? is it possible?
Yes...) Thank you for your help... Sorry for the unclear question but this answer helped me a lot!!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.