yahoo-oauth icon indicating copy to clipboard operation
yahoo-oauth copied to clipboard

get 401 error when sending request to yahoo gemini api

Open smthxwolf opened this issue 9 years ago • 12 comments

hello, this is the best python lib i have found to access yahoo oauth2. i have get access token using this lib. but when i tried to send request to yahoo gemini api, i always got an 401 Response

here is the output:

[2015-12-16 10:55:11,472 DEBUG] [yahoo_oauth.yahoo_oauth.__init__] Checking 
[2015-12-16 10:55:11,477 DEBUG] [yahoo_oauth.yahoo_oauth.token_is_valid] ELAPSED TIME : 164795.42615
[2015-12-16 10:55:11,477 DEBUG] [yahoo_oauth.yahoo_oauth.token_is_valid] TOKEN HAS EXPIRED
[2015-12-16 10:55:11,478 DEBUG] [yahoo_oauth.yahoo_oauth.refresh_access_token] REFRESHING TOKEN
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): api.login.yahoo.com
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:100: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
[2015-12-16 10:55:13,310 DEBUG] [yahoo_oauth.yahoo_oauth.token_is_valid] ELAPSED TIME : 1.83199310303
[2015-12-16 10:55:13,311 DEBUG] [yahoo_oauth.yahoo_oauth.token_is_valid] TOKEN IS STILL VALID
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): api.admanager.yahoo.com
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:100: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
<Response [401]>
INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): api.admanager.yahoo.com
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:100: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
<Response [401]>
None

here is my code:

from yahoo_oauth import OAuth2
import requests
def get_simple_report(min_date, max_date):
    yahoo_oauth = OAuth2(None, None, from_file='./config/yahooads.ini')
    if not yahoo_oauth.token_is_valid():
            yahoo_oauth.refresh_access_token()
    access_token = yahoo_oauth.access_token
    advertiser_id = 1151514
    # get campaign list
    campaign_end_point = "https://api.admanager.yahoo.com/v1/rest/campaign/"
    payload_dict = {
            "advertiserId":advertiser_id,
            "mr":2
            }
    header = {'Authorization': 'Bearer ' + access_token,'Accept': 'application/json','Content-Type': 'application/json'}
    response = requests.get(campaign_end_point, data=payload_dict, headers = header)
    print response

    response = yahoo_oauth.session.put(campaign_end_point, params=payload_dict)
    print response

i also tried rauth but got the same error.

could you pls help me with it? thanks

smthxwolf avatar Dec 16 '15 03:12 smthxwolf

Hello @jiangchunyang ,

  1. First of all, i don't think this lib support _.ini_ file, but this might the opportunity to do so. You can submit a patch if you want :wink:
  2. I don't think you need to use _requests_ since it's already encapsulated in the lib via rauth.
from yahoo_oauth import OAuth2

def get_simple_report(min_data, max_date):
    yahoo_oauth = OAuth2(None, None, from_file='./config/yahooads.json')
    # No need to check token validity, the lib auto check for you. Sorry the doc is kind of misleading
    advertiser_id = 1151514
    campaign_end_point = "https://api.admanager.yahoo.com/v1/rest/campaign/"
    payload_dict = {
            "advertiserId":advertiser_id,
            "mr":2
            }
    response = yahoo_oauth.session.put(campaign_end_point, data=payload_dict)
    print(response.status_code, response.reason)
    return response

@jiangchunyang Could you please try this and let me know ?

have a good one

josuebrunel avatar Dec 16 '15 11:12 josuebrunel

hi @josuebrunel, thank you for your quick response. i tried your suggested codes, but still got 401 response.

/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:100: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
/usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/util/ssl_.py:100: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
(401, 'Authorization Required')

i also google this problem, now i suspect it's not because of the codes. i read instructions here: https://developer.yahoo.com/gemini/ i applied an api on this page https://developer.yahoo.com/gemini/apply.html but haven't got any response mail yet. however i managed to access this page https://developer.yahoo.com/apps/create/ and created an app and got consumer key & secret, which i'm using to get gemini report. is it the reason? thanks

smthxwolf avatar Dec 17 '15 03:12 smthxwolf

@jiangchunyang ok i see, consumer key and consumer secret are required to make the lib work Once you have them, put them in a json or yaml file

example (yahooads.json)

{
    "consumer_key": "your consumer key here",
    "consumer_secret": "your consumer sercret here"
}

then in your code

from yahoo_oauth import OAuth2

oauth = OAuth2(None, None, from_file='config/yahooads.json')
....
oauth.session.put(campaign_end_point, data=payload_dict)

Something like this. If it still doesn't work i'll try to provide better example within the weekend

josuebrunel avatar Dec 17 '15 08:12 josuebrunel

many thanks for your time. just one more question which confused me these days, is it required that the access token (or some other information) is put into the request header, if i use rauth or urllib to send request to yahoo's api?

smthxwolf avatar Dec 17 '15 09:12 smthxwolf

@jiangchunyang , yeah you can check these lines https://github.com/josuebrunel/yahoo-oauth/blob/master/yahoo_oauth/yahoo_oauth.py#L147-L156. yahoo_oauth does it for you already.

