### Setup and Test Environment Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Commands to clone the repository, create a virtual environment, install dependencies, and run tests. ```bash git clone https://github.com/aws-samples/amazon-textract-response-parser.git cd amazon-textract-response-parser python -m venv virtualenv virtualenv/bin/activate python -m pip install --upgrade pip setuptools python -m pip install -e .[dev] pytest ``` -------------------------------- ### Install the library Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Use npm to add the package to your project dependencies. ```sh $ npm install amazon-textract-response-parser ``` -------------------------------- ### Install Amazon Textract Response Parser Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Install the library using pip. ```bash python -m pip install amazon-textract-response-parser ``` -------------------------------- ### Execute Project via CLI Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-csharp/README.md Command to run the project after installing .NET Core and configuring AWS credentials. ```bash dotnet run ``` -------------------------------- ### Example Output for Textract Parsing Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/textract-mapping/README.md Shows the expected console output when parsing form fields from a Textract document response. ```text ==================== Form (key/values) ==================== Field: Key: Phone Number:, Value: 555-0100 Get field by page ({'key': {'block': {'BlockType': 'KEY_VALUE_SET', 'Confidence': 63.59760284423828, 'Geometry': {'BoundingBox': {'Width': 0.16836532950401306, 'Height': 0.03139100223779678, 'Left': 0.02776719070971012, 'Top': 0.1963476836681366}, 'Polygon': [{'X': 0.02776719070971012, 'Y': 0.1963476836681366}, {'X': 0.19613252580165863, 'Y': 0.1963476836681366}, {'X': 0.19613252580165863, 'Y': 0.22773869335651398}, {'X': 0.02776719070971012, 'Y': 0.22773869335651398}]}, 'Id': 'dd8dbecf-73f1-49e2-bc9f-7169a133f6dd', 'Relationships': [{'Type': 'VALUE', 'Ids': ['a8acd770-2d5a-4799-9e0d-17a96b6da85a']}, {'Type': 'CHILD', 'Ids': ['b4dd773f-ddb7-407e-9dbc-cf623204e654', '63c1b36b-6b46-4391-b3a5-379247f448f8']}], 'EntityTypes': ['KEY']}, 'id': 'dd8dbecf-73f1-49e2-bc9f-7169a133f6dd', 'text': 'Phone Number:', 'content': [{'text': 'Phone', 'geometry': {'BoundingBox': {'Width': 0.06604675948619843, 'Height': 0.036048345267772675, 'Left': 0.029274573549628258, 'Top': 0.19063594937324524}, 'Polygon': [{'X': 0.029274573549628258, 'Y': 0.19063594937324524}, {'X': 0.09532133489847183, 'Y': 0.19063594937324524}, {'X': 0.09532133489847183, 'Y': 0.22668428719043732}, {'X': 0.029274573549628258, 'Y': 0.22668428719043732}]}, 'id': 'b4dd773f-ddb7-407e-9dbc-cf623204e654'}, {'text': 'Number:', 'geometry': {'BoundingBox': {'Width': 0.09247590601444244, 'Height': 0.034948017448186874, 'Left': 0.1015779972076416, 'Top': 0.19128166139125824}, 'Polygon': [{'X': 0.1015779972076416, 'Y': 0.19128166139125824}, {'X': 0.19405390322208405, 'Y': 0.19128166139125824}, {'X': 0.19405390322208405, 'Y': 0.2262296825647354}, {'X': 0.1015779972076416, 'Y': 0.2262296825647354}]}, 'id': '63c1b36b-6b46-4391-b3a5-379247f448f8'}]}, 'value': {'block': {'BlockType': 'KEY_VALUE_SET', 'Confidence': 63.59760284423828, 'Geometry': {'BoundingBox': {'Width': 0.09722070395946503, 'Height': 0.02516728639602661, 'Left': 0.20237421989440918, 'Top': 0.19808898866176605}, 'Polygon': [{'X': 0.20237421989440918, 'Y': 0.19808898866176605}, {'X': 0.2995949387550354, 'Y': 0.19808898866176605}, {'X': 0.2995949387550354, 'Y': 0.22325627505779266}, {'X': 0.20237421989440918, 'Y': 0.22325627505779266}]}, 'Id': 'a8acd770-2d5a-4799-9e0d-17a96b6da85a', 'Relationships': [{'Type': 'CHILD', 'Ids': ['6d3a0b8d-ce64-47d0-a8e8-3a4befb6d1e2']}], 'EntityTypes': ['VALUE']}, 'id': 'a8acd770-2d5a-4799-9e0d-17a96b6da85a', 'text': '555-0100', 'content': [{'text': '555-0100', 'geometry': {'BoundingBox': {'Width': 0.09652186185121536, 'Height': 0.03407157212495804, 'Left': 0.20061562955379486, 'Top': 0.1911606788635254}, 'Polygon': [{'X': 0.20061562955379486, 'Y': 0.1911606788635254}, {'X': 0.2971374988555908, 'Y': 0.1911606788635254}, {'X': 0.2971374988555908, 'Y': 0.22523224353790283}, {'X': 0.20061562955379486, 'Y': 0.22523224353790283}]}, 'id': '6d3a0b8d-ce64-47d0-a8e8-3a4befb6d1e2'}]}}): ==================== Field: Key: Home Address:, Value: 123 Any Street. Any Town. USA ``` -------------------------------- ### Key-Value Set JSON structure Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Example of a KEY_VALUE_SET block and its associated WORD block before processing. ```json { "Confidence": 95.5, "Geometry": {<...>}, "Id": "v1", "Relationships": [{"Type": "CHILD", "Ids": ["c1"]}], "EntityTypes": ["VALUE"], "BlockType": "KEY_VALUE_SET" }, { "Confidence": 99.2610092163086, "TextType": "PRINTED", "Geometry": {<...>}, "Id": "c1", "Text": "2021-Apr-08", "BlockType": "WORD" }, ``` -------------------------------- ### Parse A2I Human Review Response in Python Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/a2i/README.md Demonstrates the workflow from checking for a started human loop to parsing the final document structure using the Document class. ```python # Call Amazon Textract with A2I HumanLoop Config and get JSON response # client = boto3.client('textract') # response = client.analyze_document(Document={...}, FeatureTypes=[...], HumanLoopConfig={...}) # # Check if Human Loop was started # if 'HumanLoopArn' in response['HumanLoopActivationOutput']: # print(f'A human loop has been started with ARN: {response["HumanLoopActivationOutput"]["HumanLoopArn"]}') # # Once human review is complete, retrieve the human review results stored in S3 bucket # a2i_runtime_client = boto3.client('sagemaker-a2i-runtime', REGION) # describe_human_loop_response = a2i_runtime_client.describe_human_loop( # HumanLoopName=human_loop_name # ) # a2i_s3_output_uri = describe_human_loop_response['HumanLoopOutput']['OutputS3Uri'] # Split the bucket and object key from the a2i_s3_output_uri # # Gets the json file published by A2I and returns a deserialized object # s3_content = s3.get_object(Bucket=bucket, Key=output_bucket_key) # a2i_json = json.loads(s3_content['Body'].read().decode('utf-8')) # a2i_response = a2i_json["humanAnswers"][0]["answerContent"]["AWS/Textract/AnalyzeDocument/Forms/V1"] # # Parse JSON response from Textract doc = Document(a2i_response) # Iterate over elements in the document for page in doc.pages: print("PAGE\n====================") print("Form (key/values)\n====================") for field in page.form.fields: k = "" v = "" if(field.key): k = field.key.text if(field.value): v = field.value.text print("Field: Key: {}, Value: {}".format(k,v)) #Get field by key key = "Policy Number:" print("\nGet field by key ({}):\n====================".format(key)) f = page.form.getFieldByKey(key) if(f): print("Field: Key: {}, Value: {}".format(f.key.text, f.value.text)) #Search field by key key = "Policy Number:" print("\nSearch field by key ({}):\n====================".format(key)) fields = page.form.searchFieldsByKey(key) for field in fields: print("Field: Key: {}, Value: {}".format(field.key, field.value)) ``` -------------------------------- ### Import the library Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Supports both CommonJS require and ES module import syntax. ```js // With CommonJS-style require: const { TextractDocument, TextractIdentity } = require("amazon-textract-response-parser"); // Or ES-style module imports: import { TextractDocument, TextractExpense } from "amazon-textract-response-parser"; ``` -------------------------------- ### Use Pipeline via Command Line Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Test pipeline components directly from the command line using piped input. ```bash > amazon-textract --input-document "s3://somebucket/some-multi-page-pdf.pdf" | amazon-textract-pipeline --components add_page_orientation | jq '.Blocks[] | select(.BlockType=="PAGE") | .Custom'm { "Orientation": 7 } { "Orientation": 11 } ... { "Orientation": -7 } { "Orientation": 0 } ``` -------------------------------- ### Use in browser via CDN Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Link the library directly in HTML and access classes via the global trp namespace. ```html ``` -------------------------------- ### Merge tables via command line Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Demonstrates piping a JSON file through the amazon-textract-pipeline CLI to merge tables. ```bash # from the root of the repository cat src-python/tests/data/gib_multi_page_table_merge.json | amazon-textract-pipeline --components merge_tables | amazon-textract --stdin --pretty-print TABLES # compare to cat src-python/tests/data/gib_multi_page_table_merge.json | amazon-textract --stdin --pretty-print TABLES ``` -------------------------------- ### Load Textract response from file in Node.js Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Initializes a TextractDocument by reading and parsing a JSON response file. ```js fs.readFile("./my-analyze-document-response.json", (err, resBuffer) => { if (err) throw err; const doc = new TextractDocument(JSON.parse(resBuffer)); // ... }); ``` -------------------------------- ### Add OCR confidence via command line Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Pipes a JSON file through the pipeline and uses jq to filter for KEY_VALUE_SET blocks. ```bash # from the root of the repository cat "src-python/tests/data/employment-application.json" | amazon-textract-pipeline --components kv_ocr_confidence | jq '.Blocks[] | select(.BlockType=="KEY_VALUE_SET") ' ``` -------------------------------- ### Navigate document hierarchy and iterate content Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Demonstrates using count properties, index-based accessors, and iterators to traverse document pages, lines, and words. ```typescript // Navigate the document hierarchy: console.log(`Opened doc with ${doc.nPages} pages`); console.log( `The first word of the first line is ${doc.pageNumber(1).lineAtIndex(0).wordAtIndex(0).text}` ); // Iterate through content: for (const page of doc.iterPages()) { // (In Textract's output order...) for (const line of page.iterLines()) { for (const word of line.iterWords()) { console.log(word.text); } } } // ...Or get snapshot arrays instead of iterators, if you need: const linesArrsByPage = doc.listPages().map((p) => p.listLines()); ``` -------------------------------- ### Parse and Iterate Textract JSON in Python Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/textract-mapping/README.md Demonstrates how to initialize the Document object from a Textract response and iterate through form fields, including retrieving and searching fields by key. ```python # Call Amazon Textract with A2I HumanLoop Config and get JSON response # client = boto3.client('textract') # response = client.analyze_document(Document={...}, FeatureTypes=[...], HumanLoopConfig={...}) # Parse JSON response from Textract doc = Document(response) # Iterate over elements in the document for page in doc.pages: print("PAGE\n====================") print("Form (key/values)\n====================") for field in page.form.fields: k = "" v = "" if(field.key): k = field.key.text if(field.value): v = field.value.text print("Field: Key: {}, Value: {}".format(k,v)) #Get field by key key = "Policy Number:" print("\nGet field by key ({}):\n====================".format(key)) f = page.form.getFieldByKey(key) if(f): print("Field: Key: {}, Value: {}".format(f.key.text, f.value.text)) #Search field by key key = "Policy Number:" print("\nSearch field by key ({}):\n====================".format(key)) fields = page.form.searchFieldsByKey(key) for field in fields: print("Field: Key: {}, Value: {}".format(field.key, field.value)) ``` -------------------------------- ### Upload File to S3 Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-csharp/README.md AWS CLI command to upload a local image file to a specified S3 bucket. ```bash aws s3 cp test-files/employmentapp.png s3:// ``` -------------------------------- ### Load Textract response with TypeScript typecasting Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Demonstrates using the AWS SDK to fetch an expense analysis and typecasting the response for compatibility with the parser. ```typescript import { ApiAnalyzeExpenseResponse } from "amazon-textract-response-parser"; import { TextractClient, AnalyzeExpenseCommand } from "@aws-sdk/client-textract"; const textract = new TextractClient({}); async function main() { const textractResponse = await textract.send( new AnalyzeExpenseCommand({ Document: { Bytes: await fs.readFile("...") }, }) ); const expense = new TextractExpense((textractResponse as unknown) as ApiAnalyzeExpenseResponse); } ``` -------------------------------- ### Configuring Reading Order and Heuristics Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Retrieve text in reading order using either the Layout API or client-side heuristics with configurable parameters. ```typescript import { ReadingOrderLayoutMode } from "amazon-textract-response-parser"; // By default, we automatically use `Layout` when it's available and heuristics when it's not: let textInReadingOrder: string = page.getTextInReadingOrder(); // Just generate text let pseudoParas = page.getLineClustersInReadingOrder(); // You can force use of `Layout` (throwing an error if none available): let layText = page.getTextInReadingOrder({ useLayout: ReadingOrderLayoutMode.RequireLayout }); // Or fine-tune heuristic parameters: let layParas = page.getLineClustersInReadingOrder({ colHOverlapThresh = 0.75, paraVDistTol = 0.8, // ... useLayout: ReadingOrderLayoutMode.IgnoreLayout, }); // Lines are clustered by "paragraph"/layout element: for (const pseudoParagraph of pseudoParas) { for (const line of pseudoParagraph) { console.log(line.text); } console.log(); // Print a gap between "paragraphs" } ``` -------------------------------- ### Render Textract documents to HTML Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Generate HTML representations for individual document components or entire pages. Requires Layout analysis to be enabled for accurate sequencing. ```typescript // Render HTML for individual components: console.log(page.listTables[0].html()); // ...Or for whole pages/documents: const docHtml = doc.html(); fs.writeFile("./my-doc.html", docHtml, (err) => {}); ``` -------------------------------- ### Initialize and process identity document response Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Use the TextractIdentity class to wrap the response from the AnalyzeIDCommand. Requires the ApiAnalyzeIdResponse type for proper initialization. ```typescript import { ApiAnalyzeIdResponse, TextractIdentity } from "amazon-textract-response-parser"; import { TextractClient, AnalyzeIDCommand } from "@aws-sdk/client-textract"; const textract = new TextractClient({}); async function main() { const textractResponse = await textract.send( new AnalyzeIDCommand({ Document: { Bytes: await fs.readFile("...") }, }) ); const identity = new TextractIdentity((textractResponse as unknown) as ApiAnalyzeIdResponse); } ``` -------------------------------- ### Accessing Layout Analysis Components Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Iterate through layout items in reading order and filter specific block types using the page.layout collection. ```typescript // Loop through content in implied reading order (from Layout API): page.layout.listItems().forEach((layItem) => { console.log(layItem.blockType); // There are different kinds of Layout Item const textLines = layItem.listTextLines(); // All Layout* items can be queried for text LINEs const children = layItem.listContent(); // Usually text LINEs, but sometimes other Layout* items console.log(layItem.text + "\n"); // ...Or you can just pull up the text }); // Filtering by content type is also supported: for (const layItem of page.layout.listItems({ skipBlockTypes: [ ApiBlockType.LayoutHeader, ApiBlockType.LayoutFooter, ApiBlockType.LayoutPageNumber ], })) { console.log(layItem.text); } ``` -------------------------------- ### Parse Textract JSON with trp Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Initializes a Document object from a Textract response and iterates through pages, lines, words, tables, and form fields. ```python from trp import Document doc = Document(response) # Iterate over elements in the document for page in doc.pages: # Print lines and words for line in page.lines: print("Line: {}--{}".format(line.text, line.confidence)) for word in line.words: print("Word: {}--{}".format(word.text, word.confidence)) # Print tables for table in page.tables: for r, row in enumerate(table.rows): for c, cell in enumerate(row.cells): print("Table[{}][{}] = {}-{}".format(r, c, cell.text, cell.confidence)) # Print fields for field in page.form.fields: print("Field: Key: {}, Value: {}".format(field.key.text, field.value.text)) # Get field by key key = "Phone Number:" field = page.form.getFieldByKey(key) if(field): print("Field: Key: {}, Value: {}".format(field.key, field.value)) # Search fields by key key = "address" fields = page.form.searchFieldsByKey(key) for field in fields: print("Field: Key: {}, Value: {}".format(field.key, field.value)) ``` -------------------------------- ### Parse Forms in C# Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/README.md Iterate through document pages to extract lines, words, and form fields using the C# library. ```csharp document.Pages.ForEach(page => { Console.WriteLine("Print Lines and Words:"); page.Lines.ForEach(line => { Console.WriteLine("{0}--{1}", line.Text, line.Confidence); line.Words.ForEach(word => { Console.WriteLine("{0}--{1}", word.Text, word.Confidence); }); }); Console.WriteLine("Print Fields:"); page.Form.Fields.ForEach(f => { Console.WriteLine("Field: Key: {0}, Value {1}", f.Key, f.Value); }); Console.WriteLine("Get Field by Key:"); var key = "Phone Number:"; var field = page.Form.GetFieldByKey(key); if(field != null) { Console.WriteLine("Field: Key: {0}, Value: {1}", field.Key, field.Value); } }); ``` -------------------------------- ### Order Blocks by Geometry Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Reorder document blocks by their y-axis geometry to ensure logical reading order. ```bash # the sample code below makes use of the amazon-textract-caller python -m pip install amazon-textract-caller ``` ```python from textractcaller.t_call import call_textract, Textract_Features from trp.trp2 import TDocument, TDocumentSchema from trp.t_pipeline import order_blocks_by_geo import trp import json j = call_textract(input_document="path_to_some_document (PDF, JPEG, PNG)", features=[Textract_Features.FORMS, Textract_Features.TABLES]) # the t_doc will be not ordered t_doc = TDocumentSchema().load(j) # the ordered_doc has elements ordered by y-coordinate (top to bottom of page) ordered_doc = order_blocks_by_geo(t_doc) # send to trp for further processing logic trp_doc = trp.Document(TDocumentSchema().dump(ordered_doc)) ``` -------------------------------- ### Accessing Fields by Page Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Retrieve fields from the document level or specific page objects. ```typescript const fieldByDoc = doc.form.getFieldByKey("Address"); console.log(`Detected Address on page ${fieldByDoc.parentPage.pageNumber}`); const page = doc.pageNumber(1); const fieldByPage = page.form.getFieldByKey("Address"); ``` -------------------------------- ### Process expense documents with TextractExpense Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Use the TextractExpense class to iterate through expense documents, line items, and fields, or search for specific summary fields by type. ```typescript const expense = new TextractExpense(textractResponse); // Iterate through content: console.log(`Found ${expense.nDocs} expense docs in file`); const expenseDoc = [...expense.iterDocs()][0]; for (const group of expenseDoc.iterLineItemGroups()) { for (const item of group.iterLineItems()) { console.log(`Found line item with ${item.nFields} fields`); for (const field of item.iterFields()) { ... } } } // Get snapshot arrays instead of iterators, if you need: const summaryFieldsArrByDoc = expense.listDocs().map((doc) => doc.listSummaryFields()); const linesArrsByPage = doc.listPages().map((p) => p.listLines()) // Retrieve item fields by their tagged 'type': const vendorNameFields = expenseDoc.searchSummaryFieldsByType("VENDOR_NAME"); console.log(`Found ${vendorNameFields.length} vendor name fields in doc summary`); console.log(vendorNameFields[0].fieldType.text); // "VENDOR_NAME" console.log(vendorNameFields[0].value.text); // e.g. "Amazon.com" ``` -------------------------------- ### Access and search Amazon Textract queries Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Shows how to retrieve query results by alias or substring search within page-level query objects. ```typescript doc.listPages().forEach((page) => { // Log a quick human-readable overview of queries & answers: console.log(page.queries.str()); // Get a query (and its top result's text) by exact alias: const customer = page.queries.getQueryByAlias("customer_name")?.topResult?.text; // Get possible results of a query from most to least confident: const shippingAddrCandidates = page.queries.getQueryByAlias("shipping_addr")?.listResultsByConfidence() || []; const shippingAddrTopConf = shippingAddrCandidates[0].confidence; // Seaching matches queries e.g. 'What is the Shipping Address?', 'FIND THE BILLING ADDRESS', etc const addrQueries = page.queries.searchQueriesByQuestion("address"); }); ``` -------------------------------- ### Parse Tables in C# Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/README.md Iterate through document pages and their respective tables to access cell text and confidence scores. ```csharp document.Pages.ForEach(page => { page.Tables.ForEach(table => { var r = 0; table.Rows.ForEach(row => { r++; var c = 0; row.Cells.ForEach(cell => { c++; Console.WriteLine("Table [{0}][{1}] = {2}--{3}", r, c, cell.Text, cell.Confidence); }); }); }); }); ``` -------------------------------- ### Navigating Tables Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Access table cells by index or iterate through rows and cells. Merged cells are handled by default. ```typescript console.log(page.nTables); const table = page.tableAtIndex(0); // Index cells by row, column, or both: const headerStrs = table.cellsAt(1, null)?.map(cell => cell.text); const firstColCells = table.cellsAt(null, 1); const targetCell = table.cellAt(2, 4); // Iterate over rows/cells: for (const row of table.iterRows()) { for (const cell of row.iterCells()) { console.log(cell.text); } } ``` -------------------------------- ### Segment document headers and footers Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Use heuristic functions to separate page content into header, body, and footer sections. ```typescript const segmented = page.getLinesByLayoutArea( true // (Also try to sort lines in reading order) ); console.log("---- HEADER:") console.log(segmented.header.map((l) => l.text).join("\n")); console.log("\n---- CONTENT:") console.log(segmented.content.map((l) => l.text).join("\n")); console.log("\n---- FOOTER:") console.log(segmented.footer.map((l) => l.text).join("\n")); ``` -------------------------------- ### Querying Form Fields Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Access form fields by key or search for keys case-insensitively. Use getOcrConfidence() for aggregated text confidence instead of structure confidence. ```typescript console.log(doc.form.nFields); const fields = doc.form.listFields(); // Exact match: const addr = doc.form.getFieldByKey("Address").value?.text; // Search key containing (case-insensitive): const addresses = doc.form.searchFieldsByKey("address"); addresses.forEach((addrField) => { console.log(addrField.key.text); }); ``` -------------------------------- ### Detect signatures in document pages Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Access signature counts and bounding box geometry for detected signatures on specific pages. ```typescript // e.g. print number of signatures detected by page: doc.listPages() .forEach((page, ix) => { console.log(`${page.nSignatures} signatures on page ${ix+1}`); }); // ...Or get the position of the first signature on the first page: const bbox = doc.pageNumber(1).listSignatures()[0].geometry.boundingBox; ``` -------------------------------- ### Reconciling Layout with Forms and Tables Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Traverse layout items to access associated form fields or table data when those analyses are enabled. ```typescript import { ApiBlockType, LayoutKeyValue, LayoutTable } from "amazon-textract-response-parser"; page.layout.listItems().forEach((layItem) => { if (layItem.blockType === ApiBlockType.LayoutKeyValue) { const fields = (layItem as LayoutKeyValue).listFields(); // Probably multiple fields.forEach((field) => console.log(field.key.text)); } else if (layItem.blockType === ApiBlockType.LayoutTable) { const tables = (layItem as LayoutTable).listTables(); // Probably just 1 tables.forEach((table) => console.log(table.nCells)); } }); ``` -------------------------------- ### Key-Value Set with OCR confidence Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md The JSON structure after applying the KV_OCR_Confidence component, showing the added Custom field. ```json { "Confidence": 95.5, "Geometry": {<...>}, "Id": "v1", "Relationships": [{"Type": "CHILD", "Ids": ["c1"]}], "EntityTypes": ["VALUE"], "BlockType": "KEY_VALUE_SET", "Custom": {"OCRConfidence": {"mean": 99.2610092163086, "min": 99.2610092163086}} }, { "Confidence": 99.2610092163086, "TextType": "PRINTED", "Geometry": {<...>}, "Id": "c1", "Text": "2021-Apr-08", "BlockType": "WORD" }, ``` -------------------------------- ### Signature Detection Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Methods for accessing signature information within a document page. ```APIDOC ## Signature Detection Methods ### doc.listPages() Returns an array of page objects. Each page object contains an `nSignatures` property indicating the number of signatures detected. ### doc.pageNumber(n).listSignatures() Returns an array of signature objects for a specific page. Each signature object contains a `geometry.boundingBox` property. ``` -------------------------------- ### Add OCR confidence to key-value pairs in Python Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Uses the add_kv_ocr_confidence function to inject OCR confidence scores into the TDocument structure. ```python from trp.t_pipeline import add_kv_ocr_confidence import trp.trp2 as t2 j = t_document: t2.TDocument = t2.TDocumentSchema().load(j) t_document = add_kv_ocr_confidence(t_document) # further processing ``` -------------------------------- ### Merge multi-page tables in Python Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Uses the pipeline_merge_tables function to combine tables spanning multiple pages. Requires a TDocument object loaded from Textract JSON. ```python from trp.t_pipeline import pipeline_merge_tables import trp.trp2 as t2 j = t_document: t2.TDocument = t2.TDocumentSchema().load(j) t_document = pipeline_merge_tables(t_document, MergeOptions.MERGE, None, HeaderFooterType.NONE) ``` -------------------------------- ### TextractExpense Class Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Methods for processing Amazon Textract Expense (invoice and receipt) results. ```APIDOC ## TextractExpense Class Methods ### new TextractExpense(textractResponse) Initializes the parser with a raw Textract response. ### expense.iterDocs() Returns an iterator for expense documents found in the file. ### expense.listDocs() Returns an array of expense documents. ### expenseDoc.iterLineItemGroups() Returns an iterator for line item groups within an expense document. ### expenseDoc.searchSummaryFieldsByType(type) Searches for summary fields by their tagged type (e.g., 'VENDOR_NAME'). Returns an array of field objects. ``` -------------------------------- ### Table Data Extraction Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Methods for navigating tables, accessing cells by index, and iterating through rows. ```APIDOC ## Table Navigation Methods ### tableAtIndex(index: number) Retrieves a table object at the specified index. ### cellsAt(row: number | null, col: number | null, options?: {ignoreMerged: boolean}) Retrieves cells by row or column index. Supports options to handle merged cells. ### cellAt(row: number, col: number) Retrieves a specific cell at the given row and column coordinates. ### iterRows(options?: {repeatMultiRowCells: boolean}) Returns an iterator for rows in the table, with optional configuration for handling multi-row cells. ``` -------------------------------- ### Identifying Table Entity Types Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Use entity types to identify specific table components like column headers. ```typescript import { ApiTableCellEntityType, ApiTableEntityType } from "amazon-textract-response-parser"; const isSemiStruct = table.tableType === ApiTableEntityType.SemiStructuredTable; const colHeaders = table.rowAt(1).listCells() .filter((c) => c.hasEntityTypes(ApiTableCellEntityType.ColumnHeader)); ``` -------------------------------- ### Deserialize and Serialize Textract JSON Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Convert Textract JSON responses into object representations and back to JSON using the marshmallow-based schema. ```python # j holds the Textract JSON dict from trp.trp2 import TDocument, TDocumentSchema t_doc = TDocumentSchema().load(j) ``` ```python from trp.trp2 import TDocument, TDocumentSchema t_doc = TDocumentSchema().dump(t_doc) ``` -------------------------------- ### Form Data Extraction Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Methods for querying and retrieving form fields by key or searching within the document. ```APIDOC ## Form Data Methods ### getFieldByKey(key: string) Retrieves a field by an exact key match. ### searchFieldsByKey(key: string) Returns an array of fields where the key contains the provided string (case-insensitive). ### listFields() Returns a list of all fields in the form. ### isCheckbox Boolean property indicating if the field value is a selection element. ``` -------------------------------- ### Filter content during HTML rendering Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Customize the HTML output by skipping specific block types or explicitly allow-listing desired elements. ```typescript // Most commonly, you'll `skip` high-level layout elements like `LayoutHeader`: const docHtml = doc.html({ skipBlockTypes: [ ApiBlockType.LayoutHeader, ApiBlockType.LayoutFooter, ApiBlockType.LayoutPageNumber ], }); // Skipping lower-level blocks is also possible, but can produce weird results: const docHtmlNoCellsOrSelectors = doc.html({ skipBlockTypes: [ApiBlockType.Cell, ApiBlockType.SelectionElement], }); // Allow-listing is also possible, but you should include *everything* relevant: const docTablesHtml = doc.html({ includeBlockTypes: [ ApiBlockType.Page, ApiBlockType.LayoutTable, ApiBlockType.Table, ApiBlockType.Cell, ApiBlockType.SelectionElement, ApiBlockType.Word, ], }); ``` -------------------------------- ### Calculate Page Orientation Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Calculate and add page orientation degrees as a custom field to the Textract JSON response. ```python from trp.t_pipeline import add_page_orientation import trp.trp2 as t2 import trp as t1 # assign the Textract JSON dict to j j = t_document: t2.TDocument = t2.TDocumentSchema().load(j) t_document = add_page_orientation(t_document) doc = t1.Document(t2.TDocumentSchema().dump(t_document)) # page orientation can be read now for each page for page in doc.pages: print(page.custom['PageOrientationBasedOnWords']) ``` -------------------------------- ### Configuring Merged Cell Handling Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Adjust how merged cells are processed during iteration or indexing. ```typescript // Iterate over rows repeating any cells spanning multiple rows: for (const row of table.iterRows({repeatMultiRowCells: true})) {} // Return split sub-cells instead of merged cells when indexing: const firstColCellFragments = table.cellsAt(null, 1, {ignoreMerged: true}); ``` -------------------------------- ### Calculate page text skew Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Determine the average orientation angle of text on a page to validate document quality. ```typescript // Check the average angle/skew of detected text: const skew = page.getModalWordOrientationDegrees(); ``` -------------------------------- ### Deserialize and Serialize Textract AnalyzeId JSON Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-python/README.md Handle AnalyzeId specific JSON responses. ```python # j holds the Textract JSON from trp.trp2_analyzeid import TAnalyzeIdDocument, TAnalyzeIdDocumentSchema t_doc = TAnalyzeIdDocumentSchema().load(json.loads(j)) ``` ```python from trp.trp2_analyzeid import TAnalyzeIdDocument, TAnalyzeIdDocumentSchema t_doc = TAnalyzeIdDocumentSchema().dump(t_doc) ``` -------------------------------- ### Access identity document fields and types Source: https://github.com/aws-samples/amazon-textract-response-parser/blob/master/src-js/README.md Utilize IdDocumentType and IdFieldType enumerations to filter and extract specific data from identity documents. ```typescript import { IdDocumentType, IdFieldType } from "amazon-textract-response-parser"; const idDoc = identity.getDocAtIndex(0); // (Or iterate, list docs in a result) if (idDoc.idType === IdDocumentType.Passport) { // Fetch fields by known type: const passNumField = idDoc.getFieldByType(IdFieldType.DocumentNumber); console.log( `Passport number ${passNumField.value}, confidence ${passNumField.valueConfidence}%` ); } else if (idDoc.idType === IdDocumentType.DrivingLicense) { // ...Or list or iterate the document's fields: for (const field of idDoc.iterFields()) { console.log(`${field.fieldTypeRaw}: ${field.valueRaw}`); } } else { // Produce human-readable representations of fields, documents, or whole responses: console.log(idDoc.str()); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.