open-meteo 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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: []