open-meteo 0.3.2 → 0.3.4

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: 60140c0aa4f49166a8d9efef379ba7628fb663bd65c712018f7e2089f43677d5
4
- data.tar.gz: bd54e00eabe5518725f32b790e8da3257fc985e0e678d0220343ac528858fbe5
3
+ metadata.gz: 19125290e7d78eb6a4493ac3b774347b09c9bbbb5753243e77e90a49f0f7c590
4
+ data.tar.gz: f7975e9e2b8d7a49d6fd7b91c13caa0005966a8770c45536405a85f3e0a26cc8
5
5
  SHA512:
6
- metadata.gz: 17a87ed4b29b65f93ff21bfad1c2579f37faa5eb7677f7598da708438e1888d54729af4bd1946328a0b37dc14f8fef9711bab95ab3619ccc7e16b6e0c300302f
7
- data.tar.gz: 205a30320db01bf6406e69c02633c1799d81f660962b05d13749cb9f92c630044224833cd88bd1b46bcfaf85656b5067958fe94d636d92b861b7aed9bb5e82ec
6
+ metadata.gz: 5829c7d1b646385e0c8d2b8d25b6ce2faca5c4cab22a905c9fc6e62ca5cf2c1bee5c112129a11c11938b787ecec642d28e1c512302f2848c591f5618e60144d7
7
+ data.tar.gz: 0e2a5f8debf66630755b20ec5832d3a4f740bcd7fa0531fb4132516740f7b8b5aa315e8a697a679628892c43ea0fc8744184d55674e45a73e6f3adcc7bb257e2
@@ -3,7 +3,11 @@ 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", forecast_dwd_icon: "v1/dwd-icon" }.freeze
6
+ API_PATHS = {
7
+ forecast: "v1/forecast",
8
+ forecast_dwd_icon: "v1/dwd-icon",
9
+ search: "v1/search",
10
+ }.freeze
7
11
 
8
12
  attr_reader :config
9
13
 
@@ -11,11 +15,11 @@ module OpenMeteo
11
15
  @config = config
12
16
  end
13
17
 
14
- def build_url(endpoint, *args)
18
+ def build_url(endpoint, path_params = {})
15
19
  relative_path = API_PATHS.fetch(endpoint.to_sym)
16
20
  full_path = [config.url, relative_path].join("/")
17
21
 
18
- URI::DEFAULT_PARSER.escape(format(full_path, args))
22
+ URI::DEFAULT_PARSER.escape(format(full_path, path_params))
19
23
  end
20
24
  end
21
25
  end
@@ -23,11 +23,11 @@ module OpenMeteo
23
23
  @agent = agent
24
24
  end
25
25
 
26
- def get(endpoint_name, *endpoint_args, **get_params)
27
- endpoint = url_builder.build_url(endpoint_name, *endpoint_args)
26
+ def get(endpoint_name, path_params: {}, query_params: {})
27
+ endpoint = url_builder.build_url(endpoint_name, path_params)
28
28
 
29
29
  agent.connect.get do |request|
30
- request.params = get_params.merge({ apikey: config.api_key }.compact)
30
+ request.params = query_params.merge({ apikey: config.api_key }.compact)
31
31
  request.url(endpoint)
32
32
  end
33
33
  rescue Faraday::ConnectionFailed => e
@@ -12,7 +12,7 @@ module OpenMeteo
12
12
  OpenMeteo::Entities::Contracts::LocationContract.validate!(to_hash)
13
13
  end
14
14
 
15
- def to_get_params
15
+ def to_query_params
16
16
  { latitude:, longitude: }
17
17
  end
18
18
  end
@@ -0,0 +1,48 @@
1
+ module OpenMeteo
2
+ module Entities
3
+ ##
4
+ # A Search Result in the Open Meteo Geocoding API. Represents one possible location.
5
+ SearchResult =
6
+ Struct.new(
7
+ :id,
8
+ :name,
9
+ :latitude,
10
+ :longitude,
11
+ :elevation,
12
+ :feature_code,
13
+ :country_code,
14
+ :admin_1_id,
15
+ :admin_2_id,
16
+ :admin_3_id,
17
+ :admin_4_id,
18
+ :timezone,
19
+ :population,
20
+ :postcodes,
21
+ :country_id,
22
+ :country,
23
+ :admin_1,
24
+ :admin_2,
25
+ :admin_3,
26
+ :admin_4,
27
+ keyword_init: true,
28
+ )
29
+
30
+ ##
31
+ # A list of possible locations from the Geocoding API
32
+ class Search
33
+ attr_reader :attributes, :results, :raw_json
34
+
35
+ def initialize(json_body)
36
+ @raw_json = json_body
37
+
38
+ @results =
39
+ json_body["results"].map do |result|
40
+ normalized_result = result.transform_keys { |key| key.to_s.gsub(/(\w)(\d)/, '\1_\2') }
41
+
42
+ SearchResult.new(normalized_result)
43
+ end
44
+ @attributes = json_body.keys
45
+ end
46
+ end
47
+ end
48
+ end
@@ -20,7 +20,7 @@ module OpenMeteo
20
20
  conn.options[:open_timeout] = config.timeouts[:open_timeout]
21
21
 
22
22
  conn.request :retry, RETRY_OPTIONS
23
- conn.response :logger
23
+ conn.response :logger, config.logger
24
24
  end
25
25
  end
26
26
  end
@@ -25,15 +25,18 @@ module OpenMeteo
25
25
  :models,
26
26
  OpenMeteo::Types::Strict::Array.of(OpenMeteo::Types::Strict::Symbol).default([].freeze),
27
27
  )
28
+ attribute(:timezone, OpenMeteo::Types::Strict::String.optional.default(nil))
28
29
 
29
- def to_get_params
30
- get_params = {}
30
+ def to_query_params
31
+ query_params = {}
31
32
 
32
33
  %i[current minutely_15 hourly daily models].each do |key|
33
- get_params[key] = send(key).join(",") if send(key) != []
34
+ query_params[key] = send(key).join(",") if send(key) != []
34
35
  end
35
36
 
36
- get_params
37
+ %i[timezone].each { |key| query_params[key] = send(key) if send(key) }
38
+
39
+ query_params
37
40
  end
38
41
  end
39
42
  end
@@ -31,10 +31,6 @@ module OpenMeteo
31
31
  get_forecast(model_definition[:endpoint], location, variables_object)
32
32
  end
33
33
 
34
- private
35
-
36
- attr_reader :client
37
-
38
34
  AVAILABLE_FORECAST_MODELS = {
39
35
  general: {
40
36
  # See https://open-meteo.com/en/docs
@@ -46,6 +42,10 @@ module OpenMeteo
46
42
  },
47
43
  }.freeze
48
44
 
45
+ private
46
+
47
+ attr_reader :client
48
+
49
49
  def get_model_definition(model)
50
50
  AVAILABLE_FORECAST_MODELS.fetch(model) { raise ForecastModelNotImplemented }
51
51
  end
@@ -57,8 +57,8 @@ module OpenMeteo
57
57
  end
58
58
 
59
59
  def get_forecast(endpoint, location, variables)
60
- get_params = { **location.to_get_params, **variables.to_get_params }
61
- response = client.get(endpoint, **get_params)
60
+ query_params = { **location.to_query_params, **variables.to_query_params }
61
+ response = client.get(endpoint, query_params:)
62
62
 
63
63
  @response_wrapper.wrap(response, entity: OpenMeteo::Entities::Forecast)
64
64
  end
