Skip to content

[ContentUnderstanding] Expose analyze result/status retrieval by operation_id for stateless (event-driven) consumers #47951

Description

@nischays

Library name

azure-ai-contentunderstanding (1.2.0b3)

Is your feature request related to a problem? Please describe.

In an event-driven / message-based architecture, the worker that starts an
analyze operation is often not the same process (or host) that later retrieves
the result. The submitting worker enqueues a message and moves on; a separate
consumer picks the work up later to fetch the outcome.

Today the SDK only supports awaiting the returned AnalyzeLROPoller
(poller.result()), which requires keeping the poller object alive in the
originating process. That does not fit a stateless consumer.

The documented cross-process alternative — poller.continuation_token() +
ContentUnderstandingClient(...).begin_analyze(... continuation_token=...) /
from_continuation_token(...) — is impractical here because the continuation
token is a multi-KB, base64-encoded JSON blob that embeds the entire initial
HTTP exchange (request line + headers, response status + headers, and the
base64-encoded response body). Persisting that per operation onto a queue or
into a database is heavy and opaque.

Meanwhile, the service already exposes a clean primitive:
GET /analyzerResults/{operationId} returns status + result + usage in a single
call, keyed only by the short operationId. The SDK even surfaces that id today
via AnalyzeLROPoller.operation_id. But the client method that calls this
endpoint (_get_result) is marked internal (@access(Access.internal)), so
there is no supported public way to go from an operation_id back to the result.

Describe the solution you'd like

A public, non-blocking method on both the sync and async clients that takes just
the operation_id:

status = client.get_analyze_result(operation_id)  # -> ContentAnalyzerAnalyzeOperationStatus

status.status   # NotStarted | Running | Succeeded | Failed | Canceled
status.result   # AnalysisResult (present once Succeeded)
status.usage    # UsageDetails
status.error    # ODataV4Format (present on Failed)

The return model ContentAnalyzerAnalyzeOperationStatus is already public in the
API surface. A consumer would then only need to persist the short operation_id
(already available from poller.operation_id), and any worker could poll status
or fetch the completed result statelessly.

Describe alternatives you've considered

  • Continuation token (poller.continuation_token()): works, but the token is
    a large opaque blob embedding the whole initial response — undesirable to
    persist and pass around per operation in a messaging system.
  • Calling the internal _get_result(operation_id) directly: unsupported,
    underscore-prefixed, and may change or break on TypeSpec regeneration.

Additional context

operation_id is the natural correlation key (a short GUID from the
Operation-Location header). Related precedent in this package for small
ergonomic patches to the CU Python client that were accepted: #45432 (polling
interval) and #46249 (usage property, shipped in #46278).

I'm willing to contribute this — a PR to follow.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ClientThis issue points to a problem in the data-plane of the library.Cognitive - Content UnderstandingService AttentionWorkflow: This issue is responsible by Azure service team.customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-team-attentionWorkflow: This issue needs attention from Azure service team or SDK teamquestionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions