In Using the Open Weather Map API with curl we saw how to fetch the weather using curl. Now we are going to use Perl as that will make it easier to use this as part of a larger application. Before you read this article, make sure you read the one using curl.

Configuration file

As you can read in the other article, in order to access the Open Weather Map API we need to have an API key. We could store the API-key in a variable in the code, but then if we distribute the code we also distribute the API key.

Usually it is a better practice to have all of these keys and sometimes passwords in external files that are not stored together with the code of the application. That makes it also a lot easier to have a separate set of keys for development, testing, and production.

We created a file called config.ini with the following content:

[openweathermap]
api=wkfhshoiaslv

Where of course I put the API-key from Open Weather Maps.

In the code we used Config::Tiny to reading the configuration INI file. This is in the get_api_key function.

We used the get function provided by LWP::Simple to access the API and the decode_json function provided by Cpanel::JSON::XS as featured in the article about JSON to convert the received JSON string into a perl data structure.

Then in the main function we print the temperature which is inside the "main" key of the retrieved data structure using $weather->{main}{temp}; and we also use the Dumper function to show the whole data structure as a Perl hash.

The code

examples/get_weather.pl

use 5.010;
use strict;
use warnings;

use LWP::Simple qw(get);
use Config::Tiny;
use Cpanel::JSON::XS qw(decode_json);
use Data::Dumper qw(Dumper);

sub get_api_key {
    my $config = Config::Tiny->read('config.ini');
    return $config->{openweathermap}{api};
}

sub get_weather {
    my ($api_key, $location) = @_;

    my $url = "https://api.openweathermap.org/data/2.5/weather?q=$location&units=metric&appid=$api_key";
    my $json_str = get $url;
    return decode_json $json_str;
}

sub main {
    my $location = shift @ARGV or die "Usage: $0 LOCATION\n";
    my $api_key = get_api_key();
    my $weather = get_weather($api_key, $location);

    say $weather->{main}{temp};
    print Dumper $weather;
}

main();


The dumped data

$VAR1 = {
          'weather' => [
                         {
                           'id' => 701,
                           'description' => 'mist',
                           'main' => 'Mist',
                           'icon' => '50n'
                         }
                       ],
          'id' => 3054643,
          'base' => 'stations',
          'dt' => 1518193800,
          'cod' => 200,
          'name' => 'Budapest',
          'coord' => {
                       'lat' => '47.5',
                       'lon' => '19.04'
                     },
          'clouds' => {
                        'all' => 75
                      },
          'visibility' => 4500,
          'main' => {
                      'temp' => 3,
                      'humidity' => 89,
                      'temp_min' => 3,
                      'temp_max' => 3,
                      'pressure' => 1016
                    },
          'sys' => {
                     'sunset' => 1518191920,
                     'id' => 5724,
                     'message' => '0.0031',
                     'sunrise' => 1518155886,
                     'country' => 'HU',
                     'type' => 1
                   },
          'wind' => {
                      'speed' => '2.1',
                      'deg' => 350
                    }
        };

Conclusion

Once we have this basic solution we can integrate this code into a larger application or change the requested URL to match other API end-points.