webscraping_ai 3.2.0 → 4.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.
@@ -1,394 +0,0 @@
1
- =begin
2
- #WebScraping.AI
3
-
4
- #WebScraping.AI scraping API provides LLM-powered tools with Chromium JavaScript rendering, rotating proxies, and built-in HTML parsing.
5
-
6
- The version of the OpenAPI document: 3.2.0
7
- Contact: support@webscraping.ai
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.11.0
10
-
11
- =end
12
-
13
- require 'date'
14
- require 'json'
15
- require 'logger'
16
- require 'tempfile'
17
- require 'time'
18
- require 'typhoeus'
19
-
20
-
21
- module WebScrapingAI
22
- class ApiClient
23
- # The Configuration object holding settings to be used in the API client.
24
- attr_accessor :config
25
-
26
- # Defines the headers to be used in HTTP requests of all API calls by default.
27
- #
28
- # @return [Hash]
29
- attr_accessor :default_headers
30
-
31
- # Initializes the ApiClient
32
- # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
33
- def initialize(config = Configuration.default)
34
- @config = config
35
- @user_agent = "OpenAPI-Generator/#{VERSION}/ruby"
36
- @default_headers = {
37
- 'Content-Type' => 'application/json',
38
- 'User-Agent' => @user_agent
39
- }
40
- end
41
-
42
- def self.default
43
- @@default ||= ApiClient.new
44
- end
45
-
46
- # Call an API with given options.
47
- #
48
- # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
49
- # the data deserialized from response body (may be a Tempfile or nil), response status code and response headers.
50
- def call_api(http_method, path, opts = {})
51
- request = build_request(http_method, path, opts)
52
- tempfile = download_file(request) if opts[:return_type] == 'File'
53
- response = request.run
54
-
55
- if @config.debugging
56
- @config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
57
- end
58
-
59
- unless response.success?
60
- if response.timed_out?
61
- fail ApiError.new('Connection timed out')
62
- elsif response.code == 0
63
- # Errors from libcurl will be made visible here
64
- fail ApiError.new(:code => 0,
65
- :message => response.return_message)
66
- else
67
- fail ApiError.new(:code => response.code,
68
- :response_headers => response.headers,
69
- :response_body => response.body),
70
- response.status_message
71
- end
72
- end
73
-
74
- if opts[:return_type] == 'File'
75
- data = tempfile
76
- elsif opts[:return_type]
77
- data = deserialize(response, opts[:return_type])
78
- else
79
- data = nil
80
- end
81
- return data, response.code, response.headers
82
- end
83
-
84
- # Builds the HTTP request
85
- #
86
- # @param [String] http_method HTTP method/verb (e.g. POST)
87
- # @param [String] path URL path (e.g. /account/new)
88
- # @option opts [Hash] :header_params Header parameters
89
- # @option opts [Hash] :query_params Query parameters
90
- # @option opts [Hash] :form_params Query parameters
91
- # @option opts [Object] :body HTTP body (JSON/XML)
92
- # @return [Typhoeus::Request] A Typhoeus Request
93
- def build_request(http_method, path, opts = {})
94
- url = build_request_url(path, opts)
95
- http_method = http_method.to_sym.downcase
96
-
97
- header_params = @default_headers.merge(opts[:header_params] || {})
98
- query_params = opts[:query_params] || {}
99
- form_params = opts[:form_params] || {}
100
- follow_location = opts[:follow_location] || true
101
-
102
- update_params_for_auth! header_params, query_params, opts[:auth_names]
103
-
104
- # set ssl_verifyhosts option based on @config.verify_ssl_host (true/false)
105
- _verify_ssl_host = @config.verify_ssl_host ? 2 : 0
106
-
107
- req_opts = {
108
- :method => http_method,
109
- :headers => header_params,
110
- :params => query_params,
111
- :params_encoding => @config.params_encoding,
112
- :timeout => @config.timeout,
113
- :ssl_verifypeer => @config.verify_ssl,
114
- :ssl_verifyhost => _verify_ssl_host,
115
- :sslcert => @config.cert_file,
116
- :sslkey => @config.key_file,
117
- :verbose => @config.debugging,
118
- :followlocation => follow_location
119
- }
120
-
121
- # set custom cert, if provided
122
- req_opts[:cainfo] = @config.ssl_ca_cert if @config.ssl_ca_cert
123
-
124
- if [:post, :patch, :put, :delete].include?(http_method)
125
- req_body = build_request_body(header_params, form_params, opts[:body])
126
- req_opts.update :body => req_body
127
- if @config.debugging
128
- @config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
129
- end
130
- end
131
-
132
- Typhoeus::Request.new(url, req_opts)
133
- end
134
-
135
- # Builds the HTTP request body
136
- #
137
- # @param [Hash] header_params Header parameters
138
- # @param [Hash] form_params Query parameters
139
- # @param [Object] body HTTP body (JSON/XML)
140
- # @return [String] HTTP body data in the form of string
141
- def build_request_body(header_params, form_params, body)
142
- # http form
143
- if header_params['Content-Type'] == 'application/x-www-form-urlencoded' ||
144
- header_params['Content-Type'] == 'multipart/form-data'
145
- data = {}
146
- form_params.each do |key, value|
147
- case value
148
- when ::File, ::Array, nil
149
- # let typhoeus handle File, Array and nil parameters
150
- data[key] = value
151
- else
152
- data[key] = value.to_s
153
- end
154
- end
155
- elsif body
156
- data = body.is_a?(String) ? body : body.to_json
157
- else
158
- data = nil
159
- end
160
- data
161
- end
162
-
163
- # Save response body into a file in (the defined) temporary folder, using the filename
164
- # from the "Content-Disposition" header if provided, otherwise a random filename.
165
- # The response body is written to the file in chunks in order to handle files which
166
- # size is larger than maximum Ruby String or even larger than the maximum memory a Ruby
167
- # process can use.
168
- #
169
- # @see Configuration#temp_folder_path
170
- #
171
- # @return [Tempfile] the tempfile generated
172
- def download_file(request)
173
- tempfile = nil
174
- encoding = nil
175
- request.on_headers do |response|
176
- content_disposition = response.headers['Content-Disposition']
177
- if content_disposition && content_disposition =~ /filename=/i
178
- filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
179
- prefix = sanitize_filename(filename)
180
- else
181
- prefix = 'download-'
182
- end
183
- prefix = prefix + '-' unless prefix.end_with?('-')
184
- encoding = response.body.encoding
185
- tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
186
- end
187
- request.on_body do |chunk|
188
- chunk.force_encoding(encoding)
189
- tempfile.write(chunk)
190
- end
191
- # run the request to ensure the tempfile is created successfully before returning it
192
- request.run
193
- if tempfile
194
- tempfile.close
195
- @config.logger.info "Temp file written to #{tempfile.path}, please copy the file to a proper folder "\
196
- "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
197
- "will be deleted automatically with GC. It's also recommended to delete the temp file "\
198
- "explicitly with `tempfile.delete`"
199
- else
200
- fail ApiError.new("Failed to create the tempfile based on the HTTP response from the server: #{request.inspect}")
201
- end
202
-
203
- tempfile
204
- end
205
-
206
- # Check if the given MIME is a JSON MIME.
207
- # JSON MIME examples:
208
- # application/json
209
- # application/json; charset=UTF8
210
- # APPLICATION/JSON
211
- # */*
212
- # @param [String] mime MIME
213
- # @return [Boolean] True if the MIME is application/json
214
- def json_mime?(mime)
215
- (mime == '*/*') || !(mime =~ /^Application\/.*json(?!p)(;.*)?/i).nil?
216
- end
217
-
218
- # Deserialize the response to the given return type.
219
- #
220
- # @param [Response] response HTTP response
221
- # @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>"
222
- def deserialize(response, return_type)
223
- body = response.body
224
- return nil if body.nil? || body.empty?
225
-
226
- # return response body directly for String return type
227
- return body.to_s if return_type == 'String'
228
-
229
- # ensuring a default content type
230
- content_type = response.headers['Content-Type'] || 'application/json'
231
-
232
- fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
233
-
234
- begin
235
- data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
236
- rescue JSON::ParserError => e
237
- if %w(String Date Time).include?(return_type)
238
- data = body
239
- else
240
- raise e
241
- end
242
- end
243
-
244
- convert_to_type data, return_type
245
- end
246
-
247
- # Convert data to the given return type.
248
- # @param [Object] data Data to be converted
249
- # @param [String] return_type Return type
250
- # @return [Mixed] Data in a particular type
251
- def convert_to_type(data, return_type)
252
- return nil if data.nil?
253
- case return_type
254
- when 'String'
255
- data.to_s
256
- when 'Integer'
257
- data.to_i
258
- when 'Float'
259
- data.to_f
260
- when 'Boolean'
261
- data == true
262
- when 'Time'
263
- # parse date time (expecting ISO 8601 format)
264
- Time.parse data
265
- when 'Date'
266
- # parse date time (expecting ISO 8601 format)
267
- Date.parse data
268
- when 'Object'
269
- # generic object (usually a Hash), return directly
270
- data
271
- when /\AArray<(.+)>\z/
272
- # e.g. Array<Pet>
273
- sub_type = $1
274
- data.map { |item| convert_to_type(item, sub_type) }
275
- when /\AHash\<String, (.+)\>\z/
276
- # e.g. Hash<String, Integer>
277
- sub_type = $1
278
- {}.tap do |hash|
279
- data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
280
- end
281
- else
282
- # models (e.g. Pet) or oneOf
283
- klass = WebScrapingAI.const_get(return_type)
284
- klass.respond_to?(:openapi_one_of) ? klass.build(data) : klass.build_from_hash(data)
285
- end
286
- end
287
-
288
- # Sanitize filename by removing path.
289
- # e.g. ../../sun.gif becomes sun.gif
290
- #
291
- # @param [String] filename the filename to be sanitized
292
- # @return [String] the sanitized filename
293
- def sanitize_filename(filename)
294
- filename.split(/[\/\\]/).last
295
- end
296
-
297
- def build_request_url(path, opts = {})
298
- # Add leading and trailing slashes to path
299
- path = "/#{path}".gsub(/\/+/, '/')
300
- @config.base_url(opts[:operation]) + path
301
- end
302
-
303
- # Update header and query params based on authentication settings.
304
- #
305
- # @param [Hash] header_params Header parameters
306
- # @param [Hash] query_params Query parameters
307
- # @param [String] auth_names Authentication scheme name
308
- def update_params_for_auth!(header_params, query_params, auth_names)
309
- Array(auth_names).each do |auth_name|
310
- auth_setting = @config.auth_settings[auth_name]
311
- next unless auth_setting
312
- case auth_setting[:in]
313
- when 'header' then header_params[auth_setting[:key]] = auth_setting[:value]
314
- when 'query' then query_params[auth_setting[:key]] = auth_setting[:value]
315
- else fail ArgumentError, 'Authentication token must be in `query` or `header`'
316
- end
317
- end
318
- end
319
-
320
- # Sets user agent in HTTP header
321
- #
322
- # @param [String] user_agent User agent (e.g. openapi-generator/ruby/1.0.0)
323
- def user_agent=(user_agent)
324
- @user_agent = user_agent
325
- @default_headers['User-Agent'] = @user_agent
326
- end
327
-
328
- # Return Accept header based on an array of accepts provided.
329
- # @param [Array] accepts array for Accept
330
- # @return [String] the Accept header (e.g. application/json)
331
- def select_header_accept(accepts)
332
- return nil if accepts.nil? || accepts.empty?
333
- # use JSON when present, otherwise use all of the provided
334
- json_accept = accepts.find { |s| json_mime?(s) }
335
- json_accept || accepts.join(',')
336
- end
337
-
338
- # Return Content-Type header based on an array of content types provided.
339
- # @param [Array] content_types array for Content-Type
340
- # @return [String] the Content-Type header (e.g. application/json)
341
- def select_header_content_type(content_types)
342
- # return nil by default
343
- return if content_types.nil? || content_types.empty?
344
- # use JSON when present, otherwise use the first one
345
- json_content_type = content_types.find { |s| json_mime?(s) }
346
- json_content_type || content_types.first
347
- end
348
-
349
- # Convert object (array, hash, object, etc) to JSON string.
350
- # @param [Object] model object to be converted into JSON string
351
- # @return [String] JSON string representation of the object
352
- def object_to_http_body(model)
353
- return model if model.nil? || model.is_a?(String)
354
- local_body = nil
355
- if model.is_a?(Array)
356
- local_body = model.map { |m| object_to_hash(m) }
357
- else
358
- local_body = object_to_hash(model)
359
- end
360
- local_body.to_json
361
- end
362
-
363
- # Convert object(non-array) to hash.
364
- # @param [Object] obj object to be converted into JSON string
365
- # @return [String] JSON string representation of the object
366
- def object_to_hash(obj)
367
- if obj.respond_to?(:to_hash)
368
- obj.to_hash
369
- else
370
- obj
371
- end
372
- end
373
-
374
- # Build parameter value according to the given collection format.
375
- # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
376
- def build_collection_param(param, collection_format)
377
- case collection_format
378
- when :csv
379
- param.join(',')
380
- when :ssv
381
- param.join(' ')
382
- when :tsv
383
- param.join("\t")
384
- when :pipes
385
- param.join('|')
386
- when :multi
387
- # return the array directly as typhoeus will handle it as expected
388
- param
389
- else
390
- fail "unknown collection format: #{collection_format.inspect}"
391
- end
392
- end
393
- end
394
- end
@@ -1,58 +0,0 @@
1
- =begin
2
- #WebScraping.AI
3
-
4
- #WebScraping.AI scraping API provides LLM-powered tools with Chromium JavaScript rendering, rotating proxies, and built-in HTML parsing.
5
-
6
- The version of the OpenAPI document: 3.2.0
7
- Contact: support@webscraping.ai
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.11.0
10
-
11
- =end
12
-
13
- module WebScrapingAI
14
- class ApiError < StandardError
15
- attr_reader :code, :response_headers, :response_body
16
-
17
- # Usage examples:
18
- # ApiError.new
19
- # ApiError.new("message")
20
- # ApiError.new(:code => 500, :response_headers => {}, :response_body => "")
21
- # ApiError.new(:code => 404, :message => "Not Found")
22
- def initialize(arg = nil)
23
- if arg.is_a? Hash
24
- if arg.key?(:message) || arg.key?('message')
25
- super(arg[:message] || arg['message'])
26
- else
27
- super arg
28
- end
29
-
30
- arg.each do |k, v|
31
- instance_variable_set "@#{k}", v
32
- end
33
- else
34
- super arg
35
- @message = arg
36
- end
37
- end
38
-
39
- # Override to_s to display a friendly error message
40
- def to_s
41
- message
42
- end
43
-
44
- def message
45
- if @message.nil?
46
- msg = "Error message: the server returns an error"
47
- else
48
- msg = @message
49
- end
50
-
51
- msg += "\nHTTP status code: #{code}" if code
52
- msg += "\nResponse headers: #{response_headers}" if response_headers
53
- msg += "\nResponse body: #{response_body}" if response_body
54
-
55
- msg
56
- end
57
- end
58
- end
@@ -1,245 +0,0 @@
1
- =begin
2
- #WebScraping.AI
3
-
4
- #WebScraping.AI scraping API provides LLM-powered tools with Chromium JavaScript rendering, rotating proxies, and built-in HTML parsing.
5
-
6
- The version of the OpenAPI document: 3.2.0
7
- Contact: support@webscraping.ai
8
- Generated by: https://openapi-generator.tech
9
- Generator version: 7.11.0
10
-
11
- =end
12
-
13
- require 'date'
14
- require 'time'
15
-
16
- module WebScrapingAI
17
- class Account
18
- # Your account email
19
- attr_accessor :email
20
-
21
- # Remaining API credits quota
22
- attr_accessor :remaining_api_calls
23
-
24
- # Next billing cycle start time (UNIX timestamp)
25
- attr_accessor :resets_at
26
-
27
- # Remaining concurrent requests
28
- attr_accessor :remaining_concurrency
29
-
30
- # Attribute mapping from ruby-style variable name to JSON key.
31
- def self.attribute_map
32
- {
33
- :'email' => :'email',
34
- :'remaining_api_calls' => :'remaining_api_calls',
35
- :'resets_at' => :'resets_at',
36
- :'remaining_concurrency' => :'remaining_concurrency'
37
- }
38
- end
39
-
40
- # Returns all the JSON keys this model knows about
41
- def self.acceptable_attributes
42
- attribute_map.values
43
- end
44
-
45
- # Attribute type mapping.
46
- def self.openapi_types
47
- {
48
- :'email' => :'String',
49
- :'remaining_api_calls' => :'Integer',
50
- :'resets_at' => :'Integer',
51
- :'remaining_concurrency' => :'Integer'
52
- }
53
- end
54
-
55
- # List of attributes with nullable: true
56
- def self.openapi_nullable
57
- Set.new([
58
- ])
59
- end
60
-
61
- # Initializes the object
62
- # @param [Hash] attributes Model attributes in the form of hash
63
- def initialize(attributes = {})
64
- if (!attributes.is_a?(Hash))
65
- fail ArgumentError, "The input argument (attributes) must be a hash in `WebScrapingAI::Account` initialize method"
66
- end
67
-
68
- # check to see if the attribute exists and convert string to symbol for hash key
69
- attributes = attributes.each_with_object({}) { |(k, v), h|
70
- if (!self.class.attribute_map.key?(k.to_sym))
71
- fail ArgumentError, "`#{k}` is not a valid attribute in `WebScrapingAI::Account`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
72
- end
73
- h[k.to_sym] = v
74
- }
75
-
76
- if attributes.key?(:'email')
77
- self.email = attributes[:'email']
78
- end
79
-
80
- if attributes.key?(:'remaining_api_calls')
81
- self.remaining_api_calls = attributes[:'remaining_api_calls']
82
- end
83
-
84
- if attributes.key?(:'resets_at')
85
- self.resets_at = attributes[:'resets_at']
86
- end
87
-
88
- if attributes.key?(:'remaining_concurrency')
89
- self.remaining_concurrency = attributes[:'remaining_concurrency']
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
- invalid_properties
99
- end
100
-
101
- # Check to see if the all the properties in the model are valid
102
- # @return true if the model is valid
103
- def valid?
104
- warn '[DEPRECATED] the `valid?` method is obsolete'
105
- true
106
- end
107
-
108
- # Checks equality by comparing each attribute.
109
- # @param [Object] Object to be compared
110
- def ==(o)
111
- return true if self.equal?(o)
112
- self.class == o.class &&
113
- email == o.email &&
114
- remaining_api_calls == o.remaining_api_calls &&
115
- resets_at == o.resets_at &&
116
- remaining_concurrency == o.remaining_concurrency
117
- end
118
-
119
- # @see the `==` method
120
- # @param [Object] Object to be compared
121
- def eql?(o)
122
- self == o
123
- end
124
-
125
- # Calculates hash code according to all attributes.
126
- # @return [Integer] Hash code
127
- def hash
128
- [email, remaining_api_calls, resets_at, remaining_concurrency].hash
129
- end
130
-
131
- # Builds the object from hash
132
- # @param [Hash] attributes Model attributes in the form of hash
133
- # @return [Object] Returns the model itself
134
- def self.build_from_hash(attributes)
135
- return nil unless attributes.is_a?(Hash)
136
- attributes = attributes.transform_keys(&:to_sym)
137
- transformed_hash = {}
138
- openapi_types.each_pair do |key, type|
139
- if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
140
- transformed_hash["#{key}"] = nil
141
- elsif type =~ /\AArray<(.*)>/i
142
- # check to ensure the input is an array given that the attribute
143
- # is documented as an array but the input is not
144
- if attributes[attribute_map[key]].is_a?(Array)
145
- transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
146
- end
147
- elsif !attributes[attribute_map[key]].nil?
148
- transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
149
- end
150
- end
151
- new(transformed_hash)
152
- end
153
-
154
- # Deserializes the data based on type
155
- # @param string type Data type
156
- # @param string value Value to be deserialized
157
- # @return [Object] Deserialized data
158
- def self._deserialize(type, value)
159
- case type.to_sym
160
- when :Time
161
- Time.parse(value)
162
- when :Date
163
- Date.parse(value)
164
- when :String
165
- value.to_s
166
- when :Integer
167
- value.to_i
168
- when :Float
169
- value.to_f
170
- when :Boolean
171
- if value.to_s =~ /\A(true|t|yes|y|1)\z/i
172
- true
173
- else
174
- false
175
- end
176
- when :Object
177
- # generic object (usually a Hash), return directly
178
- value
179
- when /\AArray<(?<inner_type>.+)>\z/
180
- inner_type = Regexp.last_match[:inner_type]
181
- value.map { |v| _deserialize(inner_type, v) }
182
- when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
183
- k_type = Regexp.last_match[:k_type]
184
- v_type = Regexp.last_match[:v_type]
185
- {}.tap do |hash|
186
- value.each do |k, v|
187
- hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
188
- end
189
- end
190
- else # model
191
- # models (e.g. Pet) or oneOf
192
- klass = WebScrapingAI.const_get(type)
193
- klass.respond_to?(:openapi_any_of) || klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
194
- end
195
- end
196
-
197
- # Returns the string representation of the object
198
- # @return [String] String presentation of the object
199
- def to_s
200
- to_hash.to_s
201
- end
202
-
203
- # to_body is an alias to to_hash (backward compatibility)
204
- # @return [Hash] Returns the object in the form of hash
205
- def to_body
206
- to_hash
207
- end
208
-
209
- # Returns the object in the form of hash
210
- # @return [Hash] Returns the object in the form of hash
211
- def to_hash
212
- hash = {}
213
- self.class.attribute_map.each_pair do |attr, param|
214
- value = self.send(attr)
215
- if value.nil?
216
- is_nullable = self.class.openapi_nullable.include?(attr)
217
- next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
218
- end
219
-
220
- hash[param] = _to_hash(value)
221
- end
222
- hash
223
- end
224
-
225
- # Outputs non-array value in the form of hash
226
- # For object, use to_hash. Otherwise, just return the value
227
- # @param [Object] value Any valid value
228
- # @return [Hash] Returns the value in the form of hash
229
- def _to_hash(value)
230
- if value.is_a?(Array)
231
- value.compact.map { |v| _to_hash(v) }
232
- elsif value.is_a?(Hash)
233
- {}.tap do |hash|
234
- value.each { |k, v| hash[k] = _to_hash(v) }
235
- end
236
- elsif value.respond_to? :to_hash
237
- value.to_hash
238
- else
239
- value
240
- end
241
- end
242
-
243
- end
244
-
245
- end