weatherxu 1.0.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +152 -0
- data/lib/weatherxu/client.rb +132 -0
- data/lib/weatherxu/error.rb +14 -0
- data/lib/weatherxu/models.rb +173 -0
- data/lib/weatherxu/version.rb +5 -0
- data/lib/weatherxu.rb +21 -0
- metadata +125 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 85e16dc76187027dc9e39d22a18519601e33ffb95257731b2ed04dec28152e69
|
|
4
|
+
data.tar.gz: 7642f4a499ec155a472a4e5f0c42e647df90d865fbcec8105210651a1a9770e2
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c56f7ea3667523047b913444750d319b5af09fd5154755114f8d9da0cca59df286015c595de6a26dbfb069cf0092e9fd7e154a19fd0367f799e7087844e1a717
|
|
7
|
+
data.tar.gz: 778187ae76c3ffffb49f0e53af43ee1d86468a87a14037c041944205862e14f9cd44f49534e58c5224445ed2240fae3db43d43c33a82e472e97cbe36f43136c8
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 WeatherXu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# WeatherXu Ruby SDK
|
|
2
|
+
|
|
3
|
+
Official Ruby SDK for accessing WeatherXu's weather data API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
Add this line to your application's Gemfile:
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
gem 'weatherxu'
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
And then execute:
|
|
14
|
+
```bash
|
|
15
|
+
$ bundle install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or install it yourself as:
|
|
19
|
+
```bash
|
|
20
|
+
$ gem install weatherxu
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
require 'weatherxu'
|
|
27
|
+
|
|
28
|
+
# Initialize the client
|
|
29
|
+
client = WeatherXu.new(
|
|
30
|
+
api_key: 'YOUR_API_KEY',
|
|
31
|
+
units: 'metric'
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
begin
|
|
35
|
+
# Get current weather and forecast for New York City
|
|
36
|
+
weather = client.get_weather(
|
|
37
|
+
lat: 40.7128,
|
|
38
|
+
lon: -74.0060,
|
|
39
|
+
parts: ['currently', 'hourly', 'daily']
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Access current conditions
|
|
43
|
+
puts "Current temperature: #{weather.currently.temperature}°C"
|
|
44
|
+
|
|
45
|
+
# Access hourly forecast
|
|
46
|
+
weather.hourly&.each do |hour|
|
|
47
|
+
puts "Time: #{hour.forecast_start.strftime('%Y-%m-%d %H:%M')}, " \
|
|
48
|
+
"Temperature: #{hour.temperature}°C"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Get historical weather data
|
|
52
|
+
end_time = Time.now.to_i
|
|
53
|
+
start_time = end_time - (24 * 60 * 60) # 24 hours ago
|
|
54
|
+
|
|
55
|
+
historical = client.get_historical(
|
|
56
|
+
lat: 40.7128,
|
|
57
|
+
lon: -74.0060,
|
|
58
|
+
start: start_time,
|
|
59
|
+
end_time: end_time
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# Access historical data
|
|
63
|
+
historical.hourly.each do |record|
|
|
64
|
+
puts "Time: #{record.forecast_start.strftime('%Y-%m-%d %H:%M')}, " \
|
|
65
|
+
"Temperature: #{record.temperature}°C"
|
|
66
|
+
end
|
|
67
|
+
rescue WeatherXu::Error => e
|
|
68
|
+
puts "Error: #{e.message}"
|
|
69
|
+
puts "Status code: #{e.status_code}" if e.status_code
|
|
70
|
+
puts "Error code: #{e.error_code}" if e.error_code
|
|
71
|
+
end
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Features
|
|
75
|
+
|
|
76
|
+
- Modern Ruby features and best practices
|
|
77
|
+
- Automatic parsing of timestamps to Time objects
|
|
78
|
+
- Comprehensive error handling
|
|
79
|
+
- Support for both metric and imperial units
|
|
80
|
+
- Configurable request timeout
|
|
81
|
+
- Automatic retries with exponential backoff
|
|
82
|
+
|
|
83
|
+
## API Reference
|
|
84
|
+
|
|
85
|
+
### Initialization
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
WeatherXu.new(
|
|
89
|
+
api_key: String,
|
|
90
|
+
units: String = "metric",
|
|
91
|
+
timeout: Integer = 10
|
|
92
|
+
)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Methods
|
|
96
|
+
|
|
97
|
+
#### get_weather
|
|
98
|
+
|
|
99
|
+
Get current weather and forecast data for a location.
|
|
100
|
+
|
|
101
|
+
```ruby
|
|
102
|
+
get_weather(
|
|
103
|
+
lat: Float,
|
|
104
|
+
lon: Float,
|
|
105
|
+
parts: Array<String> = nil,
|
|
106
|
+
units: String = nil
|
|
107
|
+
) -> WeatherData
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Parameters:
|
|
111
|
+
- `lat`: Latitude (-90 to 90)
|
|
112
|
+
- `lon`: Longitude (-180 to 180)
|
|
113
|
+
- `parts`: Optional array of data blocks to include ('alerts', 'currently', 'hourly', 'daily')
|
|
114
|
+
- `units`: Optional unit system ('metric' or 'imperial')
|
|
115
|
+
|
|
116
|
+
#### get_historical
|
|
117
|
+
|
|
118
|
+
Get historical weather data for a location.
|
|
119
|
+
|
|
120
|
+
```ruby
|
|
121
|
+
get_historical(
|
|
122
|
+
lat: Float,
|
|
123
|
+
lon: Float,
|
|
124
|
+
start: Integer,
|
|
125
|
+
end_time: Integer,
|
|
126
|
+
units: String = nil
|
|
127
|
+
) -> HistoricalData
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Parameters:
|
|
131
|
+
- `lat`: Latitude (-90 to 90)
|
|
132
|
+
- `lon`: Longitude (-180 to 180)
|
|
133
|
+
- `start`: Start time (Unix timestamp)
|
|
134
|
+
- `end_time`: End time (Unix timestamp)
|
|
135
|
+
- `units`: Optional unit system ('metric' or 'imperial')
|
|
136
|
+
|
|
137
|
+
## Error Handling
|
|
138
|
+
|
|
139
|
+
The SDK raises `WeatherXu::Error` for any API or network-related errors. Each error includes:
|
|
140
|
+
- Error message
|
|
141
|
+
- HTTP status code (when available)
|
|
142
|
+
- API error code (when provided by the API)
|
|
143
|
+
|
|
144
|
+
## Development
|
|
145
|
+
|
|
146
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
147
|
+
|
|
148
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
|
149
|
+
|
|
150
|
+
## Requirements
|
|
151
|
+
|
|
152
|
+
- Ruby 2.7 or higher
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "json"
|
|
5
|
+
require "uri"
|
|
6
|
+
|
|
7
|
+
module WeatherXu
|
|
8
|
+
# Main client for interacting with the WeatherXu API
|
|
9
|
+
class Client
|
|
10
|
+
WEATHER_BASE_URL = "https://api.weatherxu.com/v1"
|
|
11
|
+
HISTORICAL_BASE_URL = "https://historical.weatherxu.com/v1"
|
|
12
|
+
|
|
13
|
+
# @return [String] API key for authentication
|
|
14
|
+
attr_reader :api_key
|
|
15
|
+
|
|
16
|
+
# @return [String] Unit system ('metric' or 'imperial')
|
|
17
|
+
attr_reader :units
|
|
18
|
+
|
|
19
|
+
# @return [Integer] Request timeout in seconds
|
|
20
|
+
attr_reader :timeout
|
|
21
|
+
|
|
22
|
+
# Initialize a new WeatherXu client
|
|
23
|
+
#
|
|
24
|
+
# @param api_key [String] Your WeatherXu API key
|
|
25
|
+
# @param units [String] Unit system ('metric' or 'imperial')
|
|
26
|
+
# @param timeout [Integer] Request timeout in seconds
|
|
27
|
+
# @raise [Error] if API key is missing
|
|
28
|
+
def initialize(api_key:, units: "metric", timeout: 10)
|
|
29
|
+
raise Error, "API key is required" if api_key.nil? || api_key.empty?
|
|
30
|
+
|
|
31
|
+
@api_key = api_key
|
|
32
|
+
@units = units
|
|
33
|
+
@timeout = timeout
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Get current weather and forecast data for a location
|
|
37
|
+
#
|
|
38
|
+
# @param lat [Float] Latitude (-90 to 90)
|
|
39
|
+
# @param lon [Float] Longitude (-180 to 180)
|
|
40
|
+
# @param parts [Array<String>] Data blocks to include ('alerts', 'currently', 'hourly', 'daily')
|
|
41
|
+
# @param units [String, nil] Unit system ('metric' or 'imperial')
|
|
42
|
+
# @return [WeatherData] Weather data response
|
|
43
|
+
# @raise [Error] if the API request fails
|
|
44
|
+
def get_weather(lat:, lon:, parts: nil, units: nil)
|
|
45
|
+
params = {
|
|
46
|
+
lat: lat,
|
|
47
|
+
lon: lon,
|
|
48
|
+
units: units || @units
|
|
49
|
+
}
|
|
50
|
+
params[:parts] = parts.join(",") if parts
|
|
51
|
+
|
|
52
|
+
response = make_request(
|
|
53
|
+
:get,
|
|
54
|
+
"#{WEATHER_BASE_URL}/weather",
|
|
55
|
+
params
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
WeatherData.new(response)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Get historical weather data for a location
|
|
62
|
+
#
|
|
63
|
+
# @param lat [Float] Latitude (-90 to 90)
|
|
64
|
+
# @param lon [Float] Longitude (-180 to 180)
|
|
65
|
+
# @param start [Integer] Start time (Unix timestamp)
|
|
66
|
+
# @param end_time [Integer] End time (Unix timestamp)
|
|
67
|
+
# @param units [String, nil] Unit system ('metric' or 'imperial')
|
|
68
|
+
# @return [HistoricalData] Historical weather data response
|
|
69
|
+
# @raise [Error] if the API request fails
|
|
70
|
+
def get_historical(lat:, lon:, start:, end_time:, units: nil)
|
|
71
|
+
params = {
|
|
72
|
+
lat: lat,
|
|
73
|
+
lon: lon,
|
|
74
|
+
start: start,
|
|
75
|
+
end: end_time,
|
|
76
|
+
units: units || @units
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
response = make_request(
|
|
80
|
+
:get,
|
|
81
|
+
"#{HISTORICAL_BASE_URL}/history",
|
|
82
|
+
params
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
HistoricalData.new(response)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def make_request(method, url, params = {})
|
|
91
|
+
uri = URI(url)
|
|
92
|
+
uri.query = URI.encode_www_form(params)
|
|
93
|
+
|
|
94
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
95
|
+
http.use_ssl = true
|
|
96
|
+
http.read_timeout = timeout
|
|
97
|
+
http.open_timeout = timeout
|
|
98
|
+
|
|
99
|
+
request = Net::HTTP::Get.new(uri)
|
|
100
|
+
request["X-API-KEY"] = api_key
|
|
101
|
+
request["Content-Type"] = "application/json"
|
|
102
|
+
|
|
103
|
+
response = http.request(request)
|
|
104
|
+
handle_response(response)
|
|
105
|
+
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
|
106
|
+
raise Error, "Request timed out: #{e.message}"
|
|
107
|
+
rescue SocketError, Errno::ECONNREFUSED => e
|
|
108
|
+
raise Error, "Connection failed: #{e.message}"
|
|
109
|
+
rescue StandardError => e
|
|
110
|
+
raise Error, "API request failed: #{e.message}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def handle_response(response)
|
|
114
|
+
case response.code.to_i
|
|
115
|
+
when 200
|
|
116
|
+
JSON.parse(response.body)
|
|
117
|
+
when 401
|
|
118
|
+
raise Error, "Unauthorized: Invalid API key"
|
|
119
|
+
when 429
|
|
120
|
+
raise Error, "Rate limit exceeded"
|
|
121
|
+
else
|
|
122
|
+
begin
|
|
123
|
+
error_body = JSON.parse(response.body)
|
|
124
|
+
raise Error, error_body["error"]["message"] if error_body["error"]
|
|
125
|
+
rescue JSON::ParserError
|
|
126
|
+
# If we can't parse the error body, use the status text
|
|
127
|
+
raise Error, "API request failed with status #{response.code}: #{response.message}"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module WeatherXu
|
|
4
|
+
# Custom error class for WeatherXu API errors
|
|
5
|
+
class Error < StandardError
|
|
6
|
+
attr_reader :status_code, :error_code
|
|
7
|
+
|
|
8
|
+
def initialize(message, status_code: nil, error_code: nil)
|
|
9
|
+
super(message)
|
|
10
|
+
@status_code = status_code
|
|
11
|
+
@error_code = error_code
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "time"
|
|
4
|
+
|
|
5
|
+
module WeatherXu
|
|
6
|
+
# Base class for API responses
|
|
7
|
+
class BaseModel
|
|
8
|
+
def initialize(data)
|
|
9
|
+
data.each do |key, value|
|
|
10
|
+
instance_variable_set("@#{key}", value)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Weather data response
|
|
16
|
+
class WeatherData < BaseModel
|
|
17
|
+
attr_reader :success, :data
|
|
18
|
+
|
|
19
|
+
def initialize(data)
|
|
20
|
+
@success = data["success"]
|
|
21
|
+
@data = data["data"]
|
|
22
|
+
|
|
23
|
+
if @data
|
|
24
|
+
@data["alerts"] = @data["alerts"]&.map { |alert| Alert.new(alert) }
|
|
25
|
+
@data["currently"] = CurrentConditions.new(@data["currently"]) if @data["currently"]
|
|
26
|
+
@data["hourly"] = { "data" => @data["hourly"]["data"].map { |hour| HourlyCondition.new(hour) } } if @data["hourly"]
|
|
27
|
+
@data["daily"] = { "data" => @data["daily"]["data"].map { |day| DailyCondition.new(day) } } if @data["daily"]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Historical weather data response
|
|
33
|
+
class HistoricalData < BaseModel
|
|
34
|
+
attr_reader :success, :data
|
|
35
|
+
|
|
36
|
+
def initialize(data)
|
|
37
|
+
@success = data["success"]
|
|
38
|
+
@data = data["data"]
|
|
39
|
+
|
|
40
|
+
if @data && @data["hourly"]
|
|
41
|
+
@data["hourly"] = {
|
|
42
|
+
"data" => @data["hourly"]["data"].map { |hour| HistoricalHourlyCondition.new(hour) }
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Weather alert information
|
|
49
|
+
class Alert < BaseModel
|
|
50
|
+
attr_reader :title, :description, :ends_at
|
|
51
|
+
|
|
52
|
+
def initialize(data)
|
|
53
|
+
super(data)
|
|
54
|
+
@ends_at = data["endsAt"]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Current weather conditions
|
|
59
|
+
class CurrentConditions < BaseModel
|
|
60
|
+
attr_reader :apparent_temperature, :cloud_cover, :dew_point, :humidity,
|
|
61
|
+
:icon, :precip_intensity, :pressure, :temperature, :uv_index,
|
|
62
|
+
:visibility, :wind_direction, :wind_gust, :wind_speed
|
|
63
|
+
|
|
64
|
+
def initialize(data)
|
|
65
|
+
@apparent_temperature = data["apparentTemperature"]
|
|
66
|
+
@cloud_cover = data["cloudCover"]
|
|
67
|
+
@dew_point = data["dewPoint"]
|
|
68
|
+
@humidity = data["humidity"]
|
|
69
|
+
@icon = data["icon"]
|
|
70
|
+
@precip_intensity = data["precipIntensity"]
|
|
71
|
+
@pressure = data["pressure"]
|
|
72
|
+
@temperature = data["temperature"]
|
|
73
|
+
@uv_index = data["uvIndex"]
|
|
74
|
+
@visibility = data["visibility"]
|
|
75
|
+
@wind_direction = data["windDirection"]
|
|
76
|
+
@wind_gust = data["windGust"]
|
|
77
|
+
@wind_speed = data["windSpeed"]
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Hourly weather condition
|
|
82
|
+
class HourlyCondition < BaseModel
|
|
83
|
+
attr_reader :apparent_temperature, :cloud_cover, :dew_point, :forecast_start,
|
|
84
|
+
:humidity, :icon, :precip_intensity, :precip_probability, :pressure,
|
|
85
|
+
:temperature, :uv_index, :visibility, :wind_direction, :wind_gust,
|
|
86
|
+
:wind_speed
|
|
87
|
+
|
|
88
|
+
def initialize(data)
|
|
89
|
+
@apparent_temperature = data["apparentTemperature"]
|
|
90
|
+
@cloud_cover = data["cloudCover"]
|
|
91
|
+
@dew_point = data["dewPoint"]
|
|
92
|
+
@forecast_start = data["forecastStart"]
|
|
93
|
+
@humidity = data["humidity"]
|
|
94
|
+
@icon = data["icon"]
|
|
95
|
+
@precip_intensity = data["precipIntensity"]
|
|
96
|
+
@precip_probability = data["precipProbability"]
|
|
97
|
+
@pressure = data["pressure"]
|
|
98
|
+
@temperature = data["temperature"]
|
|
99
|
+
@uv_index = data["uvIndex"]
|
|
100
|
+
@visibility = data["visibility"]
|
|
101
|
+
@wind_direction = data["windDirection"]
|
|
102
|
+
@wind_gust = data["windGust"]
|
|
103
|
+
@wind_speed = data["windSpeed"]
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Historical hourly condition
|
|
108
|
+
class HistoricalHourlyCondition < BaseModel
|
|
109
|
+
attr_reader :apparent_temperature, :cloud_cover, :dew_point, :forecast_start,
|
|
110
|
+
:humidity, :icon, :precip_intensity, :pressure, :temperature,
|
|
111
|
+
:wind_direction, :wind_gust, :wind_speed
|
|
112
|
+
|
|
113
|
+
def initialize(data)
|
|
114
|
+
@apparent_temperature = data["apparentTemperature"]
|
|
115
|
+
@cloud_cover = data["cloudCover"]
|
|
116
|
+
@dew_point = data["dewPoint"]
|
|
117
|
+
@forecast_start = data["forecastStart"]
|
|
118
|
+
@humidity = data["humidity"]
|
|
119
|
+
@icon = data["icon"]
|
|
120
|
+
@precip_intensity = data["precipIntensity"]
|
|
121
|
+
@pressure = data["pressure"]
|
|
122
|
+
@temperature = data["temperature"]
|
|
123
|
+
@wind_direction = data["windDirection"]
|
|
124
|
+
@wind_gust = data["windGust"]
|
|
125
|
+
@wind_speed = data["windSpeed"]
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Daily weather condition
|
|
130
|
+
class DailyCondition < BaseModel
|
|
131
|
+
attr_reader :apparent_temperature_avg, :apparent_temperature_max,
|
|
132
|
+
:apparent_temperature_min, :cloud_cover, :dew_point_avg,
|
|
133
|
+
:dew_point_max, :dew_point_min, :forecast_end, :forecast_start,
|
|
134
|
+
:humidity, :icon, :moon_phase, :precip_intensity,
|
|
135
|
+
:precip_probability, :pressure, :sunrise_time, :sunset_time,
|
|
136
|
+
:temperature_avg, :temperature_max, :temperature_min,
|
|
137
|
+
:uv_index_max, :visibility, :wind_direction_avg, :wind_gust_avg,
|
|
138
|
+
:wind_gust_max, :wind_gust_min, :wind_speed_avg, :wind_speed_max,
|
|
139
|
+
:wind_speed_min
|
|
140
|
+
|
|
141
|
+
def initialize(data)
|
|
142
|
+
@apparent_temperature_avg = data["apparentTemperatureAvg"]
|
|
143
|
+
@apparent_temperature_max = data["apparentTemperatureMax"]
|
|
144
|
+
@apparent_temperature_min = data["apparentTemperatureMin"]
|
|
145
|
+
@cloud_cover = data["cloudCover"]
|
|
146
|
+
@dew_point_avg = data["dewPointAvg"]
|
|
147
|
+
@dew_point_max = data["dewPointMax"]
|
|
148
|
+
@dew_point_min = data["dewPointMin"]
|
|
149
|
+
@forecast_end = data["forecastEnd"]
|
|
150
|
+
@forecast_start = data["forecastStart"]
|
|
151
|
+
@humidity = data["humidity"]
|
|
152
|
+
@icon = data["icon"]
|
|
153
|
+
@moon_phase = data["moonPhase"]
|
|
154
|
+
@precip_intensity = data["precipIntensity"]
|
|
155
|
+
@precip_probability = data["precipProbability"]
|
|
156
|
+
@pressure = data["pressure"]
|
|
157
|
+
@sunrise_time = data["sunriseTime"]
|
|
158
|
+
@sunset_time = data["sunsetTime"]
|
|
159
|
+
@temperature_avg = data["temperatureAvg"]
|
|
160
|
+
@temperature_max = data["temperatureMax"]
|
|
161
|
+
@temperature_min = data["temperatureMin"]
|
|
162
|
+
@uv_index_max = data["uvIndexMax"]
|
|
163
|
+
@visibility = data["visibility"]
|
|
164
|
+
@wind_direction_avg = data["windDirectionAvg"]
|
|
165
|
+
@wind_gust_avg = data["windGustAvg"]
|
|
166
|
+
@wind_gust_max = data["windGustMax"]
|
|
167
|
+
@wind_gust_min = data["windGustMin"]
|
|
168
|
+
@wind_speed_avg = data["windSpeedAvg"]
|
|
169
|
+
@wind_speed_max = data["windSpeedMax"]
|
|
170
|
+
@wind_speed_min = data["windSpeedMin"]
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
data/lib/weatherxu.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "weatherxu/version"
|
|
4
|
+
require_relative "weatherxu/error"
|
|
5
|
+
require_relative "weatherxu/models"
|
|
6
|
+
require_relative "weatherxu/client"
|
|
7
|
+
|
|
8
|
+
# WeatherXu module for accessing weather data
|
|
9
|
+
module WeatherXu
|
|
10
|
+
class << self
|
|
11
|
+
# Create a new client instance
|
|
12
|
+
#
|
|
13
|
+
# @param api_key [String] Your WeatherXu API key
|
|
14
|
+
# @param units [String] Unit system ('metric' or 'imperial')
|
|
15
|
+
# @param timeout [Integer] Request timeout in seconds
|
|
16
|
+
# @return [Client] A new client instance
|
|
17
|
+
def new(api_key:, units: "metric", timeout: 10)
|
|
18
|
+
Client.new(api_key: api_key, units: units, timeout: timeout)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: weatherxu
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- WeatherXu
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2025-01-29 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '13.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '13.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rspec
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '3.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '3.0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rubocop
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.21'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '1.21'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: yard
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.9'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.9'
|
|
83
|
+
description: A Ruby SDK for accessing WeatherXu's weather data, including current
|
|
84
|
+
conditions, forecasts, and historical weather data.
|
|
85
|
+
email:
|
|
86
|
+
- support@weatherxu.com
|
|
87
|
+
executables: []
|
|
88
|
+
extensions: []
|
|
89
|
+
extra_rdoc_files: []
|
|
90
|
+
files:
|
|
91
|
+
- LICENSE
|
|
92
|
+
- README.md
|
|
93
|
+
- lib/weatherxu.rb
|
|
94
|
+
- lib/weatherxu/client.rb
|
|
95
|
+
- lib/weatherxu/error.rb
|
|
96
|
+
- lib/weatherxu/models.rb
|
|
97
|
+
- lib/weatherxu/version.rb
|
|
98
|
+
homepage: https://weatherxu.com
|
|
99
|
+
licenses:
|
|
100
|
+
- MIT
|
|
101
|
+
metadata:
|
|
102
|
+
homepage_uri: https://weatherxu.com
|
|
103
|
+
source_code_uri: https://github.com/weatherxu/weatherxu-ruby
|
|
104
|
+
changelog_uri: https://github.com/weatherxu/weatherxu-ruby/blob/main/CHANGELOG.md
|
|
105
|
+
documentation_uri: https://weatherxu.com/documentation
|
|
106
|
+
post_install_message:
|
|
107
|
+
rdoc_options: []
|
|
108
|
+
require_paths:
|
|
109
|
+
- lib
|
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
111
|
+
requirements:
|
|
112
|
+
- - ">="
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: 2.6.0
|
|
115
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
|
+
requirements:
|
|
117
|
+
- - ">="
|
|
118
|
+
- !ruby/object:Gem::Version
|
|
119
|
+
version: '0'
|
|
120
|
+
requirements: []
|
|
121
|
+
rubygems_version: 3.4.10
|
|
122
|
+
signing_key:
|
|
123
|
+
specification_version: 4
|
|
124
|
+
summary: Official Ruby SDK for WeatherXu's weather data API
|
|
125
|
+
test_files: []
|