josuebrunel avatar Dec 17 '15 10:12 josuebrunel

Hey @jiangchunyang, First of all, consumer_key and consumer_secret are private data, so you shouldn't share them. I've found the issue. Yahoo Fantasay Sport doesn't use OAuth2, instead it uses OAuth1.

>>> from yahoo_oauth import OAuth1
>>> oauth = OAuth1(None, None, from_file='oauth1.json')
[2015-12-19 11:21:18,105 DEBUG] [yahoo_oauth.yahoo_oauth.__init__] Checking 
[2015-12-19 11:21:18,105 DEBUG] [yahoo_oauth.yahoo_oauth.token_is_valid] ELAPSED TIME : 150.253709078
[2015-12-19 11:21:18,105 DEBUG] [yahoo_oauth.yahoo_oauth.token_is_valid] TOKEN IS STILL VALID
>>> response = oauth.session.get('http://fantasysports.yahooapis.com/fantasy/v2/game/223')
>>> response.status_code, response.reason
(200, 'OK')
>>> 
>>> response.content
'<?xml version="1.0" encoding="UTF-8"?>\n<fantasy_content xml:lang="en-US" yahoo:uri="http://fantasysports.yahooapis.com/fantasy/v2/game/223" time="56.034088134766ms" copyright="Data provided by Yahoo! and STATS, LLC" refresh_rate="31" xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xmlns="http://fantasysports.yahooapis.com/fantasy/v2/base.rng">\n <game>\n  <game_key>223</game_key>\n  <game_id>223</game_id>\n  <name>Football PLUS</name>\n  <code>pnfl</code>\n  <type>full</type>\n  <url>http://football.fantasysports.yahoo.com/f2</url>\n  <season>2009</season>\n  <is_registration_over>1</is_registration_over>\n </game>\n</fantasy_content>\n'
>>> 

Try this and let me know :wink: Don't hesitate to ping me if you face any other trouble . I will try to inquire about Yahoo Gemini tonight, just like you i got a 401 Authorization Required. Hope i will find the issue soon enough

josuebrunel avatar Dec 19 '15 10:12 josuebrunel

@josuebrunel ,it works! although fantasy sport is not what i'm trying to access, i'm still excited to work it through. i have deleted my last post with key & secret. you are right. thank you for your efforts on this Gemini issue. hope to get good news : )

smthxwolf avatar Dec 19 '15 11:12 smthxwolf

@jiangchunyang hello. I think Yahoo Gemini API Key is different from the one we use for other services Yahoo Gemini API Key Application Form

And in the list of permissions, when creating a Yahoo App, Yahoo Gemini doesn't appear

screenshot from 2015-12-20 16-38-54

I believe that the issue is with the Api Key. Check the first step of the Get Started section

screenshot from 2015-12-20 16-54-58

I applied for Yahoo Gemini Api Key, and i'm waiting for yahoo to reply.

josuebrunel avatar Dec 20 '15 15:12 josuebrunel

@josuebrunel hello, i agree. i did some search yesterday and found some posts on YDN which involved the same issue. nobody replies those posts though. so i guess i have to wait for yahoo's email now.

smthxwolf avatar Dec 21 '15 02:12 smthxwolf

Hi Guys!

I am so delighted to see this thread! I spent a few days trying to troubleshoot the same issue. I am trying to use yahoo gemini api to fetch campaign reports @ https://developer.yahoo.com/gemini/guide/reporting/

from yahoo_oauth import OAuth2
yahoo_oauth = OAuth2(None, None, from_file='/Users/srikanthsundara/DWH/mktg/campaign_yahoo/yahooads.json')
advertiser_id = 123
campaign_end_point = "https://api.gemini.yahoo.com/v2/rest/reports"
payload_dict =  { "cube": "performance_stats",
"fields": [
    { "field": "Ad ID" },
    { "field": "Day" },
    { "alias": "My dummy column", "value": "" },
    { "field": "Impressions" },
    { "field": "Ad Image URL", "alias": "url" }
  ],
"filters": [
    { "field": "Advertiser ID", "operator": "=", "value": 123 },
    { "field": "Day", "operator": "between", "from": "2016-08-01", "to": "2016-08-03" }
  ]
}
response = yahoo_oauth.session.get(campaign_end_point,data=payload_dict)
print(response.status_code, response.reason)

first time it opened up the browser and gave me a code. I am thinking its the token.

output

(400, 'Bad Request')

Can you guys please suggest how to authenticate this when we are running this program on Ubuntu linux where there is no browser etc ?

Again, thanks a ton for this post!

you guys inspire me :)

ssundara-nw avatar Aug 18 '16 18:08 ssundara-nw

Hi @ssundara-nw , sorry for the delay. I will dive into that this weekend.

josuebrunel avatar Aug 19 '16 08:08 josuebrunel

Hey people, there's an example of Yahoo! OAuth working with Yahoo Gemini by @kubber on #48. Check it out, it will surely help you out.

josuebrunel avatar Aug 31 '16 09:08 josuebrunel