Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lib/mindee/parsing/v2/inference.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require_relative 'inference_job'
require_relative 'inference_model'
require_relative 'inference_file'
require_relative 'inference_result'
Expand All @@ -12,6 +13,8 @@ module V2
class Inference
# @return [String] Identifier of the inference (when provided by API).
attr_reader :id
# @return [InferenceJob] Metadata about the job.
attr_reader :job
# @return [InferenceModel] Information about the model used.
attr_reader :model
# @return [InferenceFile] Information about the processed file.
Expand All @@ -26,6 +29,7 @@ def initialize(server_response)
raise ArgumentError, 'server_response must be a Hash' unless server_response.is_a?(Hash)

@model = InferenceModel.new(server_response['model'])
@job = InferenceJob.new(server_response['job']) if server_response.key?('job')
@file = InferenceFile.new(server_response['file'])
@active_options = InferenceActiveOptions.new(server_response['active_options'])
@result = InferenceResult.new(server_response['result'])
Expand All @@ -39,6 +43,7 @@ def to_s
[
'Inference',
'#########',
@job.to_s,
@model.to_s,
@file.to_s,
@active_options.to_s,
Expand Down
25 changes: 25 additions & 0 deletions lib/mindee/parsing/v2/inference_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

require_relative 'common_response'
require_relative 'job'

module Mindee
module Parsing
module V2
# HTTP response wrapper that embeds a V2 job.
class InferenceJob
# @return [String] UUID of the Job.
attr_reader :id

def initialize(server_response)
@id = server_response['id']
end

# @return [String] String representation of the job.
def to_s
"Job\n===\n:ID: #{@id}\n"
end
end
end
end
end
11 changes: 9 additions & 2 deletions lib/mindee/parsing/v2/job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ module V2
class Job
# @return [String] Unique job identifier.
attr_reader :id
# @return [DateTime, nil] Timestamp of creation.
# @return [Time] Date and time of the Job creation.
attr_reader :created_at
# @return [Time, nil] Date and time of the Job completion. Filled once processing is finished.
attr_reader :completed_at
# @return [String] Identifier of the model used.
attr_reader :model_id
# @return [String] Name of the processed file.
Expand All @@ -30,6 +32,7 @@ class Job
# @return [ErrorResponse, nil] Error details when the job failed.
attr_reader :error

# rubocop:disable Metrics/CyclomaticComplexity
# @param server_response [Hash] Parsed JSON payload from the API.
def initialize(server_response)
raise ArgumentError, 'server_response must be a Hash' unless server_response.is_a?(Hash)
Expand All @@ -39,7 +42,10 @@ def initialize(server_response)
unless server_response['error'].nil? || server_response['error'].empty?
@error = ErrorResponse.new(server_response['error'])
end
@created_at = Time.iso8601(server_response['created_at'])
@created_at = Time.iso8601(server_response['created_at'])
if server_response.key?('completed_at') && !server_response['completed_at'].nil?
@completed_at = Time.iso8601(server_response['completed_at'])
end
@model_id = server_response['model_id']
@polling_url = server_response['polling_url']
@filename = server_response['filename']
Expand All @@ -50,6 +56,7 @@ def initialize(server_response)
@webhooks.push JobWebhook.new(webhook)
end
end
# rubocop:enable Metrics/CyclomaticComplexity

# String representation.
# @return [String]
Expand Down
2 changes: 2 additions & 0 deletions sig/mindee/parsing/v2/inference.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module Mindee
module Parsing
module V2
class Inference

attr_reader id: String
attr_reader job: InferenceJob
attr_reader model: InferenceModel
attr_reader file: InferenceFile
attr_reader active_options: InferenceActiveOptions
Expand Down
12 changes: 12 additions & 0 deletions sig/mindee/parsing/v2/inference_job.rbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module Mindee
module Parsing
module V2
class InferenceJob
attr_reader id: String

def initialize: (Hash[String | Symbol, untyped]) -> void
def to_s: -> String
end
end
end
end
3 changes: 2 additions & 1 deletion sig/mindee/parsing/v2/job.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ module Mindee
module V2
class Job
attr_reader alias: String
attr_reader created_at: DateTime?
attr_reader created_at: Time
attr_reader completed_at: Time?
attr_reader error: ErrorResponse?
attr_reader filename: String
attr_reader id: String
Expand Down
2 changes: 1 addition & 1 deletion spec/data
Submodule data updated 34 files
+0 −38 v2/inference/text_context_enabled.json
+2 −1 v2/job/fail_422.json
+1 −0 v2/job/ok_processed_webhooks_ok.json
+1 −0 v2/job/ok_processing.json
+3 −3 v2/products/classification/classification_single.json
+ v2/products/classification/default_invoice.jpg
+3 −3 v2/products/crop/crop_multiple.json
+23 −0 v2/products/crop/crop_multiple.rst
+3 −3 v2/products/crop/crop_single.json
+21 −0 v2/products/crop/crop_single.rst
+ v2/products/crop/default_sample.jpg
+ v2/products/crop/multipage_sample.pdf
+3 −0 v2/products/extraction/data_schema_replace.json
+0 −0 v2/products/extraction/data_schema_replace_param.json
+6 −4 v2/products/extraction/deep_nested_fields.json
+3 −3 v2/products/extraction/financial_document/blank.json
+3 −3 v2/products/extraction/financial_document/complete.json
+3 −3 v2/products/extraction/financial_document/complete_with_coordinates.json
+ v2/products/extraction/financial_document/default_sample.jpg
+3 −3 v2/products/extraction/financial_document/default_sample.json
+3 −3 v2/products/extraction/rag_matched.json
+3 −3 v2/products/extraction/rag_not_matched.json
+3 −3 v2/products/extraction/raw_texts.json
+0 −0 v2/products/extraction/raw_texts.txt
+3 −3 v2/products/extraction/standard_field_types.json
+4 −0 v2/products/extraction/standard_field_types.rst
+38 −0 v2/products/extraction/text_context_enabled.json
+ v2/products/ocr/default_sample.jpg
+3 −3 v2/products/ocr/ocr_multiple.json
+3 −3 v2/products/ocr/ocr_single.json
+ v2/products/split/default_sample.pdf
+ v2/products/split/invoice_5p.pdf
+3 −3 v2/products/split/split_multiple.json
+3 −3 v2/products/split/split_single.json
3 changes: 2 additions & 1 deletion spec/v2/client_v2_integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@

context 'A Data Schema Override' do
it 'Overrides successfully' do
data_schema_replace = File.read(File.join(V2_DATA_DIR, 'inference', 'data_schema_replace_param.json'))
data_schema_replace = File.read(File.join(V2_DATA_DIR, 'products', 'extraction',
'data_schema_replace_param.json'))
input = Mindee::Input::Source::PathInputSource.new(File.join(FILE_TYPES_DIR, 'pdf', 'blank_1.pdf'))

inference_params = Mindee::Input::InferenceParameters.new(
Expand Down
23 changes: 23 additions & 0 deletions spec/v2/client_v2_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,29 @@ def stub_next_request_with(method, hash:, status_code: 0)
resp = client.get_job('123e4567-e89b-12d3-a456-426614174000')
expect(resp).to be_a(Mindee::Parsing::V2::JobResponse)
expect(resp.job.status).to eq('Processing')
expect(
resp.job.created_at.strftime('%Y-%m-%dT%H:%M:%S.%6N')
).to eq('2025-07-03T14:27:58.974451')
expect(resp.job.completed_at).to be_nil
end

it 'should deserialize a job properly' do
json_path = File.join(V2_DATA_DIR, 'job', 'ok_processed_webhooks_ok.json')
parsed = File.read(json_path)
stub_next_request_with(:inference_job_req_get, hash: parsed, status_code: 200)

resp = client.get_job('123e4567-e89b-12d3-a456-426614174000')
expect(resp).to be_a(Mindee::Parsing::V2::JobResponse)
expect(resp.job.status).to eq('Processed')
expect(resp.job.model_id).to eq('87654321-4321-4321-4321-CBA987654321')
expect(resp.job.filename).to eq('default_sample.jpg')
expect(resp.job.alias).to eq('dummy-alias.jpg')
expect(
resp.job.created_at.strftime('%Y-%m-%dT%H:%M:%S.%6N')
).to eq('2026-04-20T18:27:58.974451')
expect(
resp.job.completed_at.strftime('%Y-%m-%dT%H:%M:%S.%6N')
).to eq('2026-04-20T18:32:02.734312')
end
ENV.delete('MINDEE_V2_BASE_URL')
end
4 changes: 3 additions & 1 deletion spec/v2/input/inference_parameter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
require 'mindee/input/data_schema'

describe Mindee::Input::InferenceParameters do
let(:extracted_schema_content) { File.read(File.join(V2_DATA_DIR, 'inference', 'data_schema_replace_param.json')) }
let(:extracted_schema_content) do
File.read(File.join(V2_DATA_DIR, 'products', 'extraction', 'data_schema_replace_param.json'))
end
let(:extracted_schema_hash) { JSON.parse(extracted_schema_content) }
let(:extracted_schema_str) { extracted_schema_hash.to_json }
let(:extracted_schema_object) { Mindee::Input::DataSchema.new(extracted_schema_hash) }
Expand Down
4 changes: 2 additions & 2 deletions spec/v2/input/local_response_v2_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

def assert_local_response(local_response)
dummy_secret_key = 'ogNjY44MhvKPGTtVsI8zG82JqWQa68woYQH'
signature = 'f390d9f7f57ac04f47b6309d8a40236b0182610804fc20e91b1f6028aaca07a7'
signature = 'e51bdf80f1a08ed44ee161100fc30a25cb35b4ede671b0a575dc9064a3f5dbf1'
expect(local_response.file).to_not be(nil)
expect(local_response.valid_hmac_signature?(
dummy_secret_key, 'invalid signature'
Expand All @@ -18,7 +18,7 @@ def assert_local_response(local_response)
end

describe Mindee::Input::LocalResponse do
let(:file_path) { File.join(V2_DATA_DIR, 'inference', 'standard_field_types.json') }
let(:file_path) { File.join(V2_DATA_DIR, 'products', 'extraction', 'standard_field_types.json') }
context 'A V2 local response' do
it 'should load from a path' do
response = Mindee::Input::LocalResponse.new(file_path)
Expand Down
24 changes: 14 additions & 10 deletions spec/v2/parsing/inference_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
require 'mindee'

RSpec.describe 'inference' do
let(:findoc_path) { File.join(V2_DATA_DIR, 'products', 'financial_document') }
let(:inference_path) { File.join(V2_DATA_DIR, 'inference') }
let(:deep_nested_field_path) { File.join(inference_path, 'deep_nested_fields.json') }
let(:standard_field_path) { File.join(inference_path, 'standard_field_types.json') }
let(:standard_field_rst_path) { File.join(inference_path, 'standard_field_types.rst') }
let(:findoc_path) { File.join(V2_DATA_DIR, 'products', 'extraction', 'financial_document') }
let(:extraction_path) { File.join(V2_DATA_DIR, 'products', 'extraction') }
let(:deep_nested_field_path) { File.join(extraction_path, 'deep_nested_fields.json') }
let(:standard_field_path) { File.join(extraction_path, 'standard_field_types.json') }
let(:standard_field_rst_path) { File.join(extraction_path, 'standard_field_types.rst') }
let(:location_field_path) { File.join(findoc_path, 'complete_with_coordinates.json') }
let(:raw_text_json_path) { File.join(inference_path, 'raw_texts.json') }
let(:raw_text_str_path) { File.join(inference_path, 'raw_texts.txt') }
let(:raw_text_json_path) { File.join(extraction_path, 'raw_texts.json') }
let(:raw_text_str_path) { File.join(extraction_path, 'raw_texts.txt') }
let(:blank_path) { File.join(findoc_path, 'blank.json') }
let(:complete_path) { File.join(findoc_path, 'complete.json') }
let(:rag_matched_path) { File.join(inference_path, 'rag_matched.json') }
let(:rag_not_matched_path) { File.join(inference_path, 'rag_not_matched.json') }
let(:text_context_path) { File.join(inference_path, 'text_context_enabled.json') }
let(:rag_matched_path) { File.join(extraction_path, 'rag_matched.json') }
let(:rag_not_matched_path) { File.join(extraction_path, 'rag_not_matched.json') }
let(:text_context_path) { File.join(extraction_path, 'text_context_enabled.json') }

def load_v2_inference(resource_path)
local_response = Mindee::Input::LocalResponse.new(resource_path)
Expand Down Expand Up @@ -62,6 +62,10 @@ def load_v2_inference(resource_path)
it 'loads a complete inference with valid properties' do
response = load_v2_inference(complete_path)
inference = response.inference
job = inference.job
expect(job).not_to be_nil
expect(job).to be_a(Mindee::Parsing::V2::InferenceJob)
expect(job.id).to eq('12345678-1234-1234-1234-jobid1234567')

expect(inference).not_to be_nil
expect(inference.id).to eq('12345678-1234-1234-1234-123456789abc')
Expand Down