Making Yahoo Weather API request with OAuth 1
Asked Answered
B

4

16

I ran into a problem with Yahoo Weather API because it wasn't giving me any data. After visiting YDN website I've found out that all requests should be updated to OAuth 1 starting from March 15th (but I got working it just today!). It's also said to include Yahoo App key and secret. What the request url should look like now, when I must use my app key and secret?

Before, I got such request string: https://query.yahooapis.com/v1/public/yql?q=SOME_QUERY&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=

UPDATE

13 minutes after I originally asked this question API calls with /v1/public/ endpoint are working again. But it's still interesting for me to get an answer to my question.

UPDATE

It's down again :(

Bogard answered 23/3, 2016 at 18:58 Comment(2)
Yesterday public access went down for us, then came back up, then went back down again either last night or this morning. Doesn't sound like a fun week for the devs at Yahoo.Uro
Yahoo, you used to be coolVaughn
T
12

If you simply replace

http://weather.yahooapis.com/

with

http://xml.weather.yahoo.com/

it should work ;)

Tear answered 28/3, 2016 at 13:3 Comment(2)
Works for me, where did you find that url?Mabuse
Wonder if this is only a temporary fix? It's great as of now, but it may stop working too in the near future.Camaraderie
B
5

Current Solution As of Mid-April 2016 - Yahoo is Allowing YQL Requests Without Oauth Again Due to Developer Outrage

You can once again write a query without any authentication like the following:

https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22nome%2C%20ak%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys

Previous answers below in case they were of help for anyone. During certain periods of Yahoo's changes they did work.


Below are Older Versions of this Answer for Historical Reasons That May Also Still Work


Updated Answer After Yahoo's Latest Round of Updates - Insecure OAuth Workaround

You will need to create a Yahoo account & then create a web application at https://developer.yahoo.com/apps/create/

You will then need to use an OAuth Library to properly encode your Client ID & Client Secret. Here is an example in JavaScript based off a Yahoo Example Page & a 2008 Blog Article by Paul Donnelly. This generates an encoded URL to use to request a weather feed.

//Fill in your consumer Key & Secret from Yahoo's App & adjust location as needed. 
//This Key & Secret combination is invalid & won't work for you
var consumerKey = "dj0yJmk9NkRjbXpjUEhPbjlnJmQ9WVdrOVFUQTFaV2wxTjJrbXnHbz3NQSktJnM9Y29uc3VtZXJzZWNyZXQmeD0wOQ--";
var consumerSecret = "9bea8a9k3934d16365ek7e23e0abo1bba4q5c03c";
var locationToQuery = "90210"; //Can be zip code or anything that works in the query select woeid from geo.places(1) where text=<Your Location>


var makeSignedRequest = function(ck,cs,loc) {

    var encodedurl = "https://query.yahooapis.com/v1/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22"+loc+"%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";

    var accessor = { consumerSecret: cs, tokenSecret: ""};          
    var message = { action: encodedurl, method: "GET", parameters: [["oauth_version","1.0"],["oauth_consumer_key",ck]]};

    OAuth.setTimestampAndNonce(message);
    OAuth.SignatureMethod.sign(message, accessor);

    var parameterMap = OAuth.getParameterMap(message);
    var baseStr = OAuth.decodeForm(OAuth.SignatureMethod.getBaseString(message));           
    var theSig = "";

    if (parameterMap.parameters) {
        for (var item in parameterMap.parameters) {
            for (var subitem in parameterMap.parameters[item]) {
                if (parameterMap.parameters[item][subitem] == "oauth_signature") {
                    theSig = parameterMap.parameters[item][1];                    
                    break;                      
                }
            }
        }
    }

    var paramList = baseStr[2][0].split("&");
    paramList.push("oauth_signature="+ encodeURIComponent(theSig));
    paramList.sort(function(a,b) {
        if (a[0] < b[0]) return -1;
        if (a[0] > b[0]) return 1;
        if (a[1] < b[1]) return  -1;
        if (a[1] > b[1]) return 1;
        return 0;
    });

    var locString = "";
    for (var x in paramList) {
        locString += paramList[x] + "&";                
    }

    var finalStr = baseStr[1][0] + "?" + locString.slice(0,locString.length - 1);

    return finalStr;
};

//Use the encodedURL to make your request
var encodedURL = makeSignedRequest(consumerKey, consumerSecret, locationToQuery); 

It should be noted never to show your consumer key or consumer secret to the public. You can use your own Yahoo Credentials in this Plunkr: http://plnkr.co/edit/EvLbgs

Original Answer

Unfortunately as of right now, the servers are down to create that app. Ideally, once they're back up you can use server side code to do the oauth part. I'll try to edit this answer when that happens. According to Yahoo the URL will be the same except without the /public part. The big difference will be that you need to send request headers with the URL that authenticate your account.

