mindee 2.2.0 → 3.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 (152) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +2 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +36 -0
  6. data/README.md +29 -16
  7. data/bin/mindee.rb +23 -26
  8. data/docs/code_samples/bank_account_details_v1.txt +10 -5
  9. data/docs/code_samples/bank_account_details_v2.txt +19 -0
  10. data/docs/code_samples/bank_check_v1.txt +10 -5
  11. data/docs/code_samples/carte_vitale_v1.txt +10 -5
  12. data/docs/code_samples/custom_v1.txt +19 -10
  13. data/docs/code_samples/default.txt +10 -2
  14. data/docs/code_samples/expense_receipts_v4.txt +10 -5
  15. data/docs/code_samples/expense_receipts_v5.txt +11 -6
  16. data/docs/code_samples/financial_document_v1.txt +10 -5
  17. data/docs/code_samples/idcard_fr_v1.txt +10 -5
  18. data/docs/code_samples/invoice_splitter_v1_async.txt +66 -0
  19. data/docs/code_samples/invoices_v4.txt +10 -5
  20. data/docs/code_samples/license_plates_v1.txt +10 -5
  21. data/docs/code_samples/passport_v1.txt +10 -5
  22. data/docs/code_samples/proof_of_address_v1.txt +10 -5
  23. data/docs/ruby-api-builder.md +30 -31
  24. data/docs/ruby-getting-started.md +64 -23
  25. data/docs/ruby-invoice-ocr.md +70 -59
  26. data/docs/ruby-passport-ocr.md +49 -40
  27. data/docs/ruby-receipt-ocr.md +45 -32
  28. data/lib/mindee/client.rb +150 -148
  29. data/lib/mindee/geometry/min_max.rb +23 -0
  30. data/lib/mindee/geometry/point.rb +35 -0
  31. data/lib/mindee/geometry/polygon.rb +23 -0
  32. data/lib/mindee/geometry/quadrilateral.rb +45 -0
  33. data/lib/mindee/geometry/utils.rb +81 -0
  34. data/lib/mindee/geometry.rb +5 -116
  35. data/lib/mindee/http/endpoint.rb +123 -16
  36. data/lib/mindee/http.rb +3 -0
  37. data/lib/mindee/input/sources.rb +87 -73
  38. data/lib/mindee/parsing/common/api_response.rb +109 -0
  39. data/lib/mindee/parsing/common/document.rb +48 -0
  40. data/lib/mindee/parsing/common/error.rb +24 -0
  41. data/lib/mindee/parsing/common/inference.rb +43 -0
  42. data/lib/mindee/parsing/common/ocr/mvision_v1.rb +34 -0
  43. data/lib/mindee/parsing/common/ocr/ocr.rb +169 -0
  44. data/lib/mindee/parsing/common/ocr.rb +3 -0
  45. data/lib/mindee/parsing/common/orientation.rb +26 -0
  46. data/lib/mindee/parsing/common/page.rb +40 -0
  47. data/lib/mindee/parsing/common/prediction.rb +15 -0
  48. data/lib/mindee/parsing/common/product.rb +19 -0
  49. data/lib/mindee/parsing/common.rb +10 -0
  50. data/lib/mindee/parsing/custom/classification_field.rb +28 -0
  51. data/lib/mindee/parsing/custom/list_field.rb +76 -0
  52. data/lib/mindee/parsing/custom.rb +4 -0
  53. data/lib/mindee/parsing/standard/amount_field.rb +26 -0
  54. data/lib/mindee/parsing/standard/base_field.rb +104 -0
  55. data/lib/mindee/parsing/standard/classification_field.rb +16 -0
  56. data/lib/mindee/parsing/standard/company_registration_field.rb +21 -0
  57. data/lib/mindee/parsing/standard/date_field.rb +34 -0
  58. data/lib/mindee/parsing/standard/locale_field.rb +50 -0
  59. data/lib/mindee/parsing/standard/payment_details_field.rb +42 -0
  60. data/lib/mindee/parsing/standard/position_field.rb +44 -0
  61. data/lib/mindee/parsing/standard/tax_field.rb +108 -0
  62. data/lib/mindee/parsing/standard/text_field.rb +16 -0
  63. data/lib/mindee/parsing/standard.rb +12 -0
  64. data/lib/mindee/parsing.rb +3 -2
  65. data/lib/mindee/{input → pdf}/pdf_processing.rb +4 -32
  66. data/lib/mindee/pdf/pdf_tools.rb +34 -0
  67. data/lib/mindee/pdf.rb +3 -0
  68. data/lib/mindee/product/.rubocop.yml +5 -0
  69. data/lib/mindee/product/custom/custom_v1.rb +35 -0
  70. data/lib/mindee/product/custom/custom_v1_document.rb +60 -0
  71. data/lib/mindee/product/custom/custom_v1_page.rb +32 -0
  72. data/lib/mindee/product/eu/license_plate/license_plate_v1.rb +38 -0
  73. data/lib/mindee/product/eu/license_plate/license_plate_v1_document.rb +37 -0
  74. data/lib/mindee/product/eu/license_plate/license_plate_v1_page.rb +34 -0
  75. data/lib/mindee/product/financial_document/financial_document_v1.rb +36 -0
  76. data/lib/mindee/product/financial_document/financial_document_v1_document.rb +188 -0
  77. data/lib/mindee/product/financial_document/financial_document_v1_line_item.rb +90 -0
  78. data/lib/mindee/product/financial_document/financial_document_v1_page.rb +32 -0
  79. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v1.rb +38 -0
  80. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v1_document.rb +43 -0
  81. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v1_page.rb +34 -0
  82. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v2.rb +38 -0
  83. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v2_bban.rb +71 -0
  84. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v2_document.rb +58 -0
  85. data/lib/mindee/product/fr/bank_account_details/bank_account_details_v2_page.rb +34 -0
  86. data/lib/mindee/product/fr/carte_vitale/carte_vitale_v1.rb +38 -0
  87. data/lib/mindee/product/fr/carte_vitale/carte_vitale_v1_document.rb +52 -0
  88. data/lib/mindee/product/fr/carte_vitale/carte_vitale_v1_page.rb +34 -0
  89. data/lib/mindee/product/fr/id_card/id_card_v1.rb +38 -0
  90. data/lib/mindee/product/fr/id_card/id_card_v1_document.rb +82 -0
  91. data/lib/mindee/product/fr/id_card/id_card_v1_page.rb +48 -0
  92. data/lib/mindee/product/invoice/invoice_v4.rb +37 -0
  93. data/lib/mindee/product/invoice/invoice_v4_document.rb +212 -0
  94. data/lib/mindee/product/invoice/invoice_v4_line_item.rb +66 -0
  95. data/lib/mindee/product/invoice/invoice_v4_page.rb +32 -0
  96. data/lib/mindee/product/invoice_splitter/invoice_splitter_v1.rb +36 -0
  97. data/lib/mindee/product/invoice_splitter/invoice_splitter_v1_document.rb +65 -0
  98. data/lib/mindee/product/invoice_splitter/invoice_splitter_v1_page.rb +32 -0
  99. data/lib/mindee/product/passport/passport_v1.rb +36 -0
  100. data/lib/mindee/{parsing/prediction/fr/id_card/id_card_v1.rb → product/passport/passport_v1_document.rb} +45 -45
  101. data/lib/mindee/product/passport/passport_v1_page.rb +32 -0
  102. data/lib/mindee/product/proof_of_address/proof_of_address_v1.rb +36 -0
  103. data/lib/mindee/product/proof_of_address/proof_of_address_v1_document.rb +83 -0
  104. data/lib/mindee/product/proof_of_address/proof_of_address_v1_page.rb +32 -0
  105. data/lib/mindee/product/receipt/receipt_v4.rb +36 -0
  106. data/lib/mindee/product/receipt/receipt_v4_document.rb +86 -0
  107. data/lib/mindee/product/receipt/receipt_v4_page.rb +32 -0
  108. data/lib/mindee/product/receipt/receipt_v5.rb +36 -0
  109. data/lib/mindee/product/receipt/receipt_v5_document.rb +138 -0
  110. data/lib/mindee/product/receipt/receipt_v5_line_item.rb +69 -0
  111. data/lib/mindee/product/receipt/receipt_v5_page.rb +32 -0
  112. data/lib/mindee/product/us/bank_check/bank_check_v1.rb +38 -0
  113. data/lib/mindee/product/us/bank_check/bank_check_v1_document.rb +73 -0
  114. data/lib/mindee/product/us/bank_check/bank_check_v1_page.rb +34 -0
  115. data/lib/mindee/product.rb +16 -0
  116. data/lib/mindee/version.rb +2 -1
  117. data/lib/mindee.rb +3 -1
  118. metadata +87 -38
  119. data/docs/code_samples/shipping_containers_v1.txt +0 -14
  120. data/lib/mindee/document_config.rb +0 -60
  121. data/lib/mindee/parsing/document.rb +0 -31
  122. data/lib/mindee/parsing/error.rb +0 -22
  123. data/lib/mindee/parsing/inference.rb +0 -53
  124. data/lib/mindee/parsing/page.rb +0 -46
  125. data/lib/mindee/parsing/prediction/base.rb +0 -30
  126. data/lib/mindee/parsing/prediction/common_fields/amount.rb +0 -21
  127. data/lib/mindee/parsing/prediction/common_fields/base.rb +0 -72
  128. data/lib/mindee/parsing/prediction/common_fields/company_registration.rb +0 -17
  129. data/lib/mindee/parsing/prediction/common_fields/date.rb +0 -30
  130. data/lib/mindee/parsing/prediction/common_fields/locale.rb +0 -45
  131. data/lib/mindee/parsing/prediction/common_fields/payment_details.rb +0 -33
  132. data/lib/mindee/parsing/prediction/common_fields/position.rb +0 -39
  133. data/lib/mindee/parsing/prediction/common_fields/tax.rb +0 -40
  134. data/lib/mindee/parsing/prediction/common_fields/text.rb +0 -12
  135. data/lib/mindee/parsing/prediction/common_fields.rb +0 -11
  136. data/lib/mindee/parsing/prediction/custom/custom_v1.rb +0 -58
  137. data/lib/mindee/parsing/prediction/custom/fields.rb +0 -91
  138. data/lib/mindee/parsing/prediction/eu/license_plate/license_plate_v1.rb +0 -34
  139. data/lib/mindee/parsing/prediction/financial_document/financial_document_v1.rb +0 -237
  140. data/lib/mindee/parsing/prediction/financial_document/financial_document_v1_line_item.rb +0 -58
  141. data/lib/mindee/parsing/prediction/fr/bank_account_details/bank_account_details_v1.rb +0 -40
  142. data/lib/mindee/parsing/prediction/fr/carte_vitale/carte_vitale_v1.rb +0 -49
  143. data/lib/mindee/parsing/prediction/invoice/invoice_v4.rb +0 -212
  144. data/lib/mindee/parsing/prediction/invoice/invoice_v4_line_item.rb +0 -58
  145. data/lib/mindee/parsing/prediction/passport/passport_v1.rb +0 -121
  146. data/lib/mindee/parsing/prediction/proof_of_address/proof_of_address_v1.rb +0 -80
  147. data/lib/mindee/parsing/prediction/receipt/receipt_v4.rb +0 -87
  148. data/lib/mindee/parsing/prediction/receipt/receipt_v5.rb +0 -136
  149. data/lib/mindee/parsing/prediction/receipt/receipt_v5_line_item.rb +0 -37
  150. data/lib/mindee/parsing/prediction/shipping_container/shipping_container_v1.rb +0 -38
  151. data/lib/mindee/parsing/prediction/us/bank_check/bank_check_v1.rb +0 -70
  152. data/lib/mindee/parsing/prediction.rb +0 -15
