Package: openmeteo-sdk
Open-Meteo SDK Schema FilesThe Open-Meteo weather API uses FlatBuffers to encode API responses efficiently. The compiled schema files for various programming languages can be found in this repository.The biggest advantage of FlatBuffers is that large floating point arrays can be encoded directly instead of expensive transformation to JSON ASCII. Especially for historical weather data processing is significantly faster. But also for displaying a regular weather forecast on low-power devices, binary data encoding saves energy.The FlatBuffers schema definition can be found in the./flatbuffersdirectory. Only non-breaking changes are accepted. Binary compatibility is ensured. Every change will be announced in new release following semantic versioning.The compiled schema files do not contain any code to perform HTTP calls. They are intent to be used by developers to build client libraries.More information on how to use the compiled schema files can be found in the directories for each programming languageSwiftvia Swift Package ManagerPythonvia PIPTypeScript / JavaScriptvia NPMJavavia Gradle PluginNot all programming languages are supported yet. It is a time-intensive process to validate all languages. Please open a issue ticket to ask for an additional language and/or package distribution system.UsageOpen-Meteo offers various APIs. Each API endpoint is using different FlatBuffers schemas to encode its API response. This enables strict typing. E.g. Weather data APIs offer offers different variables while the Geocoding API returns a different structure. Per default, the Open-Meteo API returns JSON, but specifying&format=flatbuffersin the URL return FlatBuffers encoded data.Depending on the programming language, you can use a HTTP client to fetch all data and decode the response according to each API endpoint. The following API response schema files are available:Weather, Marine, Ensemble, Flood and Climate API: Used for forecast and historical dataElevation API: Not yet availableGeocoding API: Not yet availableStructureEach response contains data for one location and one weather model. If multiple locations are requested, multiple ApiResponses will be returned as an array usingsize-prefixedencoding (see below).WeatherApiResponseThe mainWeatherApiResponsestructure containslatitude&longitudefloat: Coordinate of the weather model grid-cellelevationfloat: Terrain elevation of the requested coordinatesgeneration_time_millisecondsfloatlocation_idint64: Identifier of a locationmodelModel: Name of weather model as an enumerationutc_offset_secondsint32: Timezone offset from GMT time in seconds. e.g.3600timezonestring: Timezone name likeEurope/Berlintimezone_abbreviationstring: Abbreviation likeCETcurrentVariablesWithTime: All variables requested with&current=dailyVariablesWithTime: All variables requested with&daily=hourlyVariablesWithTime: All variables requested with&hourly=minutely_15VariablesWithTime: All variables requested with&minutely_15=six_hourlyVariablesWithTime: All variables requested with&six_hourly=VariablesWithTimeAllhourlyordailyweather variables are grouped into the classVariablesWithTime. It contains the start and end time as well as the interval.Attributes:startint64: Unix timestamp of the first value in GMTendint64: The last timestamp that is not included in the time-interval. Therefore one step after the last included timestep.intervalint32:  The number of seconds for each step. For hourly data this is3600 secondsand for daily data86400 seconds.variables[VariableWithValues]: An array of weather variablesTimestamps always use unixtime in seconds. Time is always in GMT! If you want to display local time again, you can use the attributeutc_offset_secondsfrom the response structureVariableWithValuesEach weather variable is accompanied by meta data like the name of the weather variable or unit.Attributes:variableVariable: An enumeration of the weather variable. E.g.temperatureunitUnit: Which unit is used for the result. E.g.celsiusvaluefloat: Forcurrentvalues, data is stored in this fieldvalues[float]: Any other time-series data is stored as a floating point array herevalues_int64[int64]: The variablessunriseandsunsetuse this field to store data as unix timestampaltitudeint16: The altitude of the given variable. E.g2for temperature on 2 meters or10for wind speed on 10 metersaggregationAggregation: The kind of aggregation for daily variables likeminimum,meanormaximumpressure_levelint16: If a weather variable in the upper atmosphere is requested, this field contains the pressure level in hectopascal. E.g.850for 850 hPa.depthint16: For soil variables this defined the upper limit. E.g.7insoil_moisture_7_to_28depth_toint16: The lower limit. E.g.28insoil_moisture_7_to_28ensemble_memberint16: For ensemble data, the member of each ensemble is set here.0is mostly the control run.ModelTheModelenumeration contains all available models likeicon_globalorbest_match.Depending on the programming language you will have to decode the model to a useable string. E.g. for Pythonfromopenmeteo_sdkimportModeldefmodel_to_name(code):"""convert Model to name"""forname,valueinModel.Model.__dict__.items():ifvalue==code:returnnamereturnNoneprint(response.Model())# 1print(model_to_name(result.Model()))# "best_match"VariableTheVariableenumeration contains all available variables liketemperatureorwind_speed. Please note that the altitude is not included in the variable name.temperature_2mis encoded asvariable=temperatureandaltitude=2.UnitTheUnitenumeration contains all available units likecelsiusormetre_per_second.AggregationTheAggregationenumeration contains all aggregations for daily variables likeminimumormaximum.Selecting a single variableMultiple weather variables are encoded as a list. If you want to access a single variable, you will have to loop over the array and filter by variable name and altitude. Here is an example to gettemperature_2mandprecipitation.fromopenmeteo_sdk.VariableimportVariableresponse=...hourly=response.Hourly()hourly_variables=list(map(lambdai:hourly.Variables(i),range(0,hourly.VariablesLength())))temperature_2m=next(filter(lambdax:x.Variable()==Variable.temperatureandx.Altitude()==2,hourly_variables))precipitation=next(filter(lambdax:x.Variable()==Variable.precipitation,hourly_variables))print(temperature_2m.ValuesAsNumpy())print(precipitation.ValuesAsNumpy())Depending on the variable, you only have to filter by the variable name. Filtering byaltitudeis relevant if you select wind speed on multiple heights e.g.wind_speed_10mandwind_speed_80m.If you select different daily aggregations, make sure to also check for the correct aggregation. Example:fromopenmeteo_sdk.VariableimportVariablefromopenmeteo_sdk.AggregationimportAggregationdaily=response.Daily()daily_variables=list(map(lambdai:daily.Variables(i),range(0,daily.VariablesLength())))temperature_2m_max=next(filter(lambdax:x.Variable()==Variable.temperatureandx.Altitude()==2andx.Aggregation()==Aggregation.maximum,daily_variables))temperature_2m_min=next(filter(lambdax:x.Variable()==Variable.temperatureandx.Altitude()==2andx.Aggregation()==Aggregation.minimum,daily_variables))print(temperature_2m_max.ValuesAsNumpy())print(temperature_2m_min.ValuesAsNumpy())The order of requested variables will be preserved. E.g.&current=temperature_2m,wind_speed_10m,weather_codewill stay exactly in this order. Therefore you could just use indices. Note:currentonly returns one variable encoded into the fieldvalue.current=response.Current()timestamp=current.start()temperature_2m=current.Variables(0).value()wind_speed_10m=current.Variables(1).value()weather_code=current.Variables(2).value()Encoding with Size Prefixed FlatBuffersData can be requested for multiple locations and multiple weather models in one API calls. E.g.&latitude=47.1,49.7&longitude=8.6,9.4. To return multiple locations at once, multiple FlatBuffers messages are send.To distinguish multiple messages, each message is prefixed by its length as a 32-bit integer (little endian). This is known assize-prefixedFlatBuffer messages. Over the wire the messages look like this:Length: 4 byte, int32 (little endian) = 1284 byteMessage: 1284 byteLength: 4 byte, int32 (little endian) = 1306 byteMessage: 1306 byte...While decoding the response you can loop over data and process one after another. As a reference here is thePython code.Up to 1000 locations can be requested at once. The Open-Meteo API prefetches data for all locations, but will process one location after another and "stream" the response. Therefore is it possible to decode the first message, while the next messages are still being processed on the server. This can be useful to ingest large amount of data, but is a rather complex approach. For simplicity, waiting for the entire response and then start processing data works well too.Convert API Response to JSONIf you would like to examine the data returned by the Open-Meteo API in binary FlatBuffers format, you can use the FlatBuffers schema compilerflatc. This can help to understand how the API response is structured.First, you will have to install the FlatBuffers compile. Mac:brew install flatbuffers. Ubuntusudo apt install flatbuffers-compiler.Getweather_api.fbsfrom this repository.# Make sure the URL contains `&format=flatbuffers`wget-Odata.binhttps://api.open-meteo.com/v1/forecast\?latitude\=52.52\&longitude\=13.41\&daily\=weather_code,temperature_2m_max,temperature_2m_min\&timezone\=auto\&format\=flatbuffers

flatc--json--size-prefixed--raw-binaryweather_api.fbs--data.bin
catdata.json{latitude:52.52,longitude:13.419998,elevation:38.0,generation_time_milliseconds:0.247002,model:"best_match",utc_offset_seconds:3600,timezone:"Europe/Berlin",timezone_abbreviation:"CET",daily:{time:1698620400,time_end:1699225200,interval:86400,variables:[{variable:"weather_code",unit:"wmo_code",values:[3.0,80.0,3.0,61.0,61.0,61.0,61.0]},{variable:"temperature",unit:"celsius",values:[14.8455,12.7955,14.0455,13.938999,12.389,12.3695,14.4695],altitude:2,aggregation:"maximum"},{variable:"temperature",unit:"celsius",values:[11.1455,8.1455,7.4955,8.488999,8.188999,6.389,9.0195],altitude:2,aggregation:"minimum"}]}}Note: The values formodel,variable,unitandaggregationare encoded into enumerations which use integers instead of strings. Onlytimezoneandtimezone_abbreviationare actual strings that are encoded in the binary API response.LicenseMIT