vpndetection 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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +171 -0
  4. data/lib/vpndetection/api/database_api.rb +351 -0
  5. data/lib/vpndetection/api/lookup_api.rb +85 -0
  6. data/lib/vpndetection/api_client.rb +397 -0
  7. data/lib/vpndetection/api_error.rb +58 -0
  8. data/lib/vpndetection/api_model_base.rb +88 -0
  9. data/lib/vpndetection/bogon.rb +60 -0
  10. data/lib/vpndetection/bogons.rb +67 -0
  11. data/lib/vpndetection/cache.rb +35 -0
  12. data/lib/vpndetection/client.rb +133 -0
  13. data/lib/vpndetection/configuration.rb +326 -0
  14. data/lib/vpndetection/database.rb +167 -0
  15. data/lib/vpndetection/errors.rb +107 -0
  16. data/lib/vpndetection/models/class_detail.rb +169 -0
  17. data/lib/vpndetection/models/dataset_checksums.rb +174 -0
  18. data/lib/vpndetection/models/dataset_checksums_response.rb +216 -0
  19. data/lib/vpndetection/models/dataset_format_size.rb +201 -0
  20. data/lib/vpndetection/models/dataset_list.rb +166 -0
  21. data/lib/vpndetection/models/dataset_metadata.rb +280 -0
  22. data/lib/vpndetection/models/dataset_metadata_column.rb +199 -0
  23. data/lib/vpndetection/models/download.rb +276 -0
  24. data/lib/vpndetection/models/download_list.rb +166 -0
  25. data/lib/vpndetection/models/error_envelope.rb +164 -0
  26. data/lib/vpndetection/models/licensed_dataset.rb +358 -0
  27. data/lib/vpndetection/models/licensed_version.rb +262 -0
  28. data/lib/vpndetection/models/lookup_error.rb +166 -0
  29. data/lib/vpndetection/models/lookup_response.rb +343 -0
  30. data/lib/vpndetection/models/proxy_detail.rb +199 -0
  31. data/lib/vpndetection/models/vpn_detail.rb +179 -0
  32. data/lib/vpndetection/result.rb +211 -0
  33. data/lib/vpndetection/retries.rb +33 -0
  34. data/lib/vpndetection/transport.rb +116 -0
  35. data/lib/vpndetection/version.rb +5 -0
  36. data/lib/vpndetection.rb +40 -0
  37. metadata +109 -0
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'time'
5
+
6
+ module VPNDetection
7
+ # Everything this library raises.
8
+ #
9
+ # `:rate_limited` and `:quota_exceeded` both arrive as HTTP 429 and are NOT the
10
+ # same thing. A rate limit is the API protecting itself and carries
11
+ # `Retry-After`; retrying works. A spent quota carries no such header and
12
+ # retrying will not help until the window rolls over or the limit is raised.
13
+ # The header is the only thing that distinguishes them.
14
+ class Error < StandardError
15
+ KINDS = %i[
16
+ bad_request unauthorized forbidden rate_limited quota_exceeded server_error network
17
+ ].freeze
18
+
19
+ RETRYABLE = %i[rate_limited server_error network].freeze
20
+
21
+ attr_reader :kind, :status, :retry_after_seconds
22
+
23
+ def initialize(kind, message, status: nil, retry_after_seconds: nil)
24
+ super(message)
25
+ @kind = kind
26
+ @status = status
27
+ @retry_after_seconds = retry_after_seconds
28
+ end
29
+
30
+ # Whether retrying this exact request could succeed.
31
+ def retryable?
32
+ RETRYABLE.include?(@kind)
33
+ end
34
+
35
+ # `message:` stands in for the response body, for a response whose body must
36
+ # not be read: an object storage error page has no bounded size, so a refusal
37
+ # from it is classified on the status alone.
38
+ def self.from_status(status, headers, body, message: nil)
39
+ message ||= message_of(body) || "request failed with status #{status}"
40
+ retry_after = parse_retry_after(header(headers, 'retry-after'))
41
+
42
+ case status
43
+ when 429
44
+ # Present means transient, absent means an allowance is spent. Nothing
45
+ # else in the response separates the two.
46
+ if retry_after.nil?
47
+ new(:quota_exceeded, message, status: status)
48
+ else
49
+ new(:rate_limited, message, status: status, retry_after_seconds: retry_after)
50
+ end
51
+ when 400 then new(:bad_request, message, status: status)
52
+ when 401 then new(:unauthorized, message, status: status)
53
+ when 403 then new(:forbidden, message, status: status)
54
+ # Every other 4xx is a CLIENT error. Classifying on the RANGE rather than
55
+ # on an enumerated list is what keeps a 404 from a bad dataset id falling
56
+ # through to the retryable server_error default and being retried twice
57
+ # before it fails.
58
+ when 400..499 then new(:bad_request, message, status: status)
59
+ else new(:server_error, message, status: status)
60
+ end
61
+ end
62
+
63
+ # A Typhoeus response that never carried an HTTP status: DNS failure,
64
+ # connection refused, TLS failure, or a timeout.
65
+ def self.from_transport(response)
66
+ message = response.return_message || response.return_code&.to_s || 'transport failure'
67
+ new(:network, message)
68
+ end
69
+
70
+ # Case-insensitive, and works with a plain Hash as well as with the
71
+ # case-blind header object Typhoeus builds from a live response.
72
+ def self.header(headers, name)
73
+ return nil if headers.nil?
74
+
75
+ value = headers[name] || headers[name.split('-').map(&:capitalize).join('-')]
76
+ value = headers.find { |k, _| k.to_s.downcase == name }&.last if value.nil?
77
+ value.is_a?(Array) ? value.last : value
78
+ end
79
+
80
+ # The two APIs behind this host answer with different envelopes: the lookup
81
+ # endpoint uses `error`, the database endpoints use `rc`. Both are read here
82
+ # so a caller never has to know which one they hit. An intermediary's HTML
83
+ # error page parses as neither and leaves the status to speak for itself.
84
+ def self.message_of(body)
85
+ parsed = body.is_a?(String) ? (JSON.parse(body) rescue nil) : body
86
+ return nil unless parsed.is_a?(Hash)
87
+
88
+ message = parsed['error'] || parsed['rc']
89
+ message.is_a?(String) ? message : nil
90
+ end
91
+
92
+ def self.parse_retry_after(value)
93
+ return nil if value.nil? || value.to_s.strip.empty?
94
+
95
+ seconds = Float(value, exception: false)
96
+ return seconds if seconds && seconds >= 0
97
+
98
+ # The header also permits an HTTP date.
99
+ when_at = Time.httpdate(value) rescue nil
100
+ return nil if when_at.nil?
101
+
102
+ [0, (when_at - Time.now).ceil].max
103
+ end
104
+
105
+ private_class_method :header, :message_of, :parse_retry_after
106
+ end
107
+ end
@@ -0,0 +1,169 @@
1
+ =begin
2
+ #VPNDetection API
3
+
4
+ #The VPNDetection API: classify any IP address, and download the datasets behind the answers. See https://docs.vpndetection.io for guides and https://github.com/vpndetection-io for the official client libraries.
5
+
6
+ The version of the OpenAPI document: 2026.09.04
7
+ Contact: support@vpndetection.io
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.25.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module VPNDetection
17
+ # The shared detail shape for the hosting, relay, tor and cdn datasets. Every key is present when the object is populated; the object is `{}` when its flag is false.
18
+ class ClassDetail < ApiModelBase
19
+ # The provider, or an empty string where the dataset has none.
20
+ attr_accessor :provider
21
+
22
+ # How strongly the classification is supported.
23
+ attr_accessor :confidence
24
+
25
+ # The most recent date this address was observed in this dataset.
26
+ attr_accessor :last_seen
27
+
28
+ # Attribute mapping from ruby-style variable name to JSON key.
29
+ def self.attribute_map
30
+ {
31
+ :'provider' => :'provider',
32
+ :'confidence' => :'confidence',
33
+ :'last_seen' => :'last_seen'
34
+ }
35
+ end
36
+
37
+ # Returns attribute mapping this model knows about
38
+ def self.acceptable_attribute_map
39
+ attribute_map
40
+ end
41
+
42
+ # Returns all the JSON keys this model knows about
43
+ def self.acceptable_attributes
44
+ acceptable_attribute_map.values
45
+ end
46
+
47
+ # Attribute type mapping.
48
+ def self.openapi_types
49
+ {
50
+ :'provider' => :'String',
51
+ :'confidence' => :'String',
52
+ :'last_seen' => :'Date'
53
+ }
54
+ end
55
+
56
+ # List of attributes with nullable: true
57
+ def self.openapi_nullable
58
+ Set.new([
59
+ ])
60
+ end
61
+
62
+ # Initializes the object
63
+ # @param [Hash] attributes Model attributes in the form of hash
64
+ def initialize(attributes = {})
65
+ if (!attributes.is_a?(Hash))
66
+ fail ArgumentError, "The input argument (attributes) must be a hash in `VPNDetection::ClassDetail` initialize method"
67
+ end
68
+
69
+ # check to see if the attribute exists and convert string to symbol for hash key
70
+ acceptable_attribute_map = self.class.acceptable_attribute_map
71
+ attributes = attributes.each_with_object({}) { |(k, v), h|
72
+ if (!acceptable_attribute_map.key?(k.to_sym))
73
+ fail ArgumentError, "`#{k}` is not a valid attribute in `VPNDetection::ClassDetail`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
74
+ end
75
+ h[k.to_sym] = v
76
+ }
77
+
78
+ if attributes.key?(:'provider')
79
+ self.provider = attributes[:'provider']
80
+ end
81
+
82
+ if attributes.key?(:'confidence')
83
+ self.confidence = attributes[:'confidence']
84
+ end
85
+
86
+ if attributes.key?(:'last_seen')
87
+ self.last_seen = attributes[:'last_seen']
88
+ end
89
+ end
90
+
91
+ # Show invalid properties with the reasons. Usually used together with valid?
92
+ # @return Array for valid properties with the reasons
93
+ def list_invalid_properties
94
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
95
+ invalid_properties = Array.new
96
+ invalid_properties
97
+ end
98
+
99
+ # Check to see if the all the properties in the model are valid
100
+ # @return true if the model is valid
101
+ def valid?
102
+ warn '[DEPRECATED] the `valid?` method is obsolete'
103
+ true
104
+ end
105
+
106
+ # Checks equality by comparing each attribute.
107
+ # @param [Object] Object to be compared
108
+ def ==(o)
109
+ return true if self.equal?(o)
110
+ self.class == o.class &&
111
+ provider == o.provider &&
112
+ confidence == o.confidence &&
113
+ last_seen == o.last_seen
114
+ end
115
+
116
+ # @see the `==` method
117
+ # @param [Object] Object to be compared
118
+ def eql?(o)
119
+ self == o
120
+ end
121
+
122
+ # Calculates hash code according to all attributes.
123
+ # @return [Integer] Hash code
124
+ def hash
125
+ [provider, confidence, last_seen].hash
126
+ end
127
+
128
+ # Builds the object from hash
129
+ # @param [Hash] attributes Model attributes in the form of hash
130
+ # @return [Object] Returns the model itself
131
+ def self.build_from_hash(attributes)
132
+ return nil unless attributes.is_a?(Hash)
133
+ attributes = attributes.transform_keys(&:to_sym)
134
+ transformed_hash = {}
135
+ openapi_types.each_pair do |key, type|
136
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
137
+ transformed_hash["#{key}"] = nil
138
+ elsif type =~ /\AArray<(.*)>/i
139
+ # check to ensure the input is an array given that the attribute
140
+ # is documented as an array but the input is not
141
+ if attributes[attribute_map[key]].is_a?(Array)
142
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
143
+ end
144
+ elsif !attributes[attribute_map[key]].nil?
145
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
146
+ end
147
+ end
148
+ new(transformed_hash)
149
+ end
150
+
151
+ # Returns the object in the form of hash
152
+ # @return [Hash] Returns the object in the form of hash
153
+ def to_hash
154
+ hash = {}
155
+ self.class.attribute_map.each_pair do |attr, param|
156
+ value = self.send(attr)
157
+ if value.nil?
158
+ is_nullable = self.class.openapi_nullable.include?(attr)
159
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
160
+ end
161
+
162
+ hash[param] = _to_hash(value)
163
+ end
164
+ hash
165
+ end
166
+
167
+ end
168
+
169
+ end
@@ -0,0 +1,174 @@
1
+ =begin
2
+ #VPNDetection API
3
+
4
+ #The VPNDetection API: classify any IP address, and download the datasets behind the answers. See https://docs.vpndetection.io for guides and https://github.com/vpndetection-io for the official client libraries.
5
+
6
+ The version of the OpenAPI document: 2026.09.04
7
+ Contact: support@vpndetection.io
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.25.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module VPNDetection
17
+ class DatasetChecksums < ApiModelBase
18
+ attr_accessor :md5
19
+
20
+ attr_accessor :sha1
21
+
22
+ attr_accessor :sha256
23
+
24
+ attr_accessor :sha512
25
+
26
+ # Attribute mapping from ruby-style variable name to JSON key.
27
+ def self.attribute_map
28
+ {
29
+ :'md5' => :'md5',
30
+ :'sha1' => :'sha1',
31
+ :'sha256' => :'sha256',
32
+ :'sha512' => :'sha512'
33
+ }
34
+ end
35
+
36
+ # Returns attribute mapping this model knows about
37
+ def self.acceptable_attribute_map
38
+ attribute_map
39
+ end
40
+
41
+ # Returns all the JSON keys this model knows about
42
+ def self.acceptable_attributes
43
+ acceptable_attribute_map.values
44
+ end
45
+
46
+ # Attribute type mapping.
47
+ def self.openapi_types
48
+ {
49
+ :'md5' => :'String',
50
+ :'sha1' => :'String',
51
+ :'sha256' => :'String',
52
+ :'sha512' => :'String'
53
+ }
54
+ end
55
+
56
+ # List of attributes with nullable: true
57
+ def self.openapi_nullable
58
+ Set.new([
59
+ ])
60
+ end
61
+
62
+ # Initializes the object
63
+ # @param [Hash] attributes Model attributes in the form of hash
64
+ def initialize(attributes = {})
65
+ if (!attributes.is_a?(Hash))
66
+ fail ArgumentError, "The input argument (attributes) must be a hash in `VPNDetection::DatasetChecksums` initialize method"
67
+ end
68
+
69
+ # check to see if the attribute exists and convert string to symbol for hash key
70
+ acceptable_attribute_map = self.class.acceptable_attribute_map
71
+ attributes = attributes.each_with_object({}) { |(k, v), h|
72
+ if (!acceptable_attribute_map.key?(k.to_sym))
73
+ fail ArgumentError, "`#{k}` is not a valid attribute in `VPNDetection::DatasetChecksums`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
74
+ end
75
+ h[k.to_sym] = v
76
+ }
77
+
78
+ if attributes.key?(:'md5')
79
+ self.md5 = attributes[:'md5']
80
+ end
81
+
82
+ if attributes.key?(:'sha1')
83
+ self.sha1 = attributes[:'sha1']
84
+ end
85
+
86
+ if attributes.key?(:'sha256')
87
+ self.sha256 = attributes[:'sha256']
88
+ end
89
+
90
+ if attributes.key?(:'sha512')
91
+ self.sha512 = attributes[:'sha512']
92
+ end
93
+ end
94
+
95
+ # Show invalid properties with the reasons. Usually used together with valid?
96
+ # @return Array for valid properties with the reasons
97
+ def list_invalid_properties
98
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
99
+ invalid_properties = Array.new
100
+ invalid_properties
101
+ end
102
+
103
+ # Check to see if the all the properties in the model are valid
104
+ # @return true if the model is valid
105
+ def valid?
106
+ warn '[DEPRECATED] the `valid?` method is obsolete'
107
+ true
108
+ end
109
+
110
+ # Checks equality by comparing each attribute.
111
+ # @param [Object] Object to be compared
112
+ def ==(o)
113
+ return true if self.equal?(o)
114
+ self.class == o.class &&
115
+ md5 == o.md5 &&
116
+ sha1 == o.sha1 &&
117
+ sha256 == o.sha256 &&
118
+ sha512 == o.sha512
119
+ end
120
+
121
+ # @see the `==` method
122
+ # @param [Object] Object to be compared
123
+ def eql?(o)
124
+ self == o
125
+ end
126
+
127
+ # Calculates hash code according to all attributes.
128
+ # @return [Integer] Hash code
129
+ def hash
130
+ [md5, sha1, sha256, sha512].hash
131
+ end
132
+
133
+ # Builds the object from hash
134
+ # @param [Hash] attributes Model attributes in the form of hash
135
+ # @return [Object] Returns the model itself
136
+ def self.build_from_hash(attributes)
137
+ return nil unless attributes.is_a?(Hash)
138
+ attributes = attributes.transform_keys(&:to_sym)
139
+ transformed_hash = {}
140
+ openapi_types.each_pair do |key, type|
141
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
142
+ transformed_hash["#{key}"] = nil
143
+ elsif type =~ /\AArray<(.*)>/i
144
+ # check to ensure the input is an array given that the attribute
145
+ # is documented as an array but the input is not
146
+ if attributes[attribute_map[key]].is_a?(Array)
147
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
148
+ end
149
+ elsif !attributes[attribute_map[key]].nil?
150
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
151
+ end
152
+ end
153
+ new(transformed_hash)
154
+ end
155
+
156
+ # Returns the object in the form of hash
157
+ # @return [Hash] Returns the object in the form of hash
158
+ def to_hash
159
+ hash = {}
160
+ self.class.attribute_map.each_pair do |attr, param|
161
+ value = self.send(attr)
162
+ if value.nil?
163
+ is_nullable = self.class.openapi_nullable.include?(attr)
164
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
165
+ end
166
+
167
+ hash[param] = _to_hash(value)
168
+ end
169
+ hash
170
+ end
171
+
172
+ end
173
+
174
+ end
@@ -0,0 +1,216 @@
1
+ =begin
2
+ #VPNDetection API
3
+
4
+ #The VPNDetection API: classify any IP address, and download the datasets behind the answers. See https://docs.vpndetection.io for guides and https://github.com/vpndetection-io for the official client libraries.
5
+
6
+ The version of the OpenAPI document: 2026.09.04
7
+ Contact: support@vpndetection.io
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.25.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module VPNDetection
17
+ class DatasetChecksumsResponse < ApiModelBase
18
+ attr_accessor :id
19
+
20
+ attr_accessor :format
21
+
22
+ attr_accessor :checksums
23
+
24
+ # Attribute mapping from ruby-style variable name to JSON key.
25
+ def self.attribute_map
26
+ {
27
+ :'id' => :'id',
28
+ :'format' => :'format',
29
+ :'checksums' => :'checksums'
30
+ }
31
+ end
32
+
33
+ # Returns attribute mapping this model knows about
34
+ def self.acceptable_attribute_map
35
+ attribute_map
36
+ end
37
+
38
+ # Returns all the JSON keys this model knows about
39
+ def self.acceptable_attributes
40
+ acceptable_attribute_map.values
41
+ end
42
+
43
+ # Attribute type mapping.
44
+ def self.openapi_types
45
+ {
46
+ :'id' => :'String',
47
+ :'format' => :'String',
48
+ :'checksums' => :'DatasetChecksums'
49
+ }
50
+ end
51
+
52
+ # List of attributes with nullable: true
53
+ def self.openapi_nullable
54
+ Set.new([
55
+ ])
56
+ end
57
+
58
+ # Initializes the object
59
+ # @param [Hash] attributes Model attributes in the form of hash
60
+ def initialize(attributes = {})
61
+ if (!attributes.is_a?(Hash))
62
+ fail ArgumentError, "The input argument (attributes) must be a hash in `VPNDetection::DatasetChecksumsResponse` initialize method"
63
+ end
64
+
65
+ # check to see if the attribute exists and convert string to symbol for hash key
66
+ acceptable_attribute_map = self.class.acceptable_attribute_map
67
+ attributes = attributes.each_with_object({}) { |(k, v), h|
68
+ if (!acceptable_attribute_map.key?(k.to_sym))
69
+ fail ArgumentError, "`#{k}` is not a valid attribute in `VPNDetection::DatasetChecksumsResponse`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
70
+ end
71
+ h[k.to_sym] = v
72
+ }
73
+
74
+ if attributes.key?(:'id')
75
+ self.id = attributes[:'id']
76
+ else
77
+ self.id = nil
78
+ end
79
+
80
+ if attributes.key?(:'format')
81
+ self.format = attributes[:'format']
82
+ else
83
+ self.format = nil
84
+ end
85
+
86
+ if attributes.key?(:'checksums')
87
+ self.checksums = attributes[:'checksums']
88
+ else
89
+ self.checksums = nil
90
+ end
91
+ end
92
+
93
+ # Show invalid properties with the reasons. Usually used together with valid?
94
+ # @return Array for valid properties with the reasons
95
+ def list_invalid_properties
96
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
97
+ invalid_properties = Array.new
98
+ if @id.nil?
99
+ invalid_properties.push('invalid value for "id", id cannot be nil.')
100
+ end
101
+
102
+ if @format.nil?
103
+ invalid_properties.push('invalid value for "format", format cannot be nil.')
104
+ end
105
+
106
+ if @checksums.nil?
107
+ invalid_properties.push('invalid value for "checksums", checksums cannot be nil.')
108
+ end
109
+
110
+ invalid_properties
111
+ end
112
+
113
+ # Check to see if the all the properties in the model are valid
114
+ # @return true if the model is valid
115
+ def valid?
116
+ warn '[DEPRECATED] the `valid?` method is obsolete'
117
+ return false if @id.nil?
118
+ return false if @format.nil?
119
+ return false if @checksums.nil?
120
+ true
121
+ end
122
+
123
+ # Custom attribute writer method with validation
124
+ # @param [Object] id Value to be assigned
125
+ def id=(id)
126
+ if id.nil?
127
+ fail ArgumentError, 'id cannot be nil'
128
+ end
129
+
130
+ @id = id
131
+ end
132
+
133
+ # Custom attribute writer method with validation
134
+ # @param [Object] format Value to be assigned
135
+ def format=(format)
136
+ if format.nil?
137
+ fail ArgumentError, 'format cannot be nil'
138
+ end
139
+
140
+ @format = format
141
+ end
142
+
143
+ # Custom attribute writer method with validation
144
+ # @param [Object] checksums Value to be assigned
145
+ def checksums=(checksums)
146
+ if checksums.nil?
147
+ fail ArgumentError, 'checksums cannot be nil'
148
+ end
149
+
150
+ @checksums = checksums
151
+ end
152
+
153
+ # Checks equality by comparing each attribute.
154
+ # @param [Object] Object to be compared
155
+ def ==(o)
156
+ return true if self.equal?(o)
157
+ self.class == o.class &&
158
+ id == o.id &&
159
+ format == o.format &&
160
+ checksums == o.checksums
161
+ end
162
+
163
+ # @see the `==` method
164
+ # @param [Object] Object to be compared
165
+ def eql?(o)
166
+ self == o
167
+ end
168
+
169
+ # Calculates hash code according to all attributes.
170
+ # @return [Integer] Hash code
171
+ def hash
172
+ [id, format, checksums].hash
173
+ end
174
+
175
+ # Builds the object from hash
176
+ # @param [Hash] attributes Model attributes in the form of hash
177
+ # @return [Object] Returns the model itself
178
+ def self.build_from_hash(attributes)
179
+ return nil unless attributes.is_a?(Hash)
180
+ attributes = attributes.transform_keys(&:to_sym)
181
+ transformed_hash = {}
182
+ openapi_types.each_pair do |key, type|
183
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
184
+ transformed_hash["#{key}"] = nil
185
+ elsif type =~ /\AArray<(.*)>/i
186
+ # check to ensure the input is an array given that the attribute
187
+ # is documented as an array but the input is not
188
+ if attributes[attribute_map[key]].is_a?(Array)
189
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
190
+ end
191
+ elsif !attributes[attribute_map[key]].nil?
192
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
193
+ end
194
+ end
195
+ new(transformed_hash)
196
+ end
197
+
198
+ # Returns the object in the form of hash
199
+ # @return [Hash] Returns the object in the form of hash
200
+ def to_hash
201
+ hash = {}
202
+ self.class.attribute_map.each_pair do |attr, param|
203
+ value = self.send(attr)
204
+ if value.nil?
205
+ is_nullable = self.class.openapi_nullable.include?(attr)
206
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
207
+ end
208
+
209
+ hash[param] = _to_hash(value)
210
+ end
211
+ hash
212
+ end
213
+
214
+ end
215
+
216
+ end