data/lib/mindee/client.rb CHANGED
@@ -1,33 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'input'
4
- require_relative 'document_config'
5
- require_relative 'http/endpoint'
6
- require_relative 'parsing/prediction'
4
+ require_relative 'http'
5
+ require_relative 'product'
6
+ require_relative 'parsing/common/api_response'
7
7
 
8
8
  module Mindee
9
- # General client for sending a document to the API.
10
- class DocumentClient
11
- # @param input_doc [Mindee::InputDocument]
12
- # @param doc_configs [Hash]
13
- def initialize(input_doc, doc_configs)
14
- @input_doc = input_doc
15
- @doc_configs = doc_configs
9
+ # Mindee API Client.
10
+ # See: https://developers.mindee.com/docs
11
+ class Client
12
+ # @param api_key [String]
13
+ def initialize(api_key: '')
14
+ @api_key = api_key
16
15
  end
17
16
 
18
- # Call prediction API on the document and parse the results.
17
+ # Call prediction API on a document and parse the results.
19
18
  #
20
- # @param prediction_class [Mindee::Prediction::Prediction]
19
+ # @param input_source [Mindee::Input::Source::LocalInputSource, Mindee::Input::Source::UrlInputSource]
21
20
  #
22
- # @param endpoint_name [String] For custom endpoints, the "API name" field in the "Settings" page of the
23
- # API Builder. Do not set for standard (off the shelf) endpoints.
24
- #
25
- # @param account_name [String] For custom endpoints, your account or organization username on the API Builder.
26
- # This is normally not required unless you have a custom endpoint which has the same name as a
27
- # standard (off the shelf) endpoint.
28
- # Do not set for standard (off the shelf) endpoints.
21
+ # @param endpoint [HTTP::Endpoint] Endpoint of the API
22
+ # Doesn't need to be set in the case of OTS APIs.
29
23
  #
