hybiscus_pdf_report 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a8661a6c187761886b7a0e41f3112957a31eff162cc42c3167bfeb2be793dcc4
4
+ data.tar.gz: 36465eed4413bcaa80b5d05893cd24cdeea139c1d1795b7526dd03c9d11b6de4
5
+ SHA512:
6
+ metadata.gz: '0463680072442b123263ea823606daae30a64489babe71db6078731645a42d12847df20f390d16ddc09becc8400b48490d009ccf2208e5faaf9c108e52de7a64'
7
+ data.tar.gz: 690d63a2dd4e4414fc20e526b260c284560d393a33d5c6038f1f708812bddb24ac823c07710a315abc714b9049b7a09d07c2b57bb688cdd4c63b1eedc70fed97
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,15 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Layout/LineLength:
13
+ Max: 120
14
+
15
+
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-11-23
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Philipp Baumann
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
13
+ all 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
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # Hybiscus API Ruby Wrapper
2
+
3
+ This is the API Wrapper for the Hybiscus REST API
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'hybiscus_pdf_report'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install hybiscus_pdf_report
20
+
21
+ ## Usage
22
+ ### Configure the client
23
+ The Gem is configured by default to work with the public platform of Hybiscus at
24
+ * API: `https://api.hybiscus.dev/api/v1/`
25
+
26
+ ### Instantiate a client
27
+ ```ruby
28
+ # To connect to the default SaaS Instance of Adnexo: https://prod.api.ax-track.ch/api/v1
29
+ client = HybiscusPdfReport::Client.new(api_key: your_api_key)
30
+ # Or if you have set ENV['HIBISCUS_API_KEY'] set, you don't need to pass in the api key.
31
+ client = HybiscusPdfReport::Client.new
32
+
33
+ # The default time out is 10 seconds. To change the value, pass in the parameter
34
+ client = HybiscusPdfReport::Client.new(api_key: your_api_key, timeout: 20)
35
+
36
+ # If you have a Hybiscus in your private cloud and have a different URL, you can pass the URL as a parameter
37
+ client = HybiscusPdfReport::Client.new(hibiskus_api_url: #URL#)
38
+ # You can also set the URL as ENV["HIBISCUS_API_URL"]
39
+ ```
40
+
41
+ ## Accessing the Endpoints
42
+ ### Submit to 'build-report'
43
+ ```ruby
44
+ response = client.request.build_report(json)
45
+ ```
46
+ The Response object is returned, containint the `task_id` AND the task `status`. These information are also stored and can be accessed as follows
47
+ ```ruby
48
+ response = client.request.last_task_id
49
+ response = client.request.last_task_status
50
+ ```
51
+
52
+ ### Submit to 'preview-report'
53
+ ```ruby
54
+ response = client.request.preview_report(json)
55
+ ```
56
+ ### Submit to 'get-task-status'
57
+ ```ruby
58
+ response = client.request.get_task_status(task_id)
59
+ # if you previously already made a request, you can get the status of the last task directly without having to store and pass the task_id
60
+ response = client.request.get_last_task_status
61
+ ```
62
+
63
+ ### Submit to 'get-report'
64
+ ```ruby
65
+ response = client.request.get_report(task_id)
66
+ # if you previously already made a request, you can get the status of the last task directly without having to store and pass the task_id
67
+ response = client.request.get_last_report
68
+ ```
69
+
70
+ ## Development
71
+
72
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
73
+
74
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
75
+
76
+ To test the application in the console
77
+ ```ruby
78
+ client = HybiscusPdfReport::Client.new(api_key: _YOUR_API_KEY_)
79
+ # to get a list of all trackers (just as an example)
80
+ client.trackers.all
81
+ ```
82
+
83
+ ## Contributing
84
+
85
+ Bug reports and pull requests are welcome on GitHub at https://github.com/Timly-Software-AG/HybiscusPdfReportRubyGem.
86
+
87
+ ## License
88
+
89
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
90
+
91
+ ## Open development
92
+ * Pagination for development
93
+
94
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path("lib", __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require_relative "lib/hybiscus_pdf_report/version"
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "hybiscus_pdf_report"
9
+ spec.version = HybiscusPdfReport::VERSION
10
+ spec.authors = ["Philipp Baumann"]
11
+ spec.email = ["philipp.baumann@timly.com"]
12
+
13
+ spec.summary = "API Wrapper for the Hybiscus.dev PDF reports generator"
14
+ spec.description = "This gem provides a simple access using Ruby to the Hybiscus.dev PDF reports generator API."
15
+ spec.homepage = "https://hybiscus.dev/"
16
+ spec.license = "MIT"
17
+ spec.required_ruby_version = ">= 3.0.0"
18
+
19
+ spec.metadata["source_code_uri"] = "https://github.com/Timly-Software-AG/HybiscusPdfReportRubyGem"
20
+ # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
21
+
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(__dir__) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (File.expand_path(f) == __FILE__) ||
26
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .gitlab-ci.yml appveyor Gemfile])
27
+ end
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+
33
+ spec.add_dependency "faraday", "~> 1.10"
34
+ # base64 will no longer be part of the default gems after Ruby 3.4.0. Adding base64 gemspec.
35
+ spec.add_dependency "base64"
36
+ spec.add_development_dependency "pry"
37
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "faraday"
4
+ require_relative "errors"
5
+
6
+ module HybiscusPdfReport
7
+ # Client handling the Faraday connection to the Hybiscus PDF Reports API
8
+ class Client
9
+ attr_reader :api_key, :hibiskus_api_url, :adapter, :last_request, :email
10
+
11
+ BASE_URL_API = "https://api.hybiscus.dev/api/v1/"
12
+
13
+ def initialize(api_key: ENV["HIBISCUS_API_KEY"],
14
+ hibiskus_api_url: ENV["HIBISCUS_API_URL"],
15
+ timeout: nil,
16
+ adapter: nil,
17
+ stubs: nil)
18
+ @api_key = api_key&.strip
19
+ # default to the main Adnexo production account
20
+ raise ArgumentError, "No API key defined. Check documentation on how to set the API key." if @api_key.nil?
21
+
22
+ @hibiskus_api_url = hibiskus_api_url || BASE_URL_API
23
+ # default to the main Adnexo production account
24
+ @timeout = timeout
25
+ # param made available for testing purposes: In the rspec tests the following adapter is used: :test
26
+ # https://www.rubydoc.info/gems/faraday/Faraday/Adapter/Test
27
+ @adapter = adapter || Faraday.default_adapter
28
+ @stubs = stubs
29
+ end
30
+
31
+ def request
32
+ @request ||= Request.new(self)
33
+ end
34
+
35
+ def connection(header = {})
36
+ @connection ||= build_connection(header)
37
+ end
38
+
39
+ private
40
+
41
+ # rubocop:disable Metrics/AbcSize
42
+ def build_connection(header)
43
+ Faraday.new do |conn|
44
+ conn.url_prefix = hibiskus_api_url ## typically the base URL
45
+ conn.request :json
46
+ conn.response :json, content_type: "application/json"
47
+ conn.adapter adapter, @stubs
48
+ conn.headers["X-API-KEY"] = api_key.to_s unless api_key.empty?
49
+ # adds additional header information to the connection
50
+ header.each { |key, value| conn.headers[key] = value }
51
+ conn.options.timeout = @timeout || 10
52
+ end
53
+ end
54
+ # rubocop:enable Metrics/AbcSize
55
+ end
56
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Definition of all errors that can be raised by the Hybiscus PDF Reports API
4
+ module HybiscusPdfReport
5
+ ApiError = Class.new(StandardError)
6
+ BadRequestError = Class.new(ApiError)
7
+ UnauthorizedError = Class.new(ApiError)
8
+ PaymentRequiredError = Class.new(ApiError)
9
+ ForbiddenError = Class.new(ApiError)
10
+ ApiRequestsQuotaReachedError = Class.new(ApiError)
11
+ NotFoundError = Class.new(ApiError)
12
+ UnprocessableEntityError = Class.new(ApiError)
13
+ RateLimitError = Class.new(ApiError)
14
+
15
+ HTTP_OK_CODE = 200
16
+
17
+ HTTP_BAD_REQUEST_CODE = 400
18
+ HTTP_UNAUTHORIZED_CODE = 401
19
+ HTTP_PAYMENT_REQUIRED_CODE = 402
20
+ HTTP_FORBIDDEN_CODE = 403
21
+ HTTP_NOT_FOUND_CODE = 404
22
+ HTTP_UNPROCESSABLE_CONTENT_CODE = 422
23
+ HTTP_UNPROCESSABLE_ENTITY_CODE = 429
24
+ HTTP_SERVICE_UNAVAILABLE_CODE = 503
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ostruct"
4
+
5
+ module HybiscusPdfReport
6
+ # Base class for all objects returned by the Hybiscus PDF Reports API
7
+ class Object
8
+ def initialize(attributes)
9
+ @attributes = OpenStruct.new(attributes)
10
+ end
11
+
12
+ def method_missing(method, *args, &block)
13
+ attribute = @attributes.send(method, *args, &block)
14
+
15
+ return super if attribute.nil?
16
+ return Object.new(attribute) if attribute.is_a?(Hash)
17
+
18
+ attribute
19
+ end
20
+
21
+ def respond_to_missing?(method, _include_private = false)
22
+ @attributes.respond_to? method
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HybiscusPdfReport
4
+ class Response < Object
5
+ end
6
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "base64"
5
+
6
+ module HybiscusPdfReport
7
+ # Request Handler with the individual endpoints handling the communication with the Hybiscus PDF Reports API
8
+ class Request
9
+ attr_reader :client, :response, :last_request_time_counting_against_rate_limit, :last_task_id, :last_task_status,
10
+ :remaining_single_page_reports, :remaining_multi_page_reports
11
+
12
+ def initialize(client)
13
+ @client = client
14
+ @response = nil
15
+ end
16
+
17
+ # rubocop: disable Naming/AccessorMethodName
18
+ # method names are inline with the Hybiscus API endpoint names. This is more explicit and easier to understand
19
+ # than following rubocop conventions.
20
+ def build_report(report_request_as_json)
21
+ response_body = request(endpoint: "build-report", http_method: :post, body: report_request_as_json)
22
+ ## HANDLE 402 RESPONSE --> PAYMENT REQUIRED
23
+ update_last_request_information
24
+
25
+ response = Response.new(response_body.merge(
26
+ remaining_single_page_reports: @response.headers["x-remaining-single-page-reports"],
27
+ remaining_multi_page_reports: @response.headers["x-remaining-multi-page-reports"]
28
+ ))
29
+
30
+ update_quota_information(response)
31
+ response
32
+ end
33
+
34
+ # POST
35
+ def preview_report(report_request_as_json)
36
+ response_body = request(endpoint: "preview-report", http_method: :post, body: report_request_as_json)
37
+ update_last_request_information
38
+ Response.new(response_body)
39
+ end
40
+
41
+ # GET
42
+ def get_task_status(task_id)
43
+ response_body = request(endpoint: "get-task-status", params: { task_id: task_id })
44
+ # The last task status is stored. If this method is called with the same task_id, the last task status is updated
45
+ # in the instance variable
46
+ @last_task_status = response.body["status"] if last_task_id == task_id
47
+ Response.new(response_body)
48
+ end
49
+
50
+ def get_last_task_status
51
+ raise ArgumentError, "No task_id available. Please call build_report or preview_report first." unless last_task_id
52
+
53
+ get_task_status(last_task_id)
54
+ end
55
+
56
+ def get_report(task_id)
57
+ response_body = request(endpoint: "get-report", http_method: :get, params: { task_id: task_id })
58
+ Response.new(satus: response.status, content: Base64.encode64(response_body))
59
+ end
60
+
61
+ def get_last_report
62
+ raise ArgumentError, "No task_id available. Please call build_report or preview_report first." unless last_task_id
63
+
64
+ get_report(last_task_id)
65
+ end
66
+
67
+ def get_remaining_quota
68
+ response_body = request(endpoint: "get-remaining-quota", http_method: :get)
69
+
70
+ Response.new response_body
71
+ end
72
+ # rubocop: enable Naming/AccessorMethodName
73
+
74
+ private
75
+
76
+ def request(endpoint:, http_method: :get, headers: {}, params: {}, body: {})
77
+ raise "Client not defined" unless defined? @client
78
+
79
+ @response = client.connection.public_send(http_method, endpoint, params.merge(body), headers)
80
+ raise_error unless response_successful? && no_json_error?
81
+
82
+ @last_request = Time.now
83
+
84
+ response.body
85
+ end
86
+
87
+ def update_last_request_information
88
+ @last_request_time_counting_against_rate_limit = Time.now
89
+ @last_task_id = response.body["task_id"]
90
+ @last_task_status = response.body["status"]
91
+ end
92
+
93
+ def update_quota_information(response_object)
94
+ @remaining_single_page_reports = response_object.remaining_single_page_reports
95
+ @remaining_multi_page_reports = response_object.remaining_multi_page_reports
96
+ end
97
+
98
+ def raise_error
99
+ pretty_print_json_response
100
+
101
+ raise error_class(response.status), "Code: #{response.status}, response: #{response.reason_phrase}"
102
+ end
103
+
104
+ # rubocop: disable Metrics/Metrics/MethodLength
105
+ def error_class(status)
106
+ case status
107
+ when HTTP_BAD_REQUEST_CODE
108
+ BadRequestError
109
+ when HTTP_UNAUTHORIZED_CODE
110
+ UnauthorizedError
111
+ when HTTP_NOT_FOUND_CODE, HTTP_FORBIDDEN_CODE
112
+ NotFoundError
113
+ when HTTP_UNPROCESSABLE_ENTITY_CODE
114
+ UnprocessableEntityError
115
+ when HTTP_PAYMENT_REQUIRED_CODE
116
+ PaymentRequiredError
117
+ when HTTP_SERVICE_UNAVAILABLE_CODE
118
+ # Hybiscus API returns 503 when the rate limit is reached
119
+ # https://hybiscus.dev/docs/api/rate-limitting
120
+ RateLimitError
121
+ else
122
+ ApiError
123
+ end
124
+ end
125
+ # rubocop: enable Metrics/Metrics/MethodLength
126
+
127
+ def response_successful?
128
+ response.status == HTTP_OK_CODE
129
+ end
130
+
131
+ def no_json_error?
132
+ response.status != HTTP_UNPROCESSABLE_CONTENT_CODE
133
+ end
134
+
135
+ def pretty_print_json_response
136
+ puts "Response Body:"
137
+ puts JSON.pretty_generate(response.body)
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HybiscusPdfReport
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "hybiscus_pdf_report/version"
4
+
5
+ # Service to interact with the Hybiscus PDF Reports API
6
+ module HybiscusPdfReport
7
+ autoload :Client, "hybiscus_pdf_report/client"
8
+ autoload :Request, "hybiscus_pdf_report/request"
9
+ autoload :Object, "hybiscus_pdf_report/object"
10
+ autoload :Response, "hybiscus_pdf_report/objects/response"
11
+ end
@@ -0,0 +1,4 @@
1
+ module HybiscusPdfReport
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hybiscus_pdf_report
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Philipp Baumann
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-12-10 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: '1.10'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: base64
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: This gem provides a simple access using Ruby to the Hybiscus.dev PDF
56
+ reports generator API.
57
+ email:
58
+ - philipp.baumann@timly.com
59
+ executables: []
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".rspec"
64
+ - ".rubocop.yml"
65
+ - CHANGELOG.md
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - hybiscus_pdf_report.gemspec
70
+ - lib/hybiscus_pdf_report.rb
71
+ - lib/hybiscus_pdf_report/client.rb
72
+ - lib/hybiscus_pdf_report/errors.rb
73
+ - lib/hybiscus_pdf_report/object.rb
74
+ - lib/hybiscus_pdf_report/objects/response.rb
75
+ - lib/hybiscus_pdf_report/request.rb
76
+ - lib/hybiscus_pdf_report/version.rb
77
+ - sig/hybiscus_pdf_report.rbs
78
+ homepage: https://hybiscus.dev/
79
+ licenses:
80
+ - MIT
81
+ metadata:
82
+ source_code_uri: https://github.com/Timly-Software-AG/HybiscusPdfReportRubyGem
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: 3.0.0
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubygems_version: 3.5.3
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: API Wrapper for the Hybiscus.dev PDF reports generator
102
+ test_files: []