@@ -0,0 +1,16 @@
1
+ module OpenMeteo
2
+ class Search
3
+ ##
4
+ # The variables used for a Search in the Open Meteo Geocoding API
5
+ class Variables < Dry::Struct
6
+ attribute(:count, OpenMeteo::Types::Strict::Integer.optional.default(nil))
7
+ attribute(:language, OpenMeteo::Types::Strict::String.optional.default(nil))
8
+
9
+ def to_query_params
10
+ %i[count language].each_with_object({}) do |key, query_params|
11
+ query_params[key] = send(key) if send(key)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,36 @@
1
+ require_relative "client"
2
+ require_relative "search/variables"
3
+
4
+ module OpenMeteo
5
+ ##
6
+ # Perform a search request to the Open Meteo Geocoding API
7
+ #
8
+ # Returns a list of possible locations based of a location name string
9
+ # https://open-meteo.com/en/docs/geocoding-api
10
+ class Search
11
+ def initialize(
12
+ config: OpenMeteo::Client::Config.new(host: "geocoding-api.open-meteo.com"),
13
+ client: OpenMeteo::Client.new(config:),
14
+ response_wrapper: OpenMeteo::ResponseWrapper.new(config:)
15
+ )
16
+ @client = client
17
+ @response_wrapper = response_wrapper
18
+ end
19
+
20
+ def get(name:, variables:)
21
+ variables_object = OpenMeteo::Search::Variables.new(**variables)
22
+ search_get(name, variables_object)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :client
28
+
29
+ def search_get(name, variables)
30
+ query_params = { name:, **variables.to_query_params }
31
+ response = client.get(:search, query_params:)
32
+
33
+ @response_wrapper.wrap(response, entity: OpenMeteo::Entities::Search)
34
+ end
35
+ end
36
+ end
@@ -1,3 +1,3 @@
1
1
  module OpenMeteo
2
- VERSION = "0.3.2".freeze
2
+ VERSION = "0.3.4".freeze
3
3
  end
data/lib/open_meteo.rb CHANGED
@@ -3,7 +3,9 @@ require "open_meteo/types"
3
3
  require "open_meteo/configuration"
4
4
  require "open_meteo/entities/location"
5
5
  require "open_meteo/entities/forecast"
6
+ require "open_meteo/entities/search"
6
7
  require "open_meteo/forecast"
8
+ require "open_meteo/search"
7
9
  require "open_meteo/response_wrapper"
8
10
  require "open_meteo/errors"
9
11
 
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: open-meteo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Morgenstern
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-03-21 00:00:00.000000000 Z
10
+ date: 2025-04-06 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: dry-struct
@@ -90,7 +89,6 @@ dependencies:
90
89
  - - ">="
91
90
  - !ruby/object:Gem::Version
92
91
  version: 2.0.0
93
- description:
94
92
  email:
95
93
  - gundel.peter@gmail.com
96
94
  executables: []
@@ -112,11 +110,14 @@ files:
112
110
  - lib/open_meteo/entities/forecast/minutely_15.rb
113
111
  - lib/open_meteo/entities/forecast/units.rb
114
112
  - lib/open_meteo/entities/location.rb
113
+ - lib/open_meteo/entities/search.rb
115
114
  - lib/open_meteo/errors.rb
116
115
  - lib/open_meteo/faraday_connection.rb
117
116
  - lib/open_meteo/forecast.rb
118
117
  - lib/open_meteo/forecast/variables.rb
119
118
  - lib/open_meteo/response_wrapper.rb
119
+ - lib/open_meteo/search.rb
120
+ - lib/open_meteo/search/variables.rb
120
121
  - lib/open_meteo/types.rb
121
122
  - lib/open_meteo/version.rb
122
123
  homepage: https://github.com/open-meteo-ruby/open-meteo-ruby
@@ -124,7 +125,6 @@ licenses:
124
125
  - MIT
125
126
  metadata:
126
127
  rubygems_mfa_required: 'true'
127
- post_install_message:
128
128
  rdoc_options: []
129
129
  require_paths:
130
130
  - lib
@@ -139,8 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  requirements: []
142
- rubygems_version: 3.4.10
143
- signing_key:
142
+ rubygems_version: 3.6.2
144
143
  specification_version: 4
145
144
  summary: A client for OpenMeteo weather data
146
145
  test_files: []