30
- # @param include_words [Boolean] Whether to include the full text for each page.
24
+ # @param all_words [Boolean] Whether to include the full text for each page.
31
25
  # This performs a full OCR operation on the server and will increase response time.
32
26
  #
33
27
  # @param close_file [Boolean] Whether to `close()` the file after parsing it.
@@ -44,170 +38,178 @@ module Mindee
44
38
  # @param cropper [Boolean] Whether to include cropper results for each page.
45
39
  # This performs a cropping operation on the server and will increase response time.
46
40
  #
47
- # @return [Mindee::DocumentResponse]
41
+ # @return [Mindee::Parsing::Common::ApiResponse]
48
42
  def parse(
49
- prediction_class,
50
- endpoint_name: '',
51
- account_name: '',
52
- include_words: false,
43
+ input_source,
44
+ product_class,
45
+ endpoint: nil,
46
+ all_words: false,
53
47
  close_file: true,
54
48
  page_options: nil,
55
49
  cropper: false
56
50
  )
57
- doc_config = find_doc_config(prediction_class, endpoint_name, account_name)
58
- @input_doc.process_pdf(page_options) if !page_options.nil? && @input_doc.pdf?
59
- doc_config.predict(@input_doc, include_words, close_file, cropper)
60
- end
61
-
62
- private
63
-
64
- # @param document_class [Mindee::Prediction::Prediction]
65
- # @param endpoint_name [String]
66
- def determine_endpoint_name(document_class, endpoint_name)
67
- return document_class.name if document_class.name != Prediction::CustomV1.name
68
-
69
- raise "endpoint_name is required when using #{document_class.name} class" if endpoint_name.empty?
70
-
71
- endpoint_name
72
- end
73
-
74
- # @param document_class [Mindee::Prediction::Prediction]
75
- # @param endpoint_name [String]
76
- # @param account_name [String]
77
- def find_doc_config(document_class, endpoint_name, account_name)
78
- endpoint_name = determine_endpoint_name(document_class, endpoint_name)
79
-
80
- found = []
81
- @doc_configs.each_key do |conf|
82
- found.push(conf) if conf[1] == endpoint_name
51
+ if input_source.is_a?(Mindee::Input::Source::LocalInputSource) && !page_options.nil? && input_source.pdf?
52
+ input_source.process_pdf(page_options)
83
53
  end
