mindee 2.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +2 -0
  4. data/.yardopts +1 -0
  5. data/CHANGELOG.md +31 -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 -44
  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