Skip to content

Commit 3546171

Browse files
author
Yalin Li
authored
[DI] Rename base64_source (#34634)
1 parent c8c3884 commit 3546171

File tree

6 files changed

+529
-11
lines changed

6 files changed

+529
-11
lines changed

sdk/documentintelligence/azure-ai-documentintelligence/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
### Breaking Changes
1616

1717
- Changed property name from `items` to `items_property` in model `DocumentFieldSchema` and `DocumentList`.
18+
- Changed property name from `base64_source` to `bytes_source` in model `AnalyzeDocumentRequest` and `ClassifyDocumentRequest`.
1819

1920
### Bugs Fixed
2021

sdk/documentintelligence/azure-ai-documentintelligence/azure/ai/documentintelligence/models/_models.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,15 @@ class AnalyzeDocumentRequest(_model_base.Model):
122122
123123
:ivar url_source: Document URL to analyze. Either urlSource or base64Source must be specified.
124124
:vartype url_source: str
125-
:ivar base64_source: Base64 encoding of the document to analyze. Either urlSource or
125+
:ivar bytes_source: Base64 encoding of the document to analyze. Either urlSource or
126126
base64Source
127127
must be specified.
128-
:vartype base64_source: bytes
128+
:vartype bytes_source: bytes
129129
"""
130130

131131
url_source: Optional[str] = rest_field(name="urlSource")
132132
"""Document URL to analyze. Either urlSource or base64Source must be specified."""
133-
base64_source: Optional[bytes] = rest_field(name="base64Source", format="base64")
133+
bytes_source: Optional[bytes] = rest_field(name="base64Source", format="base64")
134134
"""Base64 encoding of the document to analyze. Either urlSource or base64Source
135135
must be specified."""
136136

@@ -139,7 +139,7 @@ def __init__(
139139
self,
140140
*,
141141
url_source: Optional[str] = None,
142-
base64_source: Optional[bytes] = None,
142+
bytes_source: Optional[bytes] = None,
143143
):
144144
...
145145

@@ -642,15 +642,15 @@ class ClassifyDocumentRequest(_model_base.Model):
642642
:ivar url_source: Document URL to classify. Either urlSource or base64Source must be
643643
specified.
644644
:vartype url_source: str
645-
:ivar base64_source: Base64 encoding of the document to classify. Either urlSource or
645+
:ivar bytes_source: Base64 encoding of the document to classify. Either urlSource or
646646
base64Source
647647
must be specified.
648-
:vartype base64_source: bytes
648+
:vartype bytes_source: bytes
649649
"""
650650

651651
url_source: Optional[str] = rest_field(name="urlSource")
652652
"""Document URL to classify. Either urlSource or base64Source must be specified."""
653-
base64_source: Optional[bytes] = rest_field(name="base64Source", format="base64")
653+
bytes_source: Optional[bytes] = rest_field(name="base64Source", format="base64")
654654
"""Base64 encoding of the document to classify. Either urlSource or base64Source
655655
must be specified."""
656656

@@ -659,7 +659,7 @@ def __init__(
659659
self,
660660
*,
661661
url_source: Optional[str] = None,
662-
base64_source: Optional[bytes] = None,
662+
bytes_source: Optional[bytes] = None,
663663
):
664664
...
665665

sdk/documentintelligence/azure-ai-documentintelligence/azure/ai/documentintelligence/models/_patch.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,41 @@
66
77
Follow our quickstart for examples: https://aka.ms/azsdk/python/dpcodegen/python/customize
88
"""
9-
from typing import List
9+
from typing import List, Optional
10+
from ._models import (
11+
AnalyzeDocumentRequest as GeneratedAnalyzeDocumentRequest,
12+
ClassifyDocumentRequest as GeneratedClassifyDocumentRequest,
13+
)
14+
from .._model_base import rest_field
1015

11-
__all__: List[str] = [] # Add all objects you want publicly available to users at this package level
16+
17+
class AnalyzeDocumentRequest(GeneratedAnalyzeDocumentRequest):
18+
"""Document analysis parameters.
19+
20+
:ivar url_source: Document URL to analyze. Either url_source or bytes_source must be specified.
21+
:vartype url_source: str
22+
:ivar bytes_source: Document bytes to analyze. Either url_source or bytes_source must be specified.
23+
:vartype bytes_source: bytes
24+
"""
25+
26+
bytes_source: Optional[bytes] = rest_field(name="base64Source", format="base64")
27+
"""Document bytes to analyze. Either url_source or bytes_source must be specified."""
28+
29+
30+
class ClassifyDocumentRequest(GeneratedClassifyDocumentRequest):
31+
"""Document classification parameters.
32+
33+
:ivar url_source: Document URL to classify. Either url_source or bytes_source must be
34+
specified.
35+
:vartype url_source: str
36+
:ivar bytes_source: Document bytes to classify. Either url_source or bytes_source must be specified.
37+
:vartype bytes_source: bytes
38+
"""
39+
40+
bytes_source: Optional[bytes] = rest_field(name="base64Source", format="base64")
41+
"""Document bytes to classify. Either url_source or bytes_source must be specified."""
42+
43+
__all__: List[str] = ["AnalyzeDocumentRequest", "ClassifyDocumentRequest"] # Add all objects you want publicly available to users at this package level
1244

1345

1446
def patch_sdk():
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
# coding: utf-8
2+
3+
# -------------------------------------------------------------------------
4+
# Copyright (c) Microsoft Corporation. All rights reserved.
5+
# Licensed under the MIT License. See License.txt in the project root for
6+
# license information.
7+
# --------------------------------------------------------------------------
8+
9+
"""
10+
FILE: sample_analyze_invoices_from_bytes_source_async.py
11+
12+
DESCRIPTION:
13+
This sample demonstrates how to analyze invoices.
14+
15+
See fields found on a invoice here:
16+
https://aka.ms/azsdk/documentintelligence/invoicefieldschema
17+
18+
USAGE:
19+
python sample_analyze_invoices_from_bytes_source_async.py
20+
21+
Set the environment variables with your own values before running the sample:
22+
1) DOCUMENTINTELLIGENCE_ENDPOINT - the endpoint to your Document Intelligence resource.
23+
2) DOCUMENTINTELLIGENCE_API_KEY - your Document Intelligence API key.
24+
"""
25+
26+
import os
27+
import asyncio
28+
29+
30+
async def analyze_invoice():
31+
path_to_sample_documents = os.path.abspath(
32+
os.path.join(
33+
os.path.abspath(__file__),
34+
"..",
35+
"..",
36+
"./sample_forms/forms/sample_invoice.jpg",
37+
)
38+
)
39+
40+
from azure.core.credentials import AzureKeyCredential
41+
from azure.ai.documentintelligence.aio import DocumentIntelligenceClient
42+
from azure.ai.documentintelligence.models import AnalyzeResult, AnalyzeDocumentRequest
43+
44+
endpoint = os.environ["DOCUMENTINTELLIGENCE_ENDPOINT"]
45+
key = os.environ["DOCUMENTINTELLIGENCE_API_KEY"]
46+
47+
document_intelligence_client = DocumentIntelligenceClient(endpoint=endpoint, credential=AzureKeyCredential(key))
48+
async with document_intelligence_client:
49+
with open(path_to_sample_documents, "rb") as f:
50+
poller = await document_intelligence_client.begin_analyze_document(
51+
"prebuilt-invoice", analyze_request=AnalyzeDocumentRequest(bytes_source=f.read()), locale="en-US"
52+
)
53+
invoices: AnalyzeResult = await poller.result()
54+
55+
if invoices.documents:
56+
for idx, invoice in enumerate(invoices.documents):
57+
print(f"--------Analyzing invoice #{idx + 1}--------")
58+
if invoice.fields:
59+
vendor_name = invoice.fields.get("VendorName")
60+
if vendor_name:
61+
print(f"Vendor Name: {vendor_name.get('content')} has confidence: {vendor_name.get('confidence')}")
62+
vendor_address = invoice.fields.get("VendorAddress")
63+
if vendor_address:
64+
print(
65+
f"Vendor Address: {vendor_address.get('content')} has confidence: {vendor_address.get('confidence')}"
66+
)
67+
vendor_address_recipient = invoice.fields.get("VendorAddressRecipient")
68+
if vendor_address_recipient:
69+
print(
70+
f"Vendor Address Recipient: {vendor_address_recipient.get('content')} has confidence: {vendor_address_recipient.get('confidence')}"
71+
)
72+
customer_name = invoice.fields.get("CustomerName")
73+
if customer_name:
74+
print(
75+
f"Customer Name: {customer_name.get('content')} has confidence: {customer_name.get('confidence')}"
76+
)
77+
customer_id = invoice.fields.get("CustomerId")
78+
if customer_id:
79+
print(f"Customer Id: {customer_id.get('content')} has confidence: {customer_id.get('confidence')}")
80+
customer_address = invoice.fields.get("CustomerAddress")
81+
if customer_address:
82+
print(
83+
f"Customer Address: {customer_address.get('content')} has confidence: {customer_address.get('confidence')}"
84+
)
85+
customer_address_recipient = invoice.fields.get("CustomerAddressRecipient")
86+
if customer_address_recipient:
87+
print(
88+
f"Customer Address Recipient: {customer_address_recipient.get('content')} has confidence: {customer_address_recipient.get('confidence')}"
89+
)
90+
invoice_id = invoice.fields.get("InvoiceId")
91+
if invoice_id:
92+
print(f"Invoice Id: {invoice_id.get('content')} has confidence: {invoice_id.get('confidence')}")
93+
invoice_date = invoice.fields.get("InvoiceDate")
94+
if invoice_date:
95+
print(
96+
f"Invoice Date: {invoice_date.get('content')} has confidence: {invoice_date.get('confidence')}"
97+
)
98+
invoice_total = invoice.fields.get("InvoiceTotal")
99+
if invoice_total:
100+
print(
101+
f"Invoice Total: {invoice_total.get('content')} has confidence: {invoice_total.get('confidence')}"
102+
)
103+
due_date = invoice.fields.get("DueDate")
104+
if due_date:
105+
print(f"Due Date: {due_date.get('content')} has confidence: {due_date.get('confidence')}")
106+
purchase_order = invoice.fields.get("PurchaseOrder")
107+
if purchase_order:
108+
print(
109+
f"Purchase Order: {purchase_order.get('content')} has confidence: {purchase_order.get('confidence')}"
110+
)
111+
billing_address = invoice.fields.get("BillingAddress")
112+
if billing_address:
113+
print(
114+
f"Billing Address: {billing_address.get('content')} has confidence: {billing_address.get('confidence')}"
115+
)
116+
billing_address_recipient = invoice.fields.get("BillingAddressRecipient")
117+
if billing_address_recipient:
118+
print(
119+
f"Billing Address Recipient: {billing_address_recipient.get('content')} has confidence: {billing_address_recipient.get('confidence')}"
120+
)
121+
shipping_address = invoice.fields.get("ShippingAddress")
122+
if shipping_address:
123+
print(
124+
f"Shipping Address: {shipping_address.get('content')} has confidence: {shipping_address.get('confidence')}"
125+
)
126+
shipping_address_recipient = invoice.fields.get("ShippingAddressRecipient")
127+
if shipping_address_recipient:
128+
print(
129+
f"Shipping Address Recipient: {shipping_address_recipient.get('content')} has confidence: {shipping_address_recipient.get('confidence')}"
130+
)
131+
print("Invoice items:")
132+
items = invoice.fields.get("Items")
133+
if items:
134+
for idx, item in enumerate(items.get("valueArray")):
135+
print(f"...Item #{idx + 1}")
136+
item_description = item.get("valueObject").get("Description")
137+
if item_description:
138+
print(
139+
f"......Description: {item_description.get('content')} has confidence: {item_description.get('confidence')}"
140+
)
141+
item_quantity = item.get("valueObject").get("Quantity")
142+
if item_quantity:
143+
print(
144+
f"......Quantity: {item_quantity.get('content')} has confidence: {item_quantity.get('confidence')}"
145+
)
146+
unit = item.get("valueObject").get("Unit")
147+
if unit:
148+
print(f"......Unit: {unit.get('content')} has confidence: {unit.get('confidence')}")
149+
unit_price = item.get("valueObject").get("UnitPrice")
150+
if unit_price:
151+
unit_price_code = (
152+
unit_price.get("valueCurrency").get("currencyCode")
153+
if unit_price.get("valueCurrency").get("currencyCode")
154+
else ""
155+
)
156+
print(
157+
f"......Unit Price: {unit_price.get('content')}{unit_price_code} has confidence: {unit_price.get('confidence')}"
158+
)
159+
product_code = item.get("valueObject").get("ProductCode")
160+
if product_code:
161+
print(
162+
f"......Product Code: {product_code.get('content')} has confidence: {product_code.get('confidence')}"
163+
)
164+
item_date = item.get("valueObject").get("Date")
165+
if item_date:
166+
print(
167+
f"......Date: {item_date.get('content')} has confidence: {item_date.get('confidence')}"
168+
)
169+
tax = item.get("valueObject").get("Tax")
170+
if tax:
171+
print(f"......Tax: {tax.get('content')} has confidence: {tax.get('confidence')}")
172+
amount = item.get("valueObject").get("Amount")
173+
if amount:
174+
print(f"......Amount: {amount.get('content')} has confidence: {amount.get('confidence')}")
175+
subtotal = invoice.fields.get("SubTotal")
176+
if subtotal:
177+
print(f"Subtotal: {subtotal.get('content')} has confidence: {subtotal.get('confidence')}")
178+
total_tax = invoice.fields.get("TotalTax")
179+
if total_tax:
180+
print(f"Total Tax: {total_tax.get('content')} has confidence: {total_tax.get('confidence')}")
181+
previous_unpaid_balance = invoice.fields.get("PreviousUnpaidBalance")
182+
if previous_unpaid_balance:
183+
print(
184+
f"Previous Unpaid Balance: {previous_unpaid_balance.get('content')} has confidence: {previous_unpaid_balance.get('confidence')}"
185+
)
186+
amount_due = invoice.fields.get("AmountDue")
187+
if amount_due:
188+
print(f"Amount Due: {amount_due.get('content')} has confidence: {amount_due.get('confidence')}")
189+
service_start_date = invoice.fields.get("ServiceStartDate")
190+
if service_start_date:
191+
print(
192+
f"Service Start Date: {service_start_date.get('content')} has confidence: {service_start_date.get('confidence')}"
193+
)
194+
service_end_date = invoice.fields.get("ServiceEndDate")
195+
if service_end_date:
196+
print(
197+
f"Service End Date: {service_end_date.get('content')} has confidence: {service_end_date.get('confidence')}"
198+
)
199+
service_address = invoice.fields.get("ServiceAddress")
200+
if service_address:
201+
print(
202+
f"Service Address: {service_address.get('content')} has confidence: {service_address.get('confidence')}"
203+
)
204+
service_address_recipient = invoice.fields.get("ServiceAddressRecipient")
205+
if service_address_recipient:
206+
print(
207+
f"Service Address Recipient: {service_address_recipient.get('content')} has confidence: {service_address_recipient.get('confidence')}"
208+
)
209+
remittance_address = invoice.fields.get("RemittanceAddress")
210+
if remittance_address:
211+
print(
212+
f"Remittance Address: {remittance_address.get('content')} has confidence: {remittance_address.get('confidence')}"
213+
)
214+
remittance_address_recipient = invoice.fields.get("RemittanceAddressRecipient")
215+
if remittance_address_recipient:
216+
print(
217+
f"Remittance Address Recipient: {remittance_address_recipient.get('content')} has confidence: {remittance_address_recipient.get('confidence')}"
218+
)
219+
220+
221+
async def main():
222+
await analyze_invoice()
223+
224+
225+
if __name__ == "__main__":
226+
from azure.core.exceptions import HttpResponseError
227+
from dotenv import find_dotenv, load_dotenv
228+
229+
try:
230+
load_dotenv(find_dotenv())
231+
asyncio.run(main())
232+
except HttpResponseError as error:
233+
# Examples of how to check an HttpResponseError
234+
# Check by error code:
235+
if error.error is not None:
236+
if error.error.code == "InvalidImage":
237+
print(f"Received an invalid image error: {error.error}")
238+
if error.error.code == "InvalidRequest":
239+
print(f"Received an invalid request error: {error.error}")
240+
# Raise the error again after printing it
241+
raise
242+
# If the inner error is None and then it is possible to check the message to get more information:
243+
if "Invalid request".casefold() in error.message.casefold():
244+
print(f"Uh-oh! Seems there was an invalid request: {error}")
245+
# Raise the error again
246+
raise

0 commit comments

Comments
 (0)