Skip to content

Instantly share code, notes, and snippets.

@j08lue
Created June 23, 2020 07:26
Show Gist options
  • Save j08lue/d1babe44e1343014d4c87a0fb97e84ba to your computer and use it in GitHub Desktop.
Save j08lue/d1babe44e1343014d4c87a0fb97e84ba to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# DMI API Tutorial\n",
"\n",
"This tutorial gives an introduction on how to use the Danish Meteorological Institute's (DMI) API to download historical weather data. The API documentation can be found [here](https://confluence.govcloud.dk/display/FDAPI).\n",
"\n",
"The tutorial uses the Python programming language and is in the format of a Jupyter Notebook. The notebook can be downloaded and run locally, allowing new users to download data immediately. \n",
"\n",
"## Part 1: Retrieving data\n",
"Part 1 of this tutorial will show how to request data and convert it to a table format. Part 2 will deal with how to request specific data and more advanced data handling.\n"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"# Import necessary libraries\n",
"import requests # library for making HTTP requests\n",
"import pandas as pd # library for data analysis\n",
"# following command allows figures to be shown inline\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In order to access the API it is necessary to create a user and obtain an api-key. This key grants permission to retrieve data and allows DMI to generate usage statistics.\n",
"\n",
"A guide to creating a user profile and getting an api-key can be found [here](https://confluence.govcloud.dk/pages/viewpage.action?pageId=26476690).\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"api_key = '' # insert your own key between the '' signs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"An easy test to see if your api-key works is to paste the api url followed by a question mark and then your api-key into your browser, e.g.: https://dmigw.govcloud.dk/metObs/v1/observation?api-key=111111xx-1x11-11xx-1111-1x1111111xx1 (in the example, a API key is used that won't work for you).\n",
"\n",
"This should return a page of data in the browser window.\n",
"<br><br>\n",
"\n",
"In the following code block, data is retrieved using the *requests.get* function. Further information on REST APIs and HTTP request methods can be found [here](https://restfulapi.net/http-methods/).\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Response [401]> https://dmigw.govcloud.dk/metObs/v1/observation?api-key=\n"
]
}
],
"source": [
"url = 'https://dmigw.govcloud.dk/metObs/v1/observation' # url for the current api version\n",
"r = requests.get(url, params={'api-key': api_key}) # Issues a HTTP GET request\n",
"print(r, r.url)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The [response status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) indicates whether the request was successful or not. A 200 code means that the retrieval was successful. \n",
"<br/><br/>\n",
"\n",
"\n",
"\n",
"\n",
"Next, we extract the JSON file from the returned request object. [JSON](https://restfulapi.net/introduction-to-json/) is a human-readable format for data exchange.\n"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "unhashable type: 'slice'",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-11-8acd3e84d660>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[0mjson\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mr\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# Extract JSON data\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# Print the first two data entries\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;31mTypeError\u001b[0m: unhashable type: 'slice'"
]
}
],
"source": [
"json = r.json() # Extract JSON data\n",
"print(json[:2]) # Print the first two data entries"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Furthermore, the JSON object can be converted to a convenient table (DataFrame) using the Pandas library."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" _id parameterId stationId \\\n",
"0 120a2e3e-41b3-11ea-969d-c2bb795cdc89 temp_soil 06019 \n",
"1 e972c3fa-41b2-11ea-893e-ae5be27c74ec precip_past1min 06019 \n",
"2 e962392c-41b2-11ea-b423-061e38c0dcb3 wind_speed 06019 \n",
"3 e96237b0-41b2-11ea-b423-061e38c0dcb3 wind_max 06019 \n",
"4 e9623620-41b2-11ea-b423-061e38c0dcb3 wind_dir 06019 \n",
"\n",
" timeCreated timeObserved value \n",
"0 1.580205e+15 1.580205e+15 5.8 \n",
"1 1.580205e+15 1.580205e+15 0.0 \n",
"2 1.580205e+15 1.580205e+15 7.1 \n",
"3 1.580205e+15 1.580205e+15 9.7 \n",
"4 1.580205e+15 1.580205e+15 95.0 \n"
]
}
],
"source": [
"df = pd.DataFrame(json) # Convert JSON object to a Pandas DataFrame\n",
"print(df.head()) # Print the first five rows of the DataFrame"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"From the above snippet of data it is possible to deduce that the timestamps are in the format of microseconds since January 1st 1970. Try copying one timestamp and convert it to reable date using [this tool](https://www.epochconverter.com/).\n",
"\n",
"<br/>\n",
"\n",
"\n",
"The timestamps strings can be converted to a datetime object using the Pandas *to_datetime* function."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 2020-01-28 09:50:00\n",
"1 2020-01-28 09:50:00\n",
"2 2020-01-28 09:50:00\n",
"3 2020-01-28 09:50:00\n",
"4 2020-01-28 09:50:00\n",
"Name: time, dtype: datetime64[ns]\n"
]
}
],
"source": [
"df['time'] = pd.to_datetime(df['timeObserved'], unit='us') # The unit 'us' corresponds to microseconds\n",
"print(df['time'].head()) # Print the first five timestamps"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br/>\n",
"Last, we will generate a list of all the parameters available."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['temp_soil' 'precip_past1min' 'wind_speed' 'wind_max' 'wind_dir'\n",
" 'temp_grass' 'temp_dry' 'temp_dew' 'sun_last10min_glob' 'radia_glob'\n",
" 'precip_past10min' 'humidity' 'precip_dur_past10min'\n",
" 'leav_hum_dur_past10min' 'pressure_at_sea' 'pressure' 'visibility'\n",
" 'visib_mean_last10min' 'cloud_height' 'cloud_cover' 'weather']\n"
]
}
],
"source": [
"parameter_ids = df['parameterId'].unique() # Generate a list of unique parameter ids\n",
"print(parameter_ids) # Print all unique parameter ids"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br/><br/>\n",
"\n",
"## Part 2: Requesting specific data\n",
"\n",
"The above example was a heavily simplied example to illustrate how the API can be accessed. For most applicatios the user wants to specify query criterias, such as:\n",
"1. Meterological stations (e.g. 04320, 06074, etc.)\n",
"2. Parameters (e.g. wind_speed, humidity, etc.)\n",
"3. Time frame (to and from time)\n",
"4. Limit (maximum number of observations)\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Response [401]> https://dmigw.govcloud.dk/metObs/v1/observation?api-key=&from=1578614400000000&to=1581000566000044&stationId=06188&limit=100000\n"
]
}
],
"source": [
"# Start and end time should be specified in microseconds since January 1st 1970 (Unix time)\n",
"end_time = pd.datetime.today() # End time is defined as the current time\n",
"start_time = pd.datetime(2020,1,10) # Start time is defined as specific date\n",
"\n",
"def datetime_to_unixtime(dt):\n",
" '''Function converting a datetime objects to a Unix microsecond string'''\n",
" return str(int(pd.to_datetime(dt).value*10**-3))\n",
"\n",
"\n",
"# Specify query parameters\n",
"params = {'api-key' : api_key,\n",
" 'from' : datetime_to_unixtime(start_time),\n",
" 'to' : datetime_to_unixtime(end_time),\n",
" 'stationId' : '06188',\n",
" #'parameterId' : 'temp_mean_past1h',\n",
" 'limit' : '100000',\n",
" }\n",
"\n",
"\n",
"r = requests.get(url, params=params) # submit GET request based on url and headers\n",
"print(r, r.url) # Print request status and url"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"N.B.: the parameterId was commented out above, which results in all the parameters being included. As of the time of writing it was only possible to request one or all parameters. The same is true for the stations. The *limit* parameter is the maximum number of observations you want to download, generally it should be set to a large value in order for it not to be limiting.\n",
"\n",
"\n",
"If the request was succesfull, the variable *r* now contains a JSON object with the requested data. Next, the JSON object is extracted and converted to a Pandas DataFrame as previously shown.\n",
"\n",
"A new collumn is created named *time*, which is the observation times in the format of Python *datetime* objects. Also, the unused columns are deleted."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" parameterId stationId value time\n",
"time \n",
"2020-01-28 09:40:00 temp_soil 06188 5.3 2020-01-28 09:40:00\n",
"2020-01-28 09:40:00 wind_speed 06188 3.0 2020-01-28 09:40:00\n",
"2020-01-28 09:40:00 wind_max 06188 5.6 2020-01-28 09:40:00\n",
"2020-01-28 09:40:00 wind_dir 06188 162.0 2020-01-28 09:40:00\n",
"2020-01-28 09:40:00 temp_grass 06188 4.6 2020-01-28 09:40:00\n"
]
}
],
"source": [
"json = r.json() # Extract JSON object\n",
"df = pd.DataFrame(json) # Convert JSON object to a DataFrame\n",
"\n",
"df['time'] = pd.to_datetime(df['timeObserved'], unit='us') # Set the DataFrame index as the observation time\n",
"\n",
"df = df.drop(['_id', 'timeCreated', 'timeObserved'], axis=1) # Delete unused columns\n",
"\n",
"df.index = df['time'] # Set the time as the index\n",
"\n",
"print(df.head()) # Print the first five rows"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Since the table includes the multile parameters from station *06188*, it is convenient to format the table such that the index is time and each column represents a unique parameter. A simple method for doing this is to set a multi-index and then unstack, as shown below.\n",
"\n",
"Lastly, the data is visualized."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Text(0.5,0,'')"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x504 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"df2 = df.set_index(['time', 'parameterId']).drop_duplicates().unstack(level=-1)['value']\n",
"\n",
"params = ['wind_speed', 'humidity', 'temp_dry'] # Chosing which parameters to plot\n",
"\n",
"# Generate plot of data\n",
"ax = df2[params].interpolate().plot(figsize=(12,7), legend=False, fontsize=12, subplots=True)\n",
"ax[0].set_ylabel('Wind speed [m/s]', size=12)\n",
"ax[1].set_ylabel('Humidity [%]', size=12)\n",
"ax[2].set_ylabel('Air temperature [$^\\circ$C]', size=12)\n",
"ax[2].set_xlabel('', size=12)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Useful links:\n",
"1. [Station numbers](https://confluence.govcloud.dk/display/FDAPI/Stations)\n",
"2. [Parameters](https://confluence.govcloud.dk/display/FDAPI/Parameters)\n",
"3. [Codes](https://confluence.govcloud.dk/display/FDAPI/Codes)\n",
"4. [FAQ](https://confluence.govcloud.dk/display/FDAPI/FAQ)\n",
"5. [Terms of use](https://confluence.govcloud.dk/display/FDAPI/Terms+of+Use)\n",
"6. [Operational status](https://confluence.govcloud.dk/display/FDAPI/Operational+Status+of+API)\n",
"7. [API uptime](http://status.govcloud.dk/)\n",
"8. [Contact & support](https://confluence.govcloud.dk/pages/viewpage.action?pageId=26476715)\n",
"9. [User creation](https://confluence.govcloud.dk/pages/viewpage.action?pageId=26476690)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"[The Norwegian Meteorological Institute's historical weather data API](https://frost.met.no/)\n",
"\n",
"[Swedish Meterological Institutes Open Data API](https://opendata.smhi.se/apidocs/metobs/)\n",
"\n",
"*Updated on 27 January 2020 by Adam R. Jensen*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
@j08lue
Copy link
Author

j08lue commented Jun 23, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment