Azure / Azure/azure-sdk-for-python
Document Intelligence Batch API InvalidManagedIdentity when using SAS URLs
- Dominant language
- Python
- Stars
- 5.6k
- Forks
- 3.4k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 193
Description
- **Package Name**: azure-ai-documentintelligence
- **Package Version**: 1.0.2
- **Operating System**: Windows
- **Python Version**: 3.13.5
**Describe the bug**
When using the [batch API ](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/documentintelligence/azure-ai-documentintelligence/samples/sample_analyze_batch_documents.py) with SAS URLs, I get a `InvalidManagedIdentity` error. It works when analyzing a single pdf.
**To Reproduce**
Steps to reproduce the behavior:
1. Create containers
2. Generate SAS urls
```python
from azure.storage.blob import BlobServiceClient
client = BlobServiceClient.from_connection_string(connection_string)
def generate_container(container_name: str):
try:
container_client = client.create_container(name=container_name)
print(f"Container '{container_name}' created.")
except Exception as e:
container_client = client.get_container_client(container_name)
print(f"Error creating container '{container_name}': {e}")
sas_token = generate_container_sas(
account_name=client.account_name,
container_name="test-batch-api",
account_key=client.credential.account_key,
permission=ContainerSasPermissions(
read=True, write=True, delete=True, list=True, delete_previous_version=True, tag=True
),
expiry=datetime.datetime.now() + datetime.timedelta(days=1),
)
container_sas_url = f"{container_client.url}?{sas_token}"
return container_sas_url
generate_container("test-batch-api2")
```
3. Call the Document Intelligence batch API
```python
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import (
AnalyzeBatchDocumentsRequest,
AzureBlobContentSource,
)
import os
from azure.core.credentials import AzureKeyCredential
container_sas_url = "..."
results_container_sas_url = "..."
document_intelligence_client = DocumentIntelligenceClient(
endpoint=os.environ["AZURE_DOCUMENT_INTELLIGENCE_ENDPOINT"],
credential=AzureKeyCredential(os.environ["AZURE_DOCUMENT_INTELLIGENCE_KEY"]),
)
# poller = await document_intelligence_client.begin_analyze_document(
# model_id="prebuilt-layout", body=open("data/[...].pdf", "rb")
# )
# print(await poller.result())
request = AnalyzeBatchDocumentsRequest(
result_container_url=results_container_sas_url,
azure_blob_source=AzureBlobContentSource(container_url=container_sas_url),
)
poller = document_intelligence_client.begin_analyze_batch_documents(model_id="prebuilt-layout", body=request)
continuation_token = poller.continuation_token()
poller2 = document_intelligence_client.get_analyze_batch_result(continuation_token=continuation_token)
if poller2.done():
final_result = poller2.result()
print(f"Succeeded count: {final_result.succeeded_count}")
print(f"Failed count: {final_result.failed_count}")
print(f"Skipped count: {final_result.skipped_count}")
else:
print("The batch analyze is still in process...")
```
**Expected behavior**
I was expecting a successful request, but got an error related to managed identities:
```
---------------------------------------------------------------------------
HttpResponseError Traceback (most recent call last)
Cell In[15], [line 30](vscode-notebook-cell:?execution_count=15&line=30)
20 # poller = await document_intelligence_client.begin_analyze_document(
21 # model_id="prebuilt-layout", body=open("data/RPCAR-68935-01.pdf", "rb")
22 # )
23 # print(await poller.result())
26 request = AnalyzeBatchDocumentsRequest(
27 result_container_url=results_container_sas_url,
28 azure_blob_source=AzureBlobContentSource(container_url=container_sas_url),
29 )
---> [30](vscode-notebook-cell:?execution_count=15&line=30) poller = document_intelligence_client.begin_analyze_batch_documents(model_id="prebuilt-layout", body=request)
32 continuation_token = poller.continuation_token()
34 poller2 = document_intelligence_client.get_analyze_batch_result(continuation_token=continuation_token)
File ~\AppData\Roaming\Python\Python313\site-packages\azure\core\tracing\decorator.py:119, in distributed_trace..decorator..wrapper_use_tracer(*args, **kwargs)
117 # If tracing is disabled globally and user didn't explicitly enable it, don't trace.
118 if user_enabled is False or (not tracing_enabled and user_enabled is None):
--> [119](https://file+.vscode-resource.vscode-cdn.net/.../~/AppData/Roaming/Python/Python313/site-packages/azure/core/tracing/decorator.py:119) return func(*args, **kwargs)
121 # Merge span is parameter is set, but only if no explicit parent are passed
122 if merge_span and not passed_in_parent:
File ~\AppData\Roaming\Python\Python313\site-packages\azure\ai\documentintelligence\_operations\_operations.py:1583, in DocumentIntelligenceClientOperationsMixin.begin_analyze_batch_documents(self, model_id, body, pages, locale, string_index_type, features, query_fields, output_content_format, output, **kwargs)
1581 cont_token: Optional[str] = kwargs.pop("continuation_token", None)
1582 if cont_token is None:
-> [1583](https://file+.vscode-resource.vscode-cdn.net/.../Batch%20API/~/AppData/Roaming/Python/Python313/site-packages/azure/ai/documentintelligence/_operations/_operations.py:1583) raw_result = self._analyze_batch_documents_initial(
1584 model_id=model_id,
1585 body=body,
1586 pages=pages,
1587 locale=locale,
1588 string_index_type=string_index_type,
1589 features=features,
1590 query_fields=query_fields,
1591 output_content_format=output_content_format,
1592 output=output,
1593 content_type=content_type,
1594 cls=lambda x, y, z: x,
1595 headers=_headers,
1596 params=_params,
1597 **kwargs,
1598 )
1599 raw_result.http_response.read() # type: ignore
1600 kwargs.pop("error_map", None)
File ~\AppData\Roaming\Python\Python313\site-packages\azure\ai\documentintelligence\_operations\_operations.py:1356, in DocumentIntelligenceClientOperationsMixin._analyze_batch_documents_initial(self, model_id, body, pages, locale, string_index_type, features, query_fields, output_content_format, output, **kwargs)
1354 map_error(status_code=response.status_code, response=response, error_map=error_map)
1355 error = _failsafe_deserialize(_models.DocumentIntelligenceErrorResponse, response.json())
-> [1356](https://file+.vscode-resource.vscode-cdn.net/.../Batch%20API/~/AppData/Roaming/Python/Python313/site-packages/azure/ai/documentintelligence/_operations/_operations.py:1356) raise HttpResponseError(response=response, model=error)
1358 response_headers = {}
1359 response_headers["Retry-After"] = self._deserialize("int", response.headers.get("Retry-After"))
HttpResponseError: (InvalidRequest) Invalid request.
Code: InvalidRequest
Message: Invalid request.
Inner error: {
"code": "InvalidManagedIdentity",
"message": "The managed identity configuration is invalid: Managed identity is not enabled for the current resource."
}
```
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Additional context**
From the [documentation](https://learn.microsoft.com/en-us/azure/ai-services/document-intelligence/prebuilt/batch-analysis?view=doc-intel-4.0.0), it seems that managed identities and sas urls are both options, but it isn't even clear how to use managed identities since the examples use sas urls.
```
POST {endpoint}/documentintelligence/documentModels/{modelId}:analyzeBatch?api-version=2024-11-30
{
"azureBlobSource": {
"containerUrl": "https://myStorageAccount.blob.core.windows.net/myContainer?mySasToken",
"prefix": "inputDocs/"
},
{
"resultContainerUrl": "https://myStorageAccount.blob.core.windows.net/myOutputContainer?mySasToken",
"resultPrefix": "batchResults/",
"overwriteExisting": true
}
```
Also, why is a resultContainerUrl needed; could I simply reuse the same URL?
Contributor guide
Assessment
This issue has not been assessed yet.