Package: pymeteosource
pymeteosource - Weather API libraryMeteosource weather APIprovides accurate global weather data - get real-time, forecast, and historical hyperlocal data.Meteosource weather forecasts are based on cutting-edge machine-learning models. The algorithms learn from historical data and forecasts from manydifferent models, compare their data from different places and meteorological situations and create a single output to provide accurate hyperlocal weather forecasts anywhere in the world. Receive minute-by-minute rain forecast, detailed hour-by-hour weather forecast out to 7 days, and much more!Using this python wrapper library, you can easily implement Meteosource JSON data into your app or service.InstallationThe basic functionality of this library only needsrequestsandpytzmodules. To install it with the minimal requirements, use:pip3installpymeteosourceThe library has also optional feature of exporting the data topandasDataFrame. To use it, you will also needpandaspackage. You can either installpandasmanually, or use:pip3installpymeteosource[pandas]Get startedTo use this library, you need to obtain your Meteosource API key. You cansign upor get the API key of existing account inyour dashboard.TestsThe unit tests are written usingpytest. As thepandasexporting feature is also tested, you should havepandaslibrary installed. You can install both of them using:pip3installpytest
pip3installpandasThe tests only make 2 actual requests to live API, most of the tests use mocked API response. You need to provide your actual API key using environment variable. To run the tests, use:# Change this to your actual API keyexportMETEOSOURCE_API_KEY='abcdefghijklmnopqrstuvwxyz0123456789ABCD'pytesttestsLibrary usageInitializationTo initialize theMeteosourceobject, you need your API key and the name of your subscription plan (tier). Basic example of initialization is shown below:fromdatetimeimportdatetime,timedeltafrompymeteosource.apiimportMeteosourcefrompymeteosource.typesimporttiers# Change this to your actual API keyYOUR_API_KEY='abcdefghijklmnopqrstuvwxyz0123456789ABCD'# Change this to your actual tierYOUR_TIER=tiers.FLEXI# Initialize the main Meteosource objectmeteosource=Meteosource(YOUR_API_KEY,YOUR_TIER)Get the weather dataUsingpymeteosource, you can get weather forecasts or archive weather data (if you have a paid subscription).ForecastTo get the weather data for given place, useget_point_forecast()method of theMeteosourceobject. You have to specify either the coordinates of the place (lat+lon) or theplace_id. Detailed description of the parameters can be found in theAPI documentation.Note that the default timezone is alwaysUTC, as opposed to the API itself (which defaults to the point's local timezone). This is because the library always queries the API for theUTCtimezone to avoid ambiguous datetimes problems. If you specify a different timezone, the library still requests the API forUTC, and then converts the datetimes to desired timezone.Note that all time strings from the API response are converted to timezone-awaredatetimeobjects.frompymeteosource.typesimportsections,langs,units# Get the forecast for given pointforecast=meteosource.get_point_forecast(lat=37.7775,# Latitude of the pointlon=-122.416389,# Longitude of the pointplace_id=None,# You can specify place_id instead of lat+lonsections=[sections.CURRENT,sections.HOURLY],# Defaults to '("current", "hourly")'tz='US/Pacific',# Defaults to 'UTC', regardless of the point locationlang=langs.ENGLISH,# Defaults to 'en'units=units.US# Defaults to 'auto')Historical weatherUsers with paid subscription to Meteosource can retrieve historical weather, daily summaries and long-term statistics fromtime_machineendpoint, usingget_time_machine()method:# Get the historical weathertime_machine=meteosource.get_time_machine(date='2019-12-25',# You can also pass list/tuple/set of dates, which can be 'str' or 'datetime' objectsdate_from=None,# You can specify the range for dates you need, instead of listdate_to=None,# You can specify the range for dates you need, instead of listplace_id='london',# ID of the place you want the historical weather forlat=None,# You can specify lat instead of place_idlon=None,# You can specify lon instead of place_idtz='UTC',# Defaults to 'UTC', regardless of the point locationunits=units.US# Defaults to 'auto')Note, that the historical weather data and long-term statistics are always retrieved for full UTC days. If you specify a different timezone, the datetimes get converted, but they will cover the full UTC, not the local day. If you specify adatetimeto any of the date parameters, the hours, minutes, seconds and microseconds get ignored. So if you requestdate='2021-12-25T23:59:59', you get data for full UTC day2021-12-25.If you passlist/tuple/setof dates todateparameter, they days will be inserted into the inner structures in the order they are being iterated over. This affects time indexing by integer (see below). An API request is made for each day, even when you specify a date range.Working with the weather dataAll of the pymeteosource's data objects have overloaded__repr__()methods, so you canprintthe objects them to get useful information about them:print(forecast)# <Forecast for lat: 37.7775, lon: -122.416389>print(time_machine)# <TimeMachine for lat: 51.50853, lon: -0.12574>Attribute accessThe library loads the JSON response into its internal structures. You can access the attributes using the dot operator (.), or the index operator ([]):# You can access all of the attributes with dot operator:forecast.lat# 37.7775# ... or with index operator:forecast['lon']# -122.416389# There is also information about the elevation of the point and the timezonetime_machine.elevation# 82time_machine.timezone# 'UTC'Weather data sectionsThere are 5 weather forecast sections (current,minutely,hourly,dailyandalerts) as attributes in theForecastobject.Thecurrentdata contains data for many variables for a single point in time (it is represented bySingleTimeDataobject):# <Instance of SingleTimeData (current) with 17 member variables (cloud_cover,#  dew_point, feels_like, humidity, icon, icon_num, irradiance, ozone,#  precipitation, pressure, summary, temperature, uv_index, visibility,#  wind, wind_chill)>print(forecast.current)Theminutely,hourlyanddailysections contain forecasts for more points in time (represented byMultipleTimesData). The sections that were not requested are empty:print(forecast.minutely)# <Empty instance of MultipleTimesData>print(forecast.daily)# <Empty instance of MultipleTimesData>The sections that were requested can also beprinted, to view number of available timesteps and their range (inclusive):# <Instance of MultipleTimesData (hourly) with 164 timesteps#  from 2021-09-08T22:00:00 to 2021-09-15T17:00:00>print(forecast.hourly)Thealertssection contain meteorological alerts and warnings, if there are any issued for the location. Thealertsobject is an instance ofAlertsDataclass. You can print the object or iterate over it:print(forecast.alerts)# <Instance of AlertsData containing 4 alerts>foralertinalerts:# <Instance of SingleTimeData (alert) with 8 member variables#  (certainty, description, event, expires, headline, onset, sender, severity)>print(alert)You can also get list of all active alerts for given time. If you usestror tz-naivedatetimein this function, it will suppose that it is in the same timezone as requested for the forecast.# If you pass no parameter, it checks for current timeforecast.alerts.get_active_alerts()# returns list of SingleTimeData instances# You can use either string...forecast.alerts.get_active_alerts('2022-03-08T22:00:00')# ... or datetime (both tz-aware and naive)forecast.alerts.get_active_alerts(datetime(2022,3,8,23,0,0))There are sectionsdata,dailyandstatisticsfor historical weather as attributes in theTimeMachineobject, both represented byMultipleTimesData.print(time_machine.data)# <Instance of MultipleTimesData (time_machine) with 24 timesteps from 2019-12-25T00:00:00 to 2019-12-25T23:00:00>print(time_machine.statistics)# <Instance of MultipleTimesData (statistics) with 1 timesteps from 2019-12-25 to 2019-12-25>print(time_machine.daily)# <Instance of MultipleTimesData (daily) with 1 timesteps from 2019-12-25 to 2019-12-25>Time indexingAs mentioned above, theminutely,hourly,dailysections ofForecastand thedatasection ofTimeMachinecontain data for more timesteps. To get the data for a single time, you have several options.1. Indexing with integerYou can simply index an instance ofMultipleTimesDatawithint, as the offset from the current time:forecast.hourly[0]time_machine.data[0]2. Indexing with stringTo get the exact time, you can usestrinYYYY-MM-DDTHH:00:00format. The datetime string is assumed to be in the same timezone as the data.# Get a date in near future for which there are data in the current API responsecurrent_date=(datetime.now()+timedelta(hours=48)).strftime("%Y-%m-%dT%H:00:00")forecast.hourly[current_date]# Get historical weathertime_machine.data['2019-12-25T03:00:00']3. Indexing withdatetimeYou can also usedatetimeas an index, both timezone naive and aware. If the object is naive, it is assumed to be in the same timezone as the data. If it is aware, it is automatically converted to the timezone of the data.# Get a date in near future for which there are data in the current API responsecurrent_dt=datetime.strptime(current_date,"%Y-%m-%dT%H:00:00")# Index with naive datetimeforecast.hourly[current_dt]# Index with aware datetimeimportpytzforecast.hourly[pytz.utc.localize(current_dt)].temperature# Get historical weathertime_machine.data[datetime(2019,12,25,3)]Variable accessTo get the list of available variables, useget_membersmethod:forecast.current.get_members()# ['cloud_cover', 'dew_point', ..., 'wind_chill']time_machine.data[0].get_members()# ['cape', 'cloud_cover', ..., 'wind']To access the variable, you can use the dot operator (.), or the index operator ([]):forecast.current.temperatureforecast.hourly[0]['temperature']time_machine.data[0]['weather']# cloudySome variables are grouped into logical groups, just like in the API response. You can access the actual data with chained dot or index operators:forecast.current.wind.get_members()# ['angle', 'dir', 'gusts', 'speed']forecast.current.wind.speedtime_machine.data[0]['wind'].dir# WNWExport to pandasIf you havepandaspackage installed, you can export any of the sections topandasDataFrame. If you export the current data, you get aDataFramewith a single row (as there is only 1 timestep). If you export any other section, you get a row for each timestep.The nested sections (for examplewind.angle) are flattened, and the column names are created by concatenating them with_. So for example, instead ofwind.angle, you get column namedwind_angle.Theday(in the daily data) ordate(in minutely and hourly data) is used aspandasDateTimeIndex.df=forecast.hourly.to_pandas()print(df)For historical weather data, you can also call the method on theTimeMachineobject directly, so all following calls are valid:time_machine.data.to_pandas()time_machine.daily.to_pandas()time_machine.statistics.to_pandas()time_machine.to_pandas()You can also merge the daily statistics and the hourly historical data into singlepandasDataFrame. In this case, the daily statistics are duplicated into all hours of each day:time_machine.to_pandas(include_statistics=True)Contact usYou can contact ushere.