Here's a temporary fix until then. You can still use a YQL query geo.places with a zip code to get the woeid.

select * from geo.places where text=90210 limit 1

You can then grab your woeid from there & use it in the following url to get an xml feed:

http://weather.yahooapis.com/forecastrss?w=WOEID_GOES_HERE

I've created a Plunker as an example of this temporary fix here: http://plnkr.co/edit/dClPDtnToMhHqvKpfCzj?p=preview

Here's the gist of it though using jQuery:

var zipCode = 90210;

$.ajax({
    dataType: "json",
    headers:  { "Accept": "application/json; odata=verbose" },
    url: "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.places%20where%20text%3D"+zipCode+"%20limit%201&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys",
    beforeSend: function(xhr){xhr.setRequestHeader('Accept', 'application/json; odata=verbose');},
    success: function(data){
        $.getJSON("https://query.yahooapis.com/v1/public/yql?callback=?", {
            q: "select * from xml where url=\"https://weather.yahooapis.com/forecastrss?w="+data.query.results.place.locality1.woeid+"\"",
            format: "json"
        },function (data) {
          var weather = data.query.results.rss.channel;
          var html = '<div><span class="temperature">'+weather.item.condition.temp+'<span class="degree">&deg;</span><sup>'+weather.units.temperature+'</sup></span><br><span class="wind-chill">Feels like: '+weather.wind.chill+'<span class="degree">&deg;</span></span></div></a>';
          $("#weather").html(html);
        });
    },
});
Belia answered 24/3, 2016 at 14:57 Comment(11)
Sometimes locality1 and locality 2 both return null instead of objects. Made a small modification to fix this by falling back on postal if the first two are empty, feel free to use it: plnkr.co/edit/0ZKjQBlKG1D2xAe7YXvi?p=previewUro
Thanks a lot. Really neat solution :) Actually, I don't have a problem with creating app key and secret as long as I already had my application created :) So you can update your answer accordingly. I'm also wondering if there's any way to get a JSON-formatted data?Bogard
The above snippet of code will transform the XML into a JSON object. Use the weather variable on the line: var weather = data.query.results.rss.channel; Unfortunately Yahoo's Dev App section still appears to be down.Belia
Yeah, I see, but it's not applicable in my case because my app is written in Swift (iOS application). I meant, is there a direct link like the one you've provided above (weather.yahooapis.com/forecastrss?w=WOEID_GOES_HERE) that will get the JSON output rather than XML?Bogard
Ok, a small update from me: I've been able to adapt to answer to Swift. Thanks a lot again. I really like the workaround you've provided. If you can, please, post with OAuth part when Yahoo's Dev App section will be available.Bogard
Btw, you can not only use zip code to determine woeid, but other parameters as well. For example, I used country and city name of the location.Bogard
forecastrss now returning: Please provide valid credentials. OAuth oauth_problem="OST_OAUTH_PARAMETER_ABSENT_ERROR", realm="yahooapis.com"Vaughn
is '/v1/yql' working for anyone after an oauth authenication? I am getting a 401Vaughn
The approach described in this answer is how my app was using the API in the first place. Currently, it is also the approach not working anymore. The direct query to weather.yahoo is complaining about missing Oauth credentials, while the query via yql is working.Cowskin
The OAUTH reference URLs that you are using in the Plunkr are not working. Can you please help? Thanks.Spoilsman
You shouldn't need OAUTH anymore. Yahoo recently removed the requirement for using it after many complaints.Belia
A
4

We finally got our yql weather working again using two-legged authorization using yosdk: (https://github.com/isaacs/authentipede)

And using this script

<?php
include_once("yosdk/lib/Yahoo.inc");

define("API_KEY","your-api-key-here");
define("SHARED_SECRET","your-secret-here");
YahooLogger::setDebug(true);

$twoleg = new YahooApplication (API_KEY, SHARED_SECRET);
$query = 'select * from weather.forecast where woeid in (select woeid from geo.places(1) where text="84054") and u="f"';
print_r ($results);

I found this from this discussion: (How do I get started with oauth for YQL for historical stock data?)

Arrowworm answered 24/3, 2016 at 18:7 Comment(1)
This is great content, but you forgot to do the call. I know more people will be desperate and lost as me $results = $twoleg->query($query);Bruit
B
2

Apparently, it is meant to no longer work using Public API. For now on, you will be required to use OAuth through Secret Key.

Bib answered 24/3, 2016 at 14:41 Comment(2)
Ok. Can you, please, provide a sample request url for OAuth 1? I've been searching for sample requests in documentation, but I have found nothing.Bogard
@Bogard That's because the useless people at Yahoo haven't documented it anywhere!Camaraderie

© 2022 - 2024 — McMap. All rights reserved.