Weather-WeatherKit/README.pod
=head1 NAME
Weather::WeatherKit - Apple WeatherKit REST API client
=head1 SYNOPSIS
use Weather::WeatherKit;
my $wk = Weather::WeatherKit->new(
team_id => $apple_team_id, # Apple Developer Team Id
service_id => $weatherkit_service_id, # WeatherKit Service Id
key_id => $key_id, # WeatherKit developer key ID
key => $private_key # Encrypted private key (PEM)
);
# Request current weather:
my $report = $wk->get(
lat => $lat, # Latitude
lon => $lon, # Longitude
dataSets => 'currentWeather'
);
# Request forecast for 8 days, use Weather::API::Base helper functions
# for ISO dates, and get full HTTP::Response object to check for success
use Weather::API::Base qw(:all);
my $response = $wk->get_response(
lat => $lat,
lon => $lon,
dataSets => 'forecastHourly',
hourlyStart => ts_to_iso_date(time()),
hourlyEnd => ts_to_iso_date(time()+8*24*3600)
);
if ($response->is_success) {
my $json = $response->decoded_content;
} else {
die $response->status_line;
}
=head1 DESCRIPTION
Weather::WeatherKit provides basic access to the Apple WeatherKit REST API (v1).
WeatherKit replaces the Dark Sky API and requires an Apple developer subscription.
Pease see the L<official API documentation|https://developer.apple.com/documentation/weatherkitrestapi>
for datasets and usage options as well as the L<required attribution|https://developer.apple.com/weatherkit/get-started/#attribution-requirements>.
It was made to serve the apps L<Xasteria|https://astro.ecuadors.net/xasteria/> and
L<Polar Scope Align|https://astro.ecuadors.net/polar-scope-align/>, but if your service
requires some extra functionality, feel free to contact the author about it.
=head1 CONSTRUCTOR
=head2 C<new>
my $wk = Weather::WeatherKit->new(
team_id => "MLU84X58U4",
service_id => "com.domain.myweatherapp",
key_id => $key_id,
key => $private_key?,
key_file => $private_key_pem?,
language => $lang_code?,
timeout => $timeout_sec?,
expiration => $expire_secs?,
ua => $lwp_ua?,
curl => $use_curl?
);
Required parameters:
=over 4
=item * C<team_id> : Your 10-character Apple developer Team Id - it can be located
on the Apple developer portal.
=item * C<service_id> : The WeatherKit Service Identifier created on the Apple
developer portal. Usually a reverse-domain type string is used for this.
=item * C<key_id> : The ID of the WeatherKit key created on the Apple developer portal.
=item * C<key_file> : The encrypted WeatherKit private key file that you created on
the Apple developer portal. On the portal you download a PKCS8 format file (.p8),
which you first need to convert to the PEM format. On a Mac you can convert it simply:
openssl pkcs8 -nocrypt -in AuthKey_<key_id>.p8 -out AuthKey_<key_id>.pem
=item * C<key> : Instead of the C<.pem> file, you can pass its contents directly
as a string. If both are provided C<key> takes precedence over C<key_file>.
=back
Optional parameters:
=over 4
=item * C<language> : Language code. Default: C<en_US>.
=item * C<timeout> : Timeout for requests in secs. Default: C<30>.
=item * C<ua> : Pass your own L<LWP::UserAgent> to customise the agent string etc.
=item * C<curl> : If true, fall back to using the C<curl> command line program.
This is useful if you have issues adding http support to L<LWP::UserAgent>, which
is the default method for the WeatherKit requests. It assumes the C<curl> program
is installed in C<$PATH>.
=item * C<expiration> : Token expiration time in seconds. Tokens are cached until
there are less than 10 minutes left to expiration. Default: C<7200>.
=back
=head1 METHODS
=head2 C<get>
my $report = $wk->get(
lat => $lat,
lon => $lon,
dataSets => $datasets
%args?
);
my %report = $wk->get( ... );
Fetches datasets (weather report, forecast, alert...) for the requested location.
Returns a string containing the JSON data, except in array context, in which case,
as a convenience, it will use L<JSON> to decode it directly to a Perl hash.
Requires L<LWP::UserAgent>, unless the C<curl> option was set.
If the request is not successful, it will C<die> throwing the C<< HTTP::Response->status_line >>.
=over 4
=item * C<lat> : Latitude (-90 to 90).
=item * C<lon> : Longitude (-18 to 180).
=item * C<dataSets> : A comma-separated string of the dataset(s) you request. Example
supported data sets: C<currentWeather, forecastDaily, forecastHourly, forecastNextHour, weatherAlerts>.
Some data sets might not be available for all locations. Will return empty results
if parameter is missing.
=item * C<%args> : See the official API documentation for the supported weather API
query parameters which you can pass as key/value pairs.
=back
=head2 C<get_response>
my $response = $wk->get_response(
lat => $lat,
lon => $lon,
dataSets => $datasets
%args?
);
Same as C<get> except it returns the full L<HTTP::Response> from the API (so you
can handle bad requests yourself).
=head1 CONVENIENCE METHODS
=head2 C<jwt>
my $jwt = $wk->jwt(
iat => $iat?,
exp => $exp?
);
Returns the JSON Web Token string in case you need it. Will return a cached one
if it has more than 10 minutes until expiration and you don't explicitly pass an
C<exp> argument.
=over 4
=item * C<iat> : Specify the token creation timestamp. Default is C<time()>.
=item * C<exp> : Specify the token expiration timestamp. Passing this parameter
will force the creation of a new token. Default is C<time()+7200> (or what you
specified in the constructor).
=back
=head1 HELPER FUNCTIONS (from Weather::API::Base)
The parent class L<Weather::API::Base> contains some useful functions e.g.:
use Weather::API::Base qw(:all);
# Get time in ISO (YYYY-MM-DDTHH:mm:ss) format
my $datetime = ts_to_iso_date(time());
# Convert 30 degrees Celsius to Fahrenheit
my $result = convert_units('C', 'F', 30);
See the doc for that module for more details.
=head1 KNOWN ISSUES
=head2 400 errors on 10 day forecast
Although WeatherKit is supposed to provide 10 days of forecast, at some point users
started getting C<400> errors when requesting (e.g. with C<hourlyEnd>) more than 8 or 9
days of forecast. If you encounter this issue, limit your forecast request to 9 or
8 days in the future.
=head1 OTHER PERL WEATHER MODULES
Some Perl modules for current weather and forecasts from other sources:
=head2 L<Weather::OWM>
OpenWeatherMap uses various weather sources combined with their own ML and offers
a couple of free endpoints (the v2.5 current weather and 5d/3h forecast) with generous
request limits. Their newer One Call 3.0 API also offers some free usage (1000 calls/day)
and the cost is per call above that. If you want access to history APIs, extended
hourly forecasts etc, there are monthly subscriptions. L<Weather::OWM> is from the
same author as this module and similar in use.
=head2 L<Weather::Astro7Timer>
The 7Timer! weather forecast is completely free and would be of extra interest if
you are interested in astronomy/stargazing. It uses the standard NOAA forecast,
but also calculates astronomical seeing and transparency. It can be accessed with
L<Weather::Astro7Timer>, which is another module similar to this (same author).
=head1 AUTHOR
Dimitrios Kechagias, C<< <dkechag at cpan.org> >>
=head1 BUGS
Please report any bugs or feature requests either on L<GitHub|https://github.com/dkechag/Weather-WeatherKit> (preferred), or on RT (via the email
C<bug-weather-weatherkit at rt.cpan.org> or L<web interface|https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Weather-WeatherKit>).
I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
=head1 GIT
L<https://github.com/dkechag/Weather-WeatherKit>
=head1 LICENSE AND COPYRIGHT
This software is copyright (c) 2023 by Dimitrios Kechagias.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.