openmeteo-requests


Nameopenmeteo-requests JSON
Version 1.3.0 PyPI version JSON
download
home_pageNone
SummaryOpen-Meteo Python Library
upload_time2024-08-05 16:00:24
maintainerNone
docs_urlNone
authorNone
requires_python>=3.8.1
licenseNone
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Open-Meteo API Python Client

This ia an API client to get weather data from the [Open-Meteo Weather API](https://open-meteo.com) based on the Python library `requests`.

Instead of using JSON, the API client uses FlatBuffers to transfer data. Encoding data in FlatBuffers is more efficient for long time-series data. Data can be transferred to `numpy`, `pandas`, or `polars` using [Zero-Copy](https://en.wikipedia.org/wiki/Zero-copy) to analyze large amount of data quickly. The schema definition files can be found on [GitHub open-meteo/sdk](https://github.com/open-meteo/sdk).

This library is primarily designed for data-scientists to process weather data. In combination with the [Open-Meteo Historical Weather API](https://open-meteo.com/en/docs/historical-weather-api) data from 1940 onwards can be analyzed quickly.

## Basic Usage

The following example gets an hourly temperature, wind speed and precipitation forecast for Berlin. Additionally, the current temperature and relative humidity is retrieved. It is recommended to only specify the required weather variables.

```python
# pip install openmeteo-requests

import openmeteo_requests
from openmeteo_sdk.Variable import Variable

om = openmeteo_requests.Client()
params = {
    "latitude": 52.54,
    "longitude": 13.41,
    "hourly": ["temperature_2m", "precipitation", "wind_speed_10m"],
    "current": ["temperature_2m", "relative_humidity_2m"]
}

responses = om.weather_api("https://api.open-meteo.com/v1/forecast", params=params)
response = responses[0]
print(f"Coordinates {response.Latitude()}°N {response.Longitude()}°E")
print(f"Elevation {response.Elevation()} m asl")
print(f"Timezone {response.Timezone()} {response.TimezoneAbbreviation()}")
print(f"Timezone difference to GMT+0 {response.UtcOffsetSeconds()} s")

# Current values
current = response.Current()
current_variables = list(map(lambda i: current.Variables(i), range(0, current.VariablesLength())))
current_temperature_2m = next(filter(lambda x: x.Variable() == Variable.temperature and x.Altitude() == 2, current_variables))
current_relative_humidity_2m = next(filter(lambda x: x.Variable() == Variable.relative_humidity and x.Altitude() == 2, current_variables))

print(f"Current time {current.Time()}")
print(f"Current temperature_2m {current_temperature_2m.Value()}")
print(f"Current relative_humidity_2m {current_relative_humidity_2m.Value()}")
```

Note 1: You can also supply a list of latitude and longitude coordinates to get data for multiple locations. The API will return a array of results, hence in this example, we only consider the first location with `response = responses[0]`.

Note 2: Please note the function calls `()` for each attribute like `Latitude()`. Those function calls are necessary due to the FlatBuffers format to dynamically get data from an attribute without expensive parsing.

### NumPy

If you are using `NumPy` you can easily get hourly or daily data as `NumPy` array of type float.

```python
import numpy as np

hourly = response.Hourly()
hourly_time = range(hourly.Time(), hourly.TimeEnd(), hourly.Interval())
hourly_variables = list(map(lambda i: hourly.Variables(i), range(0, hourly.VariablesLength())))

hourly_temperature_2m = next(filter(lambda x: x.Variable() == Variable.temperature and x.Altitude() == 2, hourly_variables)).ValuesAsNumpy()
hourly_precipitation = next(filter(lambda x: x.Variable() == Variable.precipitation, hourly_variables)).ValuesAsNumpy()
hourly_wind_speed_10m = next(filter(lambda x: x.Variable() == Variable.wind_speed and x.Altitude() == 10, hourly_variables)).ValuesAsNumpy()
```

### Pandas

After using `NumPy` to create arrays for hourly data, you can use `Pandas` to create a DataFrame from hourly data like follows:

```python
import pandas as pd

hourly_data = {"date": pd.date_range(
	start = pd.to_datetime(hourly.Time(), unit = "s"),
	end = pd.to_datetime(hourly.TimeEnd(), unit = "s"),
	freq = pd.Timedelta(seconds = hourly.Interval()),
	inclusive = "left"
)}
hourly_data["temperature_2m"] = hourly_temperature_2m
hourly_data["precipitation"] = hourly_precipitation
hourly_data["wind_speed_10m"] = hourly_wind_speed_10m

hourly_dataframe_pd = pd.DataFrame(data = hourly_data)
print(hourly_dataframe_pd)
#                    date  temperature_2m  precipitation  wind_speed_10m
# 0   2024-06-21 00:00:00       17.437000            0.0        6.569383
# 1   2024-06-21 01:00:00       17.087000            0.0        6.151683
# 2   2024-06-21 02:00:00       16.786999            0.0        7.421590
# 3   2024-06-21 03:00:00       16.337000            0.0        5.154416
```

### Polars

Additionally, `Polars` can also be used to create a DataFrame from hourly data using the `NumPy` arrays created previously:

```python
import polars as pl
from datetime import datetime, timedelta, timezone

start = datetime.fromtimestamp(hourly.Time(), timezone.utc)
end = datetime.fromtimestamp(hourly.TimeEnd(), timezone.utc)
freq = timedelta(seconds = hourly.Interval())

hourly_dataframe_pl = pl.select(
    date = pl.datetime_range(start, end, freq, closed = "left"),
    temperature_2m = hourly_temperature_2m,
    precipitation = hourly_precipitation,
    wind_speed_10m = hourly_wind_speed_10m
)
print(hourly_dataframe_pl)
# ┌─────────────────────────┬────────────────┬───────────────┬────────────────┐
# │ date                    ┆ temperature_2m ┆ precipitation ┆ wind_speed_10m │
# │ ---                     ┆ ---            ┆ ---           ┆ ---            │
# │ datetime[μs, UTC]       ┆ f32            ┆ f32           ┆ f32            │
# ╞═════════════════════════╪════════════════╪═══════════════╪════════════════╡
# │ 2024-06-21 00:00:00 UTC ┆ 17.437         ┆ 0.0           ┆ 6.569383       │
# │ 2024-06-21 01:00:00 UTC ┆ 17.087         ┆ 0.0           ┆ 6.151683       │
# │ 2024-06-21 02:00:00 UTC ┆ 16.786999      ┆ 0.0           ┆ 7.42159        │
# │ 2024-06-21 03:00:00 UTC ┆ 16.337         ┆ 0.0           ┆ 5.154416       │
```

### Caching Data

If you are working with large amounts of data, caching data can make it easier to develop. You can pass a cached session from the library `requests-cache` to the Open-Meteo API client.

The following example stores all data indefinitely (`expire_after=-1`) in a SQLite database called `.cache.sqlite`. For more options read the [requests-cache documentation](https://pypi.org/project/requests-cache/).

Additionally, `retry-requests` to automatically retry failed API calls in case there has been any unexpected network or server error.

```python
# pip install openmeteo-requests
# pip install requests-cache retry-requests

import openmeteo_requests
import requests_cache
from retry_requests import retry

# Setup the Open-Meteo API client with a cache and retry mechanism
cache_session = requests_cache.CachedSession('.cache', expire_after=-1)
retry_session = retry(cache_session, retries=5, backoff_factor=0.2)
om = openmeteo_requests.Client(session=retry_session)

# Using the client object `om` will now cache all weather data
```

# TODO

- Document multi location/timeinterval usage
- Document FlatBuffers data structure
- Document time start/end/interval
- Document timezones behavior
- Document pressure level and upper level
- Document endpoints for air quality, etc
- Consider dedicated pandas library to convert responses quickly

# License

MIT

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "openmeteo-requests",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8.1",
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": "Patrick Zippenfenig <info@open-meteo.com>",
    "download_url": "https://files.pythonhosted.org/packages/d6/0f/41364bf4f30164cb0d7c357e6b3c099f85995d946ae31959a52605253da5/openmeteo_requests-1.3.0.tar.gz",
    "platform": null,
    "description": "# Open-Meteo API Python Client\n\nThis ia an API client to get weather data from the [Open-Meteo Weather API](https://open-meteo.com) based on the Python library `requests`.\n\nInstead of using JSON, the API client uses FlatBuffers to transfer data. Encoding data in FlatBuffers is more efficient for long time-series data. Data can be transferred to `numpy`, `pandas`, or `polars` using [Zero-Copy](https://en.wikipedia.org/wiki/Zero-copy) to analyze large amount of data quickly. The schema definition files can be found on [GitHub open-meteo/sdk](https://github.com/open-meteo/sdk).\n\nThis library is primarily designed for data-scientists to process weather data. In combination with the [Open-Meteo Historical Weather API](https://open-meteo.com/en/docs/historical-weather-api) data from 1940 onwards can be analyzed quickly.\n\n## Basic Usage\n\nThe following example gets an hourly temperature, wind speed and precipitation forecast for Berlin. Additionally, the current temperature and relative humidity is retrieved. It is recommended to only specify the required weather variables.\n\n```python\n# pip install openmeteo-requests\n\nimport openmeteo_requests\nfrom openmeteo_sdk.Variable import Variable\n\nom = openmeteo_requests.Client()\nparams = {\n    \"latitude\": 52.54,\n    \"longitude\": 13.41,\n    \"hourly\": [\"temperature_2m\", \"precipitation\", \"wind_speed_10m\"],\n    \"current\": [\"temperature_2m\", \"relative_humidity_2m\"]\n}\n\nresponses = om.weather_api(\"https://api.open-meteo.com/v1/forecast\", params=params)\nresponse = responses[0]\nprint(f\"Coordinates {response.Latitude()}\u00b0N {response.Longitude()}\u00b0E\")\nprint(f\"Elevation {response.Elevation()} m asl\")\nprint(f\"Timezone {response.Timezone()} {response.TimezoneAbbreviation()}\")\nprint(f\"Timezone difference to GMT+0 {response.UtcOffsetSeconds()} s\")\n\n# Current values\ncurrent = response.Current()\ncurrent_variables = list(map(lambda i: current.Variables(i), range(0, current.VariablesLength())))\ncurrent_temperature_2m = next(filter(lambda x: x.Variable() == Variable.temperature and x.Altitude() == 2, current_variables))\ncurrent_relative_humidity_2m = next(filter(lambda x: x.Variable() == Variable.relative_humidity and x.Altitude() == 2, current_variables))\n\nprint(f\"Current time {current.Time()}\")\nprint(f\"Current temperature_2m {current_temperature_2m.Value()}\")\nprint(f\"Current relative_humidity_2m {current_relative_humidity_2m.Value()}\")\n```\n\nNote 1: You can also supply a list of latitude and longitude coordinates to get data for multiple locations. The API will return a array of results, hence in this example, we only consider the first location with `response = responses[0]`.\n\nNote 2: Please note the function calls `()` for each attribute like `Latitude()`. Those function calls are necessary due to the FlatBuffers format to dynamically get data from an attribute without expensive parsing.\n\n### NumPy\n\nIf you are using `NumPy` you can easily get hourly or daily data as `NumPy` array of type float.\n\n```python\nimport numpy as np\n\nhourly = response.Hourly()\nhourly_time = range(hourly.Time(), hourly.TimeEnd(), hourly.Interval())\nhourly_variables = list(map(lambda i: hourly.Variables(i), range(0, hourly.VariablesLength())))\n\nhourly_temperature_2m = next(filter(lambda x: x.Variable() == Variable.temperature and x.Altitude() == 2, hourly_variables)).ValuesAsNumpy()\nhourly_precipitation = next(filter(lambda x: x.Variable() == Variable.precipitation, hourly_variables)).ValuesAsNumpy()\nhourly_wind_speed_10m = next(filter(lambda x: x.Variable() == Variable.wind_speed and x.Altitude() == 10, hourly_variables)).ValuesAsNumpy()\n```\n\n### Pandas\n\nAfter using `NumPy` to create arrays for hourly data, you can use `Pandas` to create a DataFrame from hourly data like follows:\n\n```python\nimport pandas as pd\n\nhourly_data = {\"date\": pd.date_range(\n\tstart = pd.to_datetime(hourly.Time(), unit = \"s\"),\n\tend = pd.to_datetime(hourly.TimeEnd(), unit = \"s\"),\n\tfreq = pd.Timedelta(seconds = hourly.Interval()),\n\tinclusive = \"left\"\n)}\nhourly_data[\"temperature_2m\"] = hourly_temperature_2m\nhourly_data[\"precipitation\"] = hourly_precipitation\nhourly_data[\"wind_speed_10m\"] = hourly_wind_speed_10m\n\nhourly_dataframe_pd = pd.DataFrame(data = hourly_data)\nprint(hourly_dataframe_pd)\n#                    date  temperature_2m  precipitation  wind_speed_10m\n# 0   2024-06-21 00:00:00       17.437000            0.0        6.569383\n# 1   2024-06-21 01:00:00       17.087000            0.0        6.151683\n# 2   2024-06-21 02:00:00       16.786999            0.0        7.421590\n# 3   2024-06-21 03:00:00       16.337000            0.0        5.154416\n```\n\n### Polars\n\nAdditionally, `Polars` can also be used to create a DataFrame from hourly data using the `NumPy` arrays created previously:\n\n```python\nimport polars as pl\nfrom datetime import datetime, timedelta, timezone\n\nstart = datetime.fromtimestamp(hourly.Time(), timezone.utc)\nend = datetime.fromtimestamp(hourly.TimeEnd(), timezone.utc)\nfreq = timedelta(seconds = hourly.Interval())\n\nhourly_dataframe_pl = pl.select(\n    date = pl.datetime_range(start, end, freq, closed = \"left\"),\n    temperature_2m = hourly_temperature_2m,\n    precipitation = hourly_precipitation,\n    wind_speed_10m = hourly_wind_speed_10m\n)\nprint(hourly_dataframe_pl)\n# \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n# \u2502 date                    \u2506 temperature_2m \u2506 precipitation \u2506 wind_speed_10m \u2502\n# \u2502 ---                     \u2506 ---            \u2506 ---           \u2506 ---            \u2502\n# \u2502 datetime[\u03bcs, UTC]       \u2506 f32            \u2506 f32           \u2506 f32            \u2502\n# \u255e\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u256a\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2561\n# \u2502 2024-06-21 00:00:00 UTC \u2506 17.437         \u2506 0.0           \u2506 6.569383       \u2502\n# \u2502 2024-06-21 01:00:00 UTC \u2506 17.087         \u2506 0.0           \u2506 6.151683       \u2502\n# \u2502 2024-06-21 02:00:00 UTC \u2506 16.786999      \u2506 0.0           \u2506 7.42159        \u2502\n# \u2502 2024-06-21 03:00:00 UTC \u2506 16.337         \u2506 0.0           \u2506 5.154416       \u2502\n```\n\n### Caching Data\n\nIf you are working with large amounts of data, caching data can make it easier to develop. You can pass a cached session from the library `requests-cache` to the Open-Meteo API client.\n\nThe following example stores all data indefinitely (`expire_after=-1`) in a SQLite database called `.cache.sqlite`. For more options read the [requests-cache documentation](https://pypi.org/project/requests-cache/).\n\nAdditionally, `retry-requests` to automatically retry failed API calls in case there has been any unexpected network or server error.\n\n```python\n# pip install openmeteo-requests\n# pip install requests-cache retry-requests\n\nimport openmeteo_requests\nimport requests_cache\nfrom retry_requests import retry\n\n# Setup the Open-Meteo API client with a cache and retry mechanism\ncache_session = requests_cache.CachedSession('.cache', expire_after=-1)\nretry_session = retry(cache_session, retries=5, backoff_factor=0.2)\nom = openmeteo_requests.Client(session=retry_session)\n\n# Using the client object `om` will now cache all weather data\n```\n\n# TODO\n\n- Document multi location/timeinterval usage\n- Document FlatBuffers data structure\n- Document time start/end/interval\n- Document timezones behavior\n- Document pressure level and upper level\n- Document endpoints for air quality, etc\n- Consider dedicated pandas library to convert responses quickly\n\n# License\n\nMIT\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Open-Meteo Python Library",
    "version": "1.3.0",
    "project_urls": {
        "Documentation": "https://github.com/open-meteo/python-requests/tree/main#readme",
        "Source": "https://github.com/open-meteo/python-requests",
        "Tracker": "https://github.com/open-meteo/python-requests/issues"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "133196209383687cf35055eb628e3a9207a07ac2d5faf6e70076f459435a989e",
                "md5": "45a30295c87e329fe5de1b9ddee538c8",
                "sha256": "e9b4eb9f4a3d234f573be6f83f1c179f2f2f2bbc6533a1541a3fa0a0eb1df54b"
            },
            "downloads": -1,
            "filename": "openmeteo_requests-1.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "45a30295c87e329fe5de1b9ddee538c8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8.1",
            "size": 6030,
            "upload_time": "2024-08-05T16:00:22",
            "upload_time_iso_8601": "2024-08-05T16:00:22.569923Z",
            "url": "https://files.pythonhosted.org/packages/13/31/96209383687cf35055eb628e3a9207a07ac2d5faf6e70076f459435a989e/openmeteo_requests-1.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d60f41364bf4f30164cb0d7c357e6b3c099f85995d946ae31959a52605253da5",
                "md5": "ab41ae286373143ccf2483f4f13cf9f3",
                "sha256": "6606975d1939669b69ee1ea46cc5356a03aa99f2259b7b8a2e73841b478eb640"
            },
            "downloads": -1,
            "filename": "openmeteo_requests-1.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "ab41ae286373143ccf2483f4f13cf9f3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8.1",
            "size": 58816,
            "upload_time": "2024-08-05T16:00:24",
            "upload_time_iso_8601": "2024-08-05T16:00:24.310268Z",
            "url": "https://files.pythonhosted.org/packages/d6/0f/41364bf4f30164cb0d7c357e6b3c099f85995d946ae31959a52605253da5/openmeteo_requests-1.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-05 16:00:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "open-meteo",
    "github_project": "python-requests",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "openmeteo-requests"
}
        
Elapsed time: 0.37817s