84
- raise "Endpoint not configured: #{endpoint_name}" if found.empty?
85
-
86
- if !account_name.empty?
87
- config_key = [account_name, endpoint_name]
88
- elsif found.length == 1
89
- config_key = found[0]
90
- else
91
- usernames = found.map { |conf| conf[0] }
92
- raise "Duplicate configuration detected.\n" \
93
- "You specified the document '#{endpoint_name}' in your custom config.\n" \
94
- "To avoid confusion, please add the 'account_name' attribute to " \
95
- "the parse method, one of #{usernames}."
96
- end
97
-
98
- @doc_configs[config_key]
54
+ endpoint = initialize_endpoint(product_class) if endpoint.nil?
55
+ prediction = endpoint.predict(input_source, all_words, close_file, cropper)
56
+ Mindee::Parsing::Common::ApiResponse.new(product_class, prediction)
99
57
  end
100
- end
101
58
 
102
- # Mindee API Client.
103
- # See: https://developers.mindee.com/docs/
104
- class Client
105
- # @param api_key [String]
106
- def initialize(api_key: '')
107
- @doc_configs = {}
108
- @api_key = api_key
109
- init_default_endpoints
59
+ # Enqueue a document for async parsing
60
+ #
61
+ # @param input_source [Mindee::Input::Source::LocalInputSource, Mindee::Input::Source::UrlInputSource]
62
+ #
63
+ # @param endpoint [HTTP::Endpoint, nil] Endpoint of the API.
64
+ # Doesn't need to be set in the case of OTS APIs.
65
+ #
66
+ # @param all_words [Boolean] Whether to extract all the words on each page.
67
+ # This performs a full OCR operation on the server and will increase response time.
68
+ #
69
+ # @param close_file [Boolean] Whether to `close()` the file after parsing it.
70
+ # Set to false if you need to access the file after this operation.
71
+ #
72
+ # @param page_options [Hash, nil] Page cutting/merge options:
73
+ #
74
+ # * `:page_indexes` Zero-based list of page indexes.
75
+ # * `:operation` Operation to apply on the document, given the `page_indexes specified:
76
+ # * `:KEEP_ONLY` - keep only the specified pages, and remove all others.
77
+ # * `:REMOVE` - remove the specified pages, and keep all others.
78
+ # * `:on_min_pages` Apply the operation only if document has at least this many pages.
79
+ #
80
+ # @param cropper [Boolean] Whether to include cropper results for each page.
81
+ # This performs a cropping operation on the server and will increase response time.
82
+ #
83
+ # @return [Mindee::Parsing::Common::ApiResponse]
84
+ def enqueue(
85
+ input_source,
86
+ product_class,
87
+ endpoint: nil,
88
+ all_words: false,
89
+ close_file: true,
90
+ page_options: nil,
91
+ cropper: false
92
+ )
93
+ if input_source.is_a?(Mindee::Input::Source::LocalInputSource) && !page_options.nil? && input_source.pdf?
94
+ input_source.process_pdf(page_options)
95
+ end
96
+ endpoint = initialize_endpoint(product_class) if endpoint.nil?
97
+ Mindee::Parsing::Common::ApiResponse.new(product_class,
98
+ endpoint.predict_async(input_source, all_words, close_file, cropper))
110
99
  end
