open-meteo 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f1fd59fe55c171c4cefb24b80613933b28d10040fdff524490dcd9e6e2ed0514
4
+ data.tar.gz: 8231a53ba4250c627db4c44eb513f6f0cf41631c3a5ba3c3934a20d0ee731562
5
+ SHA512:
6
+ metadata.gz: ec997727575db6186329054eca41b3c60c6729571788d012c57a74ed7c0314308ee75e11dc201287cc396d6be570b1e38ef675dd67ebd79e41d3d5a645de7957
7
+ data.tar.gz: 4055bd5d3d7d63c40f3cfa8eae6822f755d806c48b7e700e65ffd2de14bdd3761373318bba2699752c97db26621893cefb3ec1b34caa87d9151ca5c05b112d40
@@ -0,0 +1,17 @@
1
+ module OpenMeteo
2
+ class Client
3
+ ##
4
+ # The configuration for the OpenMeteo::Client.
5
+ class Config
6
+ attr_reader :host
7
+
8
+ def initialize(host: "api.open-meteo.com")
9
+ @host = host
10
+ end
11
+
12
+ def url
13
+ "https://#{host}"
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,22 @@
1
+ module OpenMeteo
2
+ class Client
3
+ ##
4
+ # The class that constructs the URLs for given endpoints.
5
+ class UrlBuilder
6
+ API_PATHS = { forecast: "v1/forecast" }.freeze
7
+
8
+ attr_reader :api_config
9
+
10
+ def initialize(api_config: OpenMeteo::Client::Config.new)
11
+ @api_config = api_config
12
+ end
13
+
14
+ def build_url(endpoint, *args)
15
+ relative_path = API_PATHS.fetch(endpoint.to_sym)
16
+ full_path = [api_config.url, relative_path].join("/")
17
+
18
+ URI::DEFAULT_PARSER.escape(format(full_path, args))
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ require "faraday"
2
+
3
+ require_relative "client/config"
4
+ require_relative "client/url_builder"
5
+
6
+ module OpenMeteo
7
+ ##
8
+ # The client that makes the actual requests to the OpenMeteo API.
9
+ class Client
10
+ class ConnectionFailed < StandardError
11
+ end
12
+ class Timeout < StandardError
13
+ end
14
+
15
+ attr_reader :api_config
16
+
17
+ def initialize(
18
+ api_config: OpenMeteo::Client::Config.new,
19
+ url_builder: OpenMeteo::Client::UrlBuilder.new,
20
+ agent: Faraday.new
21
+ )
22
+ @api_config = api_config
23
+ @url_builder = url_builder
24
+ @agent = agent
25
+ end
26
+
27
+ def get(endpoint_name, *endpoint_args, **get_params)
28
+ endpoint = url_builder.build_url(endpoint_name, *endpoint_args)
29
+
30
+ agent.get do |req|
31
+ req.params = get_params
32
+ req.url(endpoint)
33
+ end
34
+ rescue Faraday::ConnectionFailed => e
35
+ raise ConnectionFailed, "Could not connect to OpenMeteo API: #{e.message}"
36
+ rescue Faraday::TimeoutError
37
+ raise Timeout, "Timeout error from the OpenMeteo API"
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :agent, :url_builder
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ module OpenMeteo
2
+ class Forecast
3
+ module Variables
4
+ ##
5
+ # The Variables for a general request (meaning without a specific model) to the OpenMeteo API.
6
+ #
7
+ # See https://open-meteo.com/en/docs
8
+ class General
9
+ attr_reader :current, :hourly, :daily
10
+
11
+ def initialize(current:, hourly:, daily:)
12
+ @current = current
13
+ @hourly = hourly
14
+ @daily = daily
15
+ end
16
+
17
+ def validate
18
+ # FIXME: Placeholder for validation
19
+ true
20
+ end
21
+
22
+ def to_get_params
23
+ get_params = {}
24
+
25
+ get_params[:current] = current.join(",") if current != []
26
+ get_params[:hourly] = hourly.join(",") if hourly != []
27
+ get_params[:daily] = daily.join(",") if daily != []
28
+
29
+ get_params
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,55 @@
1
+ require_relative "client"
2
+ require_relative "forecast/variables/general"
3
+
4
+ module OpenMeteo
5
+ ##
6
+ # Perform a forecase request to the OpenMeteo API.
7
+ #
8
+ # See https://open-meteo.com/en/docs
9
+ class Forecast
10
+ class ForecastModelNotImplemented < StandardError
11
+ end
12
+
13
+ def initialize(client: OpenMeteo::Client.new)
14
+ @client = client
15
+ end
16
+
17
+ def get(location:, variables:, model: :general)
18
+ ensure_valid_location(location)
19
+
20
+ model_definition = get_model_definition(model)
21
+
22
+ variables = model_definition[:variables_class].new(**variables)
23
+ variables.validate
24
+
25
+ get_forecast(model_definition[:endpoint], location, variables)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :client
31
+
32
+ AVAILABLE_FORECAST_MODELS = {
33
+ general: {
34
+ # See https://open-meteo.com/en/docs
35
+ variables_class: OpenMeteo::Forecast::Variables::General,
36
+ endpoint: :forecast,
37
+ },
38
+ }.freeze
39
+
40
+ def get_model_definition(model)
41
+ AVAILABLE_FORECAST_MODELS.fetch(model) { raise ForecastModelNotImplemented }
42
+ end
43
+
44
+ def ensure_valid_location(location)
45
+ raise "Not an OpenMeteo::Location" unless location.is_a? OpenMeteo::Location
46
+
47
+ location.validate!
48
+ end
49
+
50
+ def get_forecast(endpoint, location, variables)
51
+ get_params = { **location.to_get_params, **variables.to_get_params }
52
+ client.get(endpoint, **get_params)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,21 @@
1
+ module OpenMeteo
2
+ ##
3
+ # A location for a request to OpenMeteo.
4
+ class Location
5
+ attr_reader :latitude, :longitude
6
+
7
+ def initialize(longitude:, latitude:)
8
+ @longitude = longitude
9
+ @latitude = latitude
10
+ end
11
+
12
+ def validate!
13
+ # FIXME: Placeholder for validation
14
+ true
15
+ end
16
+
17
+ def to_get_params
18
+ { latitude:, longitude: }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module OpenMeteo
2
+ VERSION = "0.0.2".freeze
3
+ end
data/lib/open_meteo.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "open_meteo/forecast"
2
+ require "open_meteo/location"
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: open-meteo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Peter Morgenstern
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-11-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
33
+ description:
34
+ email:
35
+ - gundel.peter@gmail.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - lib/open_meteo.rb
41
+ - lib/open_meteo/client.rb
42
+ - lib/open_meteo/client/config.rb
43
+ - lib/open_meteo/client/url_builder.rb
44
+ - lib/open_meteo/forecast.rb
45
+ - lib/open_meteo/forecast/variables/general.rb
46
+ - lib/open_meteo/location.rb
47
+ - lib/open_meteo/version.rb
48
+ homepage: https://github.com/open-meteo-ruby/open-meteo-ruby
49
+ licenses:
50
+ - MIT
51
+ metadata:
52
+ rubygems_mfa_required: 'true'
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.3.7
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: A client for OpenMeteo weather data
72
+ test_files: []