Usage¶
To use PyMeteoFr in a project:
import pymeteofr
The first thing to do is to set a valid API key.
Setting the web service token¶
First we need to import the Fetcher
class:
from pymeteofr import Fetcher
You can instanciate a Fetcher
object without a token:
fetcher = Fetcher()
fetcher.token is None
True
The token can later be fetched using a credentials JSON file of the form:
{
"username": "john.doe",
"password": "1234"
}
This is done with the credentials_file_path
argument of the fetch_token
method:
fetcher.fetch_token(credentials_file_path='/home/john/Workspace/pymeteofr/notebooks/credentials.json')
-- GetAPIKey request --
Or by directly giving a username and password:
fetcher.fetch_token(username="john.doe", password="1234")
-- GetAPIKey request --
These username and password are the ones we got from support.inspire@meteo.fr. PyMeteoFr is using a GetAPIKey
request to fetch the token. Note that if we give a wrong username/password, we still fetch a token from the web service, which is not going to be valid.
Finally the token can be directly given as an argument when instanciating the Fetcher
object:
fetcher = Fetcher(token="__xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx__")
Selecting a product¶
Now that the token is set, we need to choose which weather-related product we are interested in. This is done using the select_product
method with appropriate arguments: dataset
, area
and accuracy
. Here is the list of available products so far:
dataset | area | accuracy | |
---|---|---|---|
0 | arpege | world | 0.500 |
1 | arpege | europe | 0.100 |
2 | arome | france | 0.025 |
3 | arome | france | 0.010 |
4 | arome | antilles | 0.025 |
5 | arome | guyane | 0.025 |
6 | arome | réunion | 0.025 |
7 | arome | nouvelle-calédonie | 0.025 |
8 | arome | polynésie | 0.025 |
Note that we do not need to enter all the arguments, but just give enough information to select a single product. In the following example, we select two products instead of one, which raises an error:
try:
fetcher.select_product(dataset="arome", area="france")
except ValueError as e:
print(e)
dataset area accuracy service_type
2 arome france 0.025 wcs
3 arome france 0.010 wcs
Several services match the criteria
In this other example, no product matches the given criteria:
try:
fetcher.select_product(dataset="arome", area="france", accuracy=0.03)
except ValueError as e:
print(e)
No service matching the criteria
Now here is a case where a single produt is selected:
fetcher.select_product(dataset="arome", area="france", accuracy=0.01)
-- GetCapabilities request --
This triggers a GetCapabilities
request which returns some information about the selected product, mainly the list of available titles (variables) associated with the product:
fetcher.list_titles()
['Brightness temperature',
'Convective available potential energy',
'Geometric height',
'High cloud cover',
'Low cloud cover',
'Medium cloud cover',
'Pressure',
'Relative humidity at specified height level above ground',
'Temperature at specified height level above ground',
'Wind speed (gust) at specified height level above ground',
'Wind speed at specified height level above ground',
'rainfall rate',
'u component of wind at specified height level above ground',
'u component of wind gust at specified height level above ground',
'v component of wind at specified height level above ground',
'v component of wind gust at specified height level above ground']
and the list of available run times (we will see more about that in the next section). Note that this list of titles depends on the chosen product.
An important point is that we only keep the titles that are available with a temporal resolution of 1 hour. Other titles are discarded.
Selecting a CoverageId¶
A CoverageId is a combination of title
and run_time
. The title
is a variable (e.g. temperature, presure) resulting from a model and a run_time
is a time stamp identifying when the model was run.
So when we select a CoverageId
we can enter the title
and run_time
as attributes to the select_coverage_id
method. Actually, the title
is mandatory but not the run_time
. If not entered, the latest available run_time
is chosen. Let us choose for example the ‘Pressure’ title
:
fetcher.select_coverage_id(title='Pressure')
fetcher.CoverageId
'PRESSURE__GROUND_OR_WATER_SURFACE___2020-02-27T09.00.00Z'
The run_time
information as well as the list of titles
is re-built at each GetCapabilities
request, for example when we select a product. However we can simply refresh this information with the update
method:
fetcher.update()
-- GetCapabilities request --
This can be useful for example if several hours have passed since a product was chosen. Now what if we want to look at the list of available run times? This is done using the list_available_run_times
method:
run_times = fetcher.list_available_run_times('Relative humidity at specified height level above ground')
print(run_times)
['2020-02-23T00', '2020-02-23T03', '2020-02-23T06', '2020-02-23T09', '2020-02-23T12', '2020-02-23T15', '2020-02-23T18', '2020-02-23T21', '2020-02-24T00', '2020-02-24T03', '2020-02-24T06', '2020-02-24T09', '2020-02-24T12', '2020-02-24T15', '2020-02-24T18', '2020-02-24T21', '2020-02-25T00', '2020-02-25T03', '2020-02-25T06', '2020-02-25T09', '2020-02-25T12', '2020-02-25T15', '2020-02-25T18', '2020-02-25T21', '2020-02-26T00', '2020-02-26T03', '2020-02-26T06', '2020-02-26T09', '2020-02-26T12', '2020-02-26T15', '2020-02-26T18', '2020-02-26T21', '2020-02-27T00', '2020-02-27T03', '2020-02-27T06', '2020-02-27T09']
We can now choose an earlier run time when selecting a CoverageId:
fetcher.select_coverage_id(title='Relative humidity at specified height level above ground', run_time=run_times[1])
fetcher.CoverageId
'RELATIVE_HUMIDITY__SPECIFIC_HEIGHT_LEVEL_ABOVE_GROUND___2020-02-23T03.00.00Z'
The Fetcher
object also has a run_time
attribute:
fetcher.run_time
'2020-02-23T03.00.00Z'
Describing a CoverageId¶
Now that we selected a CoverageId, which corresponds to a run of a model, we need to know what’s inside in terms of spatial and temporal coverage. This is why we have a describe
method, which uses a DescribeCoverage
request to fetch the maximum bounding box, and the available time steps of the simulation results.
fetcher.describe()
-- DescribeCoverage request --
We can then have a list of the available time steps at the time of the request with the dts
attribute:
fetcher.dts
DatetimeIndex(['2020-03-13 06:00:00', '2020-03-13 07:00:00',
'2020-03-13 08:00:00', '2020-03-13 09:00:00',
'2020-03-13 10:00:00', '2020-03-13 11:00:00',
'2020-03-13 12:00:00', '2020-03-13 13:00:00',
'2020-03-13 14:00:00', '2020-03-13 15:00:00',
'2020-03-13 16:00:00', '2020-03-13 17:00:00',
'2020-03-13 18:00:00', '2020-03-13 19:00:00',
'2020-03-13 20:00:00', '2020-03-13 21:00:00',
'2020-03-13 22:00:00', '2020-03-13 23:00:00',
'2020-03-14 00:00:00', '2020-03-14 01:00:00',
'2020-03-14 02:00:00', '2020-03-14 03:00:00',
'2020-03-14 04:00:00', '2020-03-14 05:00:00',
'2020-03-14 06:00:00', '2020-03-14 07:00:00',
'2020-03-14 08:00:00', '2020-03-14 09:00:00',
'2020-03-14 10:00:00', '2020-03-14 11:00:00',
'2020-03-14 12:00:00', '2020-03-14 13:00:00',
'2020-03-14 14:00:00', '2020-03-14 15:00:00',
'2020-03-14 16:00:00', '2020-03-14 17:00:00',
'2020-03-14 18:00:00', '2020-03-14 19:00:00',
'2020-03-14 20:00:00', '2020-03-14 21:00:00',
'2020-03-14 22:00:00', '2020-03-14 23:00:00',
'2020-03-15 00:00:00'],
dtype='datetime64[ns]', freq='H')
While the spatial coverage is given by the max_bbox
attribute:
fetcher.max_bbox
(-12.0, 37.5, 16.0, 55.4)
This is a bounding box expressed in WGS84 (EPSG:4326) CRS. However the computation uses a different CRS, which may create some empty zones within the WGS84 bounding box:
Setting the horizon of interest¶
When the run time is fairly new, all the time steps are not available yet: they are progressively being pushed to the web service. So there is some chance that the latest run time is not complete. This is why we created the check_run_time
method. The argument is the horizon of the forecasts, expressed in hours, that you want. Suppose that you are interested in the next 24 hours, starting from now:
fetcher.check_run_time(horizon=24)
-- DescribeCoverage request --
Switched to previous (Python index: -2) run time
-- DescribeCoverage request --
What check_run_time
does, is looping through the available run times from latest to oldest, until the time steps corresponding to the next 24 hours are found, and then setting this run time/CoverageId. Also it creates a list of the time steps of interest:
fetcher.check_run_time(4)
-- DescribeCoverage request --
fetcher.requested_dts
['2020-03-13T17:00:00Z',
'2020-03-13T18:00:00Z',
'2020-03-13T19:00:00Z',
'2020-03-13T20:00:00Z']
from datetime import datetime
datetime.now().isoformat()
'2020-03-13T17:02:16.522364'
These datetimes always are in the future. These are the time steps that we are going to fetch with the create_3D_array
method.