open-meteo 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1c6c6b4ccb93360c8c3f27479f8bc01cc5cc37a7d14f2ff6942d745e3bd243a8
4
- data.tar.gz: e10768db1766c5c7a48f8c68e6b15d2e367aefa0dc1bc3fc9a3fa263ce7cca93
3
+ metadata.gz: f33676766f8b3c6bb0e373337e836eafe3cc8d7d4d2f0ee17a5cd397768592e8
4
+ data.tar.gz: 928328683daf2420bd23852cff7aa08ca71ffc637050dd2df5a77aa072729ac0
5
5
  SHA512:
6
- metadata.gz: 966bbb364b37dc3e4fe846516f862216c172e242949b5b64d45afded542336f704904e6725b7fcb867de0481a23988789c4392f7480c62dc24491d62b65740fa
7
- data.tar.gz: 694c506e84309461346622763b562f34cd9f11d6fb34d7ab81b25faa7a808298cc07ecb58e02765ae9abd8a80b4122df388f9a57d657b7b63131e7cda07008ee
6
+ metadata.gz: 85d8aef77f27747a258b26e54eece4a092843bf7bb5f5b852c4d85246e56ae94bfeb902219edf78b3501fe266e741ed6d4e8a4bb8928c39ae00be8a56bfa9479
7
+ data.tar.gz: bcd21c77a39fdc3bd8f30b2ef8f003ec52d68725b5f664852086f995ad620ad2ae804eb5c6605874e29a7c5de986aacd54b498c35d4d0be90a9cd3c45790ab7d
@@ -3,9 +3,10 @@ module OpenMeteo
3
3
  ##
4
4
  # The configuration for the OpenMeteo::Client.
5
5
  class Config
6
- attr_reader :host, :logger
6
+ attr_reader :api_key, :host, :logger
7
7
 
8
- def initialize(host: nil, logger: nil)
8
+ def initialize(api_key: nil, host: nil, logger: nil)
9
+ @api_key = api_key || OpenMeteo.configuration.api_key
9
10
  @host = host || OpenMeteo.configuration.host
10
11
  @logger = logger || OpenMeteo.configuration.logger
11
12
  end
@@ -3,7 +3,7 @@ module OpenMeteo
3
3
  ##
4
4
  # The class that constructs the URLs for given endpoints.
5
5
  class UrlBuilder
6
- API_PATHS = { forecast: "v1/forecast" }.freeze
6
+ API_PATHS = { forecast: "v1/forecast", forecast_dwd_icon: "v1/dwd-icon" }.freeze
7
7
 
8
8
  attr_reader :api_config
9
9
 
@@ -1,4 +1,5 @@
1
1
  require "faraday"
2
+ require "faraday/retry"
2
3
 
3
4
  require_relative "client/config"
4
5
  require_relative "client/url_builder"
@@ -12,24 +13,23 @@ module OpenMeteo
12
13
  class Timeout < StandardError
13
14
  end
14
15
 
15
- attr_reader :api_config
16
+ # See https://github.com/lostisland/faraday-retry/tree/main#usage
17
+ RETRY_OPTIONS = { max: 3, interval: 0.05, interval_randomness: 0.5, backoff_factor: 3 }.freeze
16
18
 
17
- def initialize(
18
- api_config: OpenMeteo::Client::Config.new,
19
- url_builder: OpenMeteo::Client::UrlBuilder.new,
20
- agent: Faraday.new
21
- )
19
+ attr_reader :api_config, :agent
20
+
21
+ def initialize(api_config: OpenMeteo::Client::Config.new, url_builder: nil, agent: nil)
22
22
  @api_config = api_config
23
- @url_builder = url_builder
24
- @agent = agent
23
+ @url_builder = url_builder || UrlBuilder.new(api_config:)
24
+ @agent = agent || Faraday.new { |f| f.request :retry, RETRY_OPTIONS }
25
25
  end
26
26
 
27
27
  def get(endpoint_name, *endpoint_args, **get_params)
28
28
  endpoint = url_builder.build_url(endpoint_name, *endpoint_args)
29
29
 
30
- agent.get do |req|
31
- req.params = get_params
32
- req.url(endpoint)
30
+ agent.get do |request|
31
+ request.params = get_params.merge({ apikey: api_config.api_key }.compact)
32
+ request.url(endpoint)
33
33
  end
34
34
  rescue Faraday::ConnectionFailed => e
35
35
  raise ConnectionFailed, "Could not connect to OpenMeteo API: #{e.message}"
@@ -39,6 +39,6 @@ module OpenMeteo
39
39
 
40
40
  private
41
41
 
42
- attr_reader :agent, :url_builder
42
+ attr_reader :url_builder
43
43
  end
44
44
  end
@@ -27,5 +27,6 @@ module OpenMeteo
27
27
 
28
28
  add_setting :logger, -> { Logger.new($stdout) }
29
29
  add_setting :host, "api.open-meteo.com"
30
+ add_setting :api_key, -> { ENV.fetch("OPEN_METEO_API_KEY", nil) }
30
31
  end
31
32
  end
@@ -0,0 +1,35 @@
1
+ module OpenMeteo
2
+ module Entities
3
+ class Forecast
4
+ ##
5
+ # A forecast Entity for 15 minute data returned by OpenMeteo
6
+ class Minutely15
7
+ attr_reader :items, :units, :raw_json_hourly, :raw_json_hourly_units
8
+
9
+ def initialize(json_minutely_15, json_minutely_15_units)
10
+ @items = initialize_items(json_minutely_15)
11
+ @units =
12
+ json_minutely_15_units &&
13
+ OpenMeteo::Entities::Forecast::Units.new(json_minutely_15_units)
14
+
15
+ @raw_json_minutely_15 = json_minutely_15
16
+ @raw_json_minutely_15_units = json_minutely_15_units
17
+ end
18
+
19
+ private
20
+
21
+ def initialize_items(json_minutely_15)
22
+ json_minutely_15["time"]
23
+ .map do |element|
24
+ json_minutely_15
25
+ .keys
26
+ .each_with_object({}) do |attr, json_item|
27
+ json_item[attr] = json_minutely_15[attr][json_minutely_15["time"].index(element)]
28
+ end
29
+ end
30
+ .map { |json_item| OpenMeteo::Entities::Forecast::Item.new(json_item) }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,4 +1,5 @@
1
1
  require_relative "forecast/current"
2
+ require_relative "forecast/minutely_15"
2
3
  require_relative "forecast/hourly"
3
4
  require_relative "forecast/daily"
4
5
  require_relative "forecast/units"
@@ -9,29 +10,35 @@ module OpenMeteo
9
10
  #
10
11
  # A forecast Entity with data returned by OpenMeteo
11
12
  class Forecast
12
- attr_reader :attributes, :current, :hourly, :daily, :raw_json
13
+ attr_reader :attributes, :current, :minutely_15, :hourly, :daily, :raw_json
13
14
 
14
15
  def initialize(json_body)
15
16
  @raw_json = json_body
16
17
 
17
- @current =
18
- json_body["current"] &&
19
- OpenMeteo::Entities::Forecast::Current.new(
20
- json_body["current"],
21
- json_body["current_units"],
22
- )
23
- @hourly =
24
- json_body["hourly"] &&
25
- OpenMeteo::Entities::Forecast::Hourly.new(
26
- json_body["hourly"],
27
- json_body["hourly_units"],
28
- )
29
- @daily =
30
- json_body["daily"] &&
31
- OpenMeteo::Entities::Forecast::Daily.new(json_body["daily"], json_body["daily_units"])
18
+ init_data_for(OpenMeteo::Entities::Forecast::Current)
19
+ init_data_for(OpenMeteo::Entities::Forecast::Minutely15)
20
+ init_data_for(OpenMeteo::Entities::Forecast::Hourly)
21
+ init_data_for(OpenMeteo::Entities::Forecast::Daily)
32
22
 
33
23
  @attributes = json_body.keys
34
24
  end
25
+
26
+ private
27
+
28
+ def init_data_for(klass)
29
+ name = name_for_klass(klass)
30
+
31
+ return if raw_json[name.to_s].nil?
32
+
33
+ instance_variable_set("@#{name}", klass.new(raw_json[name.to_s], raw_json["#{name}_units"]))
34
+ end
35
+
36
+ def name_for_klass(klass)
37
+ # Extract that last part of the class name, e.g. "Minutely15"
38
+ # from "OpenMeteo::Entities::Forecast::Minutely15"
39
+ # but as snake_case version e.g. "minutely_15"
40
+ klass.to_s.split("::").last.downcase.gsub(/(\d+)/, '_\1').to_sym
41
+ end
35
42
  end
36
43
  end
37
44
  end
@@ -9,6 +9,10 @@ module OpenMeteo
9
9
  :current,
10
10
  OpenMeteo::Types::Strict::Array.of(OpenMeteo::Types::Strict::Symbol).default([].freeze),
11
11
  )
12
+ attribute(
13
+ :minutely_15,
14
+ OpenMeteo::Types::Strict::Array.of(OpenMeteo::Types::Strict::Symbol).default([].freeze),
15
+ )
12
16
  attribute(
13
17
  :hourly,
14
18
  OpenMeteo::Types::Strict::Array.of(OpenMeteo::Types::Strict::Symbol).default([].freeze),
@@ -17,13 +21,17 @@ module OpenMeteo
17
21
  :daily,
18
22
  OpenMeteo::Types::Strict::Array.of(OpenMeteo::Types::Strict::Symbol).default([].freeze),
19
23
  )
24
+ attribute(
25
+ :models,
26
+ OpenMeteo::Types::Strict::Array.of(OpenMeteo::Types::Strict::Symbol).default([].freeze),
27
+ )
20
28
 
21
29
  def to_get_params
22
30
  get_params = {}
23
31
 
24
- get_params[:current] = current.join(",") if current != []
25
- get_params[:hourly] = hourly.join(",") if hourly != []
26
- get_params[:daily] = daily.join(",") if daily != []
32
+ %i[current minutely_15 hourly daily models].each do |key|
33
+ get_params[key] = send(key).join(",") if send(key) != []
34
+ end
27
35
 
28
36
  get_params
29
37
  end
@@ -3,7 +3,7 @@ require_relative "forecast/variables"
3
3
 
4
4
  module OpenMeteo
5
5
  ##
6
- # Perform a forecase request to the OpenMeteo API.
6
+ # Perform a forecast request to the OpenMeteo API.
7
7
  #
8
8
  # See https://open-meteo.com/en/docs
9
9
  class Forecast
@@ -36,6 +36,10 @@ module OpenMeteo
36
36
  # See https://open-meteo.com/en/docs
37
37
  endpoint: :forecast,
38
38
  },
39
+ dwd_icon: {
40
+ # See https://open-meteo.com/en/docs/dwd-api
41
+ endpoint: :forecast_dwd_icon,
42
+ },
39
43
  }.freeze
40
44
 
41
45
  def get_model_definition(model)
@@ -1,3 +1,3 @@
1
1
  module OpenMeteo
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open-meteo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Morgenstern
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-08 00:00:00.000000000 Z
11
+ date: 2024-01-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-struct
@@ -70,6 +70,26 @@ dependencies:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
72
  version: 2.0.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: faraday-retry
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '2.0'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 2.0.0
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 2.0.0
73
93
  description:
74
94
  email:
75
95
  - gundel.peter@gmail.com
@@ -89,6 +109,7 @@ files:
89
109
  - lib/open_meteo/entities/forecast/daily.rb
90
110
  - lib/open_meteo/entities/forecast/hourly.rb
91
111
  - lib/open_meteo/entities/forecast/item.rb
112
+ - lib/open_meteo/entities/forecast/minutely_15.rb
92
113
  - lib/open_meteo/entities/forecast/units.rb
93
114
  - lib/open_meteo/entities/location.rb
94
115
  - lib/open_meteo/errors.rb
@@ -117,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
138
  - !ruby/object:Gem::Version
118
139
  version: '0'
119
140
  requirements: []
120
- rubygems_version: 3.4.21
141
+ rubygems_version: 3.4.10
121
142
  signing_key:
122
143
  specification_version: 4
123
144
  summary: A client for OpenMeteo weather data