111
100
 
112
- # Configure a custom document using the 'Mindee API Builder'.
113
- # @param account_name [String] Your organization's username on the API Builder
114
- # @param endpoint_name [String] The "API name" field in the "Settings" page of the API Builder
115
- # @param version [String] Specify the version of the model to use. If not set, use the latest version of the model.
116
- # @return [Mindee::Client]
117
- def add_endpoint(
118
- account_name,
119
- endpoint_name,
120
- version: '1'
101
+ # Parses a queued document
102
+ #
103
+ # @param endpoint [HTTP::Endpoint, nil] Endpoint of the API
104
+ # Doesn't need to be set in the case of OTS APIs.
105
+ #
106
+ # @param job_id [String] Id of the job (queue) to poll from
107
+ #
108
+ # @return [Mindee::Parsing::Common::ApiResponse]
109
+ def parse_queued(
110
+ job_id,
111
+ product_class,
112
+ endpoint: nil
121
113
  )
122
- @doc_configs[[account_name, endpoint_name]] = DocumentConfig.new(
123
- Prediction::CustomV1,
124
- HTTP::CustomEndpoint.new(account_name, endpoint_name, version, @api_key)
125
- )
126
- self
114
+ endpoint = initialize_endpoint(product_class) if endpoint.nil?
115
+ Mindee::Parsing::Common::ApiResponse.new(product_class, endpoint.parse_async(job_id))
127
116
  end
128
117
 
129
118
  # Load a document from an absolute path, as a string.
130
119
  # @param input_path [String] Path of file to open
131
- # @return [Mindee::DocumentClient]
132
- def doc_from_path(input_path)
133
- doc = Input::PathDocument.new(input_path)
134
- DocumentClient.new(doc, @doc_configs)
120
+ # @return [Mindee::Input::Source::PathInputSource]
121
+ def source_from_path(input_path)
122
+ Input::Source::PathInputSource.new(input_path)
135
123
  end
136
124
 
137
125
  # Load a document from raw bytes.
138
126
  # @param input_bytes [String] Encoding::BINARY byte input
139
127
  # @param filename [String] The name of the file (without the path)
140
- # @return [Mindee::DocumentClient]
141
- def doc_from_bytes(input_bytes, filename)
142
- doc = Input::BytesDocument.new(input_bytes, filename)
143
- DocumentClient.new(doc, @doc_configs)
128
+ # @return [Mindee::Input::Source::BytesInputSource]
129
+ def source_from_bytes(input_bytes, filename)
130
+ Input::Source::BytesInputSource.new(input_bytes, filename)
144
131
  end
145
132
 
146
133
  # Load a document from a base64 encoded string.
147
134
  # @param base64_string [String] Input to parse as base64 string
148
135
  # @param filename [String] The name of the file (without the path)
149
- # @return [Mindee::DocumentClient]
150
- def doc_from_b64string(base64_string, filename)
151
- doc = Input::Base64Document.new(base64_string, filename)
152
- DocumentClient.new(doc, @doc_configs)
136
+ # @return [Mindee::Input::Source::Base64InputSource]
137
+ def source_from_b64string(base64_string, filename)
138
+ Input::Source::Base64InputSource.new(base64_string, filename)
153
139
  end
154
140
 
155
141
  # Load a document from a normal Ruby `File`.
156
142
  # @param input_file [File] Input file handle
157
143
  # @param filename [String] The name of the file (without the path)
158
- # @return [Mindee::DocumentClient]
159
- def doc_from_file(input_file, filename)
160
- doc = Input::FileDocument.new(input_file, filename)
161
- DocumentClient.new(doc, @doc_configs)
144
+ # @return [Mindee::Input::Source::FileInputSource]
145
+ def source_from_file(input_file, filename)
146
+ Input::Source::FileInputSource.new(input_file, filename)
147
+ end
148
+
149
+ # Load a document from a secure remote source (HTTPS).
150
+ # @param url [String] Url of the file
151
+ # @return [Mindee::Input::Source::UrlInputSource]
152
+ def source_from_url(url)
153
+ Input::Source::UrlInputSource.new(url)
154
+ end
155
+
156
+ # Creates a custom endpoint with the given values.
157
+ # Do not set for standard (off the shelf) endpoints.
158
+ #
159
+ # @param endpoint_name [String] For custom endpoints, the "API name" field in the "Settings" page of the
160
+ # API Builder. Do not set for standard (off the shelf) endpoints.
161
+ #
162
+ # @param account_name [String] For custom endpoints, your account or organization username on the API Builder.
163
+ # This is normally not required unless you have a custom endpoint which has the same name as a
164
+ # standard (off the shelf) endpoint.
165
+ # @param version [String] For custom endpoints, version of the product
166
+ # @return [Mindee::HTTP::Endpoint]
167
+ def create_endpoint(endpoint_name: '', account_name: '', version: '')
168
+ initialize_endpoint(Mindee::Product::Custom::CustomV1, endpoint_name: endpoint_name, account_name: account_name,
169
+ version: version)
162
170
  end
163
171
 
164
172
  private
165
173
 
166
- def standard_document_config(prediction_class, endpoint_name, version)
167
- DocumentConfig.new(
168
- prediction_class,
169
- HTTP::StandardEndpoint.new(endpoint_name, version, @api_key)
170
- )
174
+ # Creates an endpoint with the given values. Raises an error if the endpoint is invalid.
175
+ # @param product_class [Mindee::Product] class of the product
176
+ #
177
+ # @param endpoint_name [String] For custom endpoints, the "API name" field in the "Settings" page of the
178
+ # API Builder. Do not set for standard (off the shelf) endpoints.
179
+ #
180
+ # @param account_name [String] For custom endpoints, your account or organization username on the API Builder.
181
+ # This is normally not required unless you have a custom endpoint which has the same name as a
182
+ # standard (off the shelf) endpoint.
183
+ # @param version [String] For custom endpoints, version of the product.
184
+ # @return [Mindee::HTTP::Endpoint]
185
+ def initialize_endpoint(product_class, endpoint_name: '', account_name: '', version: '')
186
+ if (endpoint_name.nil? || endpoint_name.empty?) && product_class == Mindee::Product::Custom::CustomV1
187
+ raise 'Missing argument endpoint_name when using custom class'
188
+ end
189
+
190
+ endpoint_name = fix_endpoint_name(product_class, endpoint_name)
191
+ account_name = fix_account_name(account_name)
192
+ version = fix_version(product_class, version)
193
+ HTTP::Endpoint.new(account_name, endpoint_name, version, api_key: @api_key)
194
+ end
195
+
196
+ def fix_endpoint_name(product_class, endpoint_name)
197
+ return product_class.endpoint_name if endpoint_name.nil? || endpoint_name.empty?
198
+
199
+ endpoint_name
171
200
  end
172
201
 
173
- def init_default_endpoints
174
- @doc_configs[['mindee', Prediction::ProofOfAddressV1.name]] = standard_document_config(
175
- Prediction::ProofOfAddressV1, 'proof_of_address', '1'
176
- )
177
- @doc_configs[['mindee', Prediction::FinancialDocumentV1.name]] = standard_document_config(
178
- Prediction::FinancialDocumentV1, 'financial_document', '1'
179
- )
180
- @doc_configs[['mindee', Prediction::InvoiceV4.name]] = standard_document_config(
181
- Prediction::InvoiceV4, 'invoices', '4'
182
- )
183
- @doc_configs[['mindee', Prediction::ReceiptV4.name]] = standard_document_config(
184
- Prediction::ReceiptV4, 'expense_receipts', '4'
185
- )
186
- @doc_configs[['mindee', Prediction::ReceiptV5.name]] = standard_document_config(
187
- Prediction::ReceiptV5, 'expense_receipts', '5'
188
- )
189
- @doc_configs[['mindee', Prediction::PassportV1.name]] = standard_document_config(
190
- Prediction::PassportV1, 'passport', '1'
191
- )
192
- @doc_configs[['mindee', Prediction::EU::LicensePlateV1.name]] = standard_document_config(
193
- Prediction::EU::LicensePlateV1, 'license_plates', '1'
194
- )
195
- @doc_configs[['mindee', Prediction::ShippingContainerV1.name]] = standard_document_config(
196
- Prediction::ShippingContainerV1, 'shipping_containers', '1'
197
- )
198
- @doc_configs[['mindee', Prediction::US::BankCheckV1.name]] = standard_document_config(
199
- Prediction::US::BankCheckV1, 'bank_check', '1'
200
- )
201
- @doc_configs[['mindee', Prediction::FR::BankAccountDetailsV1.name]] = standard_document_config(
202
- Prediction::FR::BankAccountDetailsV1, 'bank_account_details', '1'
203
- )
204
- @doc_configs[['mindee', Prediction::FR::CarteVitaleV1.name]] = standard_document_config(
205
- Prediction::FR::CarteVitaleV1, 'carte_vitale', '1'
206
- )
207
- @doc_configs[['mindee', Prediction::FR::IdCardV1.name]] = standard_document_config(
208
- Prediction::FR::IdCardV1, 'idcard_fr', '1'
209
- )
210
- self
202
+ def fix_account_name(account_name)
203
+ return 'mindee' if account_name.nil? || account_name.empty?
204
+
205
+ account_name
206
+ end
207
+
208
+ def fix_version(product_class, version)
209
+ return version unless version.nil? || version.empty?
210
+ return '1' if product_class.endpoint_version.nil? || product_class.endpoint_version.empty?
211
+
212
+ product_class.endpoint_version
211
213
  end
212
214
  end
213
215
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mindee
4
+ # Various helper functions & classes for geometry.
5
+ module Geometry
6
+ # A set of minimum and maximum values.
7
+ class MinMax
8
+ # Minimum
9
+ # @return [Float]
10
+ attr_reader :min
11
+ # Maximum
12
+ # @return [Float]
13
+ attr_reader :max
14
+
15
+ # @param min [Float]
16
+ # @param max [Float]
17
+ def initialize(min, max)
18
+ @min = min
19
+ @max = max
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mindee
4
+ # Various helper functions for geometry.
5
+ module Geometry
6
+ # A relative set of coordinates (X, Y) on the document.
7
+ class Point
8
+ # @return [Float]
9
+ attr_accessor :x
10
+ # @return [Float]
11
+ attr_accessor :y
12
+
13
+ # @param x [Float]
14
+ # @param y [Float]
15
+ # rubocop:disable Naming/MethodParameterName
16
+ def initialize(x, y)
17
+ @x = x
18
+ @y = y
19
+ end
20
+ # rubocop:enable Naming/MethodParameterName
21
+
22
+ # @return [Float]
23
+ def [](key)
24
+ case key
25
+ when 0
26
+ @x
27
+ when 1
28
+ @y
29
+ else
30
+ throw '0 or 1 only'
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mindee
4
+ # Various helper functions & classes for geometry.
5
+ module Geometry
6
+ # Contains any number of vertex coordinates (Points).
7
+ class Polygon < Array
8
+ # Get the central point (centroid) of the polygon.
9
+ # @return [Mindee::Geometry::Point]
10
+ def centroid
11
+ Geometry.get_centroid(self)
12
+ end
13
+
14
+ # Determine if the Point is in the Polygon's Y-axis.
15
+ # @param point [Mindee::Geometry::Point]
16
+ # @return [Boolean]
17
+ def point_in_y?(point)
18
+ min_max = Geometry.get_min_max_y(self)
19
+ min_max.min <= point.y && point.y <= min_max.max
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mindee
4
+ # Various helper functions & classes for geometry.
5
+ module Geometry
6
+ # Contains exactly 4 relative vertices coordinates (Points).
7
+ class Quadrilateral
8
+ # @return [Mindee::Geometry::Point]
9
+ attr_accessor :top_left
10
+ # @return [Mindee::Geometry::Point]
11
+ attr_accessor :top_right
12
+ # @return [Mindee::Geometry::Point]
13
+ attr_accessor :bottom_right
14
+ # @return [Mindee::Geometry::Point]
15
+ attr_accessor :bottom_left
16
+
17
+ # @param top_left [Mindee::Geometry::Point]
18
+ # @param top_right [Mindee::Geometry::Point]
19
+ # @param bottom_right [Mindee::Geometry::Point]
20
+ # @param bottom_left [Mindee::Geometry::Point]
21
+ def initialize(top_left, top_right, bottom_right, bottom_left)
22
+ @top_left = top_left
23
+ @top_right = top_right
24
+ @bottom_right = bottom_right
25
+ @bottom_left = bottom_left
26
+ end
27
+
28
+ # @return [Mindee::Geometry::Point]
29
+ def [](key)
30
+ case key
31
+ when 0
32
+ @top_left
33
+ when 1
34
+ @top_right
35
+ when 2
36
+ @bottom_right
37
+ when 3
38
+ @bottom_left
39
+ else
40
+ throw '0, 1, 2, 3 only'
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mindee
4
+ # Various helper functions for geometry.
5
+ module Geometry
6
+ # Transform a prediction into a Quadrilateral.
7
+ # @param prediction [Hash]
8
+ # @return [Mindee::Geometry::Quadrilateral]
9
+ def self.quadrilateral_from_prediction(prediction)
10
+ throw "Prediction must have exactly 4 points, found #{prediction.size}" if prediction.size != 4
11
+
12
+ Quadrilateral.new(
13
+ Point.new(prediction[0][0], prediction[0][1]),
14
+ Point.new(prediction[1][0], prediction[1][1]),
15
+ Point.new(prediction[2][0], prediction[2][1]),
16
+ Point.new(prediction[3][0], prediction[3][1])
17
+ )
18
+ end
19
+
20
+ # Transform a prediction into a Polygon.
21
+ # @param prediction [Hash]
22
+ # @return [Mindee::Geometry::Polygon]
23
+ def self.polygon_from_prediction(prediction)
24
+ polygon = Polygon.new
25
+ return polygon if prediction.nil?
26
+
27
+ prediction.each do |point|
28
+ polygon << Point.new(point[0], point[1])
29
+ end
30
+ polygon
31
+ end
32
+
33
+ # Gets the points of a bounding box for a given set of points
34
+ # @param vertices [Array<Mindee::Geometry::Point>]
35
+ # @return [Array<Float>]
36
+ def self.get_bbox(vertices)
37
+ x_coords = vertices.map(&:x)
38
+ y_coords = vertices.map(&:y)
39
+ [x_coords.min, y_coords.min, x_coords.max, y_coords.max]
40
+ end
41
+
42
+ # Creates the bounding bounding box for a given set of points
43
+ # @param vertices [Array<Mindee::Geometry::Point>]
44
+ # @return [Mindee::Geometry::Quadrilateral]
45
+ def self.get_bounding_box(vertices)
46
+ x_min, y_min, x_max, y_max = get_bbox(vertices)
47
+ Quadrilateral.new(
48
+ Point.new(x_min, y_min),
49
+ Point.new(x_max, y_min),
50
+ Point.new(x_max, y_max),
51
+ Point.new(x_min, y_max)
52
+ )
53
+ end
54
+
55
+ # Get the central point (centroid) given a sequence of points.
56
+ # @param points [Array<Mindee::Geometry::Point>]
57
+ # @return [Mindee::Geometry::Point]
58
+ def self.get_centroid(points)
59
+ vertices_count = points.size
60
+ x_sum = points.map(&:x).sum
61
+ y_sum = points.map(&:y).sum
62
+ Point.new(x_sum / vertices_count, y_sum / vertices_count)
63
+ end
64
+
65
+ # Get the maximum and minimum Y value given a sequence of points.
66
+ # @param points [Array<Mindee::Geometry::Point>]
67
+ # @return [Mindee::Geometry::MinMax]
68
+ def self.get_min_max_y(points)
69
+ coords = points.map(&:y)
70
+ MinMax.new(coords.min, coords.max)
71
+ end
72
+
73
+ # Get the maximum and minimum X value given a sequence of points.
74
+ # @param points [Array<Mindee::Geometry::Point>]
75
+ # @return [Mindee::Geometry::MinMax]
76
+ def self.get_min_max_x(points)
77
+ coords = points.map(&:x)
78
+ MinMax.new(coords.min, coords.max)
79
+ end
80
+ end
81
+ end