Skip to content

[cognitiveservices] Unblock managed compute creation — fix misleading 202 / AuthorizationFailed errors (Task 5441745)#48096

Draft
swarupecenits wants to merge 1 commit into
Azure:mainfrom
swarupecenits:fix/cognitiveservices-compute-create-no-poll
Draft

[cognitiveservices] Unblock managed compute creation — fix misleading 202 / AuthorizationFailed errors (Task 5441745)#48096
swarupecenits wants to merge 1 commit into
Azure:mainfrom
swarupecenits:fix/cognitiveservices-compute-create-no-poll

Conversation

@swarupecenits

Copy link
Copy Markdown
Member

Description

Work item: Task 5441745

Fixes the misleading errors users hit when creating a Cognitive Services managed compute via
ComputesOperations.begin_create_or_update (surfaced through az cognitiveservices account compute create).

The generated SDK failed asynchronous compute creation in two ways:

  1. Rejected the async 202 Accepted. The service returns HTTP 202 for the async create, but the
    generated _create_or_update_initial only accepts 200/201, so it raised
    Operation returned an invalid status 'Accepted'.
  2. Polled a permission-gated endpoint. The default poller followed the Azure-AsyncOperation header
    to .../locations/{location}/computeOperations/{operationId}, which requires
    Microsoft.CognitiveServices/locations/computeOperations/read. Callers allowed to create a compute
    but not granted that read permission saw a misleading AuthorizationFailed even though the create
    succeeded.

What this change does

Overrides ComputesOperations.begin_create_or_update (sync + async, in _patch.py) to:

  • Accept 202 in addition to 200/201.
  • Track the long-running operation by polling the compute resource itself (a GET on the resource
    URL, watching provisioningState) via BodyContentPolling, deliberately excluding the algorithms
    that follow the Azure-AsyncOperation/Location headers. This needs only computes/read (which
    callers already have) and never touches computeOperations.
  • Tolerate the read-after-write window (~15–20s) right after the create where the resource GET
    returns 404 "Cluster not found", so a successful create is not wrongly reported as failed (bounded
    grace so a genuinely missing resource still surfaces).
  • Block until terminal and, on failure, surface the compute's own properties.errors (e.g. the
    quota message) instead of a generic Operation returned an invalid status 'OK'.
  • Preserve the polling=False escape hatch and propagate genuine non-2xx create failures.

Only private helpers were added (_ComputeResourcePolling, _compute_provisioning_error,
_TERMINAL_FAILED_STATES); the public API surface is unchanged.

Notes

  • This is a client-side workaround while the service-side behavior (202 + computeOperations/read
    requirement + resource read-after-write lag) is addressed.
  • _patch.py re-implements the initial request send because the generated _create_or_update_initial
    rejects the 202; kept intentionally close to the generated code.
  • Version bumped 15.0.0b315.0.0b4; CHANGELOG updated.

Testing

  • 14 unit tests added (tests/test_computes_operations_patch.py + ..._async.py), driving the real
    azure-core poll loop: accept 202 · polls the resource, never computeOperations · blocks until
    terminal · tolerates the read-after-write 404 · gives up on a persistent 404 · surfaces the real
    failure reason · propagates non-2xx · polling=False. All pass; black + pyflakes clean.
  • Live-verified against a real account: 202 accepted, .result() blocks (~31s), survives the 404
    window, and raises the real quota error on a failed provision; invalid SKUs rejected correctly.

All SDK Contribution checklist:

  • The pull request does not introduce [breaking changes]
  • CHANGELOG is updated for new features, bug fixes or other significant changes.
  • I have read the contribution guidelines.

General Guidelines and Best Practices

  • Title of the pull request is clear and informative.
  • There are a small number of commits, each of which have an informative message.

Testing Guidelines

  • Pull request includes test coverage for the included changes.

Verification :
Screenshot 2026-07-16 232607

Screenshot 2026-07-16 201837

…lerate read-after-write 404

Override begin_create_or_update (sync + async) to accept the service's HTTP 202 and track the LRO by polling the compute resource (BodyContentPolling) instead of the computeOperations status endpoint that needs computeOperations/read many callers lack. Tolerates the ~15-20s read-after-write 404 window, blocks until terminal, and surfaces the compute's own provisioning error. Adds 14 unit tests; bumps to 15.0.0b4.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
9 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes managed compute creation by accepting HTTP 202 and polling the compute resource directly.

Changes:

  • Adds customized synchronous and asynchronous resource polling.
  • Handles transient 404s and provisioning errors.
  • Adds tests, changelog entry, and version bump.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
operations/_patch.py Implements synchronous polling workaround.
aio/operations/_patch.py Implements asynchronous polling workaround.
tests/test_computes_operations_patch.py Tests synchronous behavior.
tests/test_computes_operations_patch_async.py Tests asynchronous behavior.
CHANGELOG.md Documents the fix.
_version.py Bumps version to 15.0.0b4.

reaches a terminal state, and surfaces a genuine provisioning failure instead of masking it.
"""

@distributed_trace
"""

@distributed_trace
def begin_create_or_update(
cls = kwargs.pop("cls", None)
polling: Union[bool, PollingMethod] = kwargs.pop("polling", True)
lro_delay = kwargs.pop("polling_interval", self._config.polling_interval)
kwargs.pop("continuation_token", None)
reaches a terminal state, and surfaces a genuine provisioning failure instead of masking it.
"""

@distributed_trace_async
"""

@distributed_trace_async
async def begin_create_or_update(
cls = kwargs.pop("cls", None)
polling: Union[bool, AsyncPollingMethod] = kwargs.pop("polling", True)
lro_delay = kwargs.pop("polling_interval", self._config.polling_interval)
kwargs.pop("continuation_token", None)
Comment on lines +98 to +99
if str(self._status).lower() in _TERMINAL_FAILED_STATES:
raise _compute_provisioning_error(response)
Comment on lines +70 to +71
if str(self._status).lower() in _TERMINAL_FAILED_STATES:
raise _compute_provisioning_error(response)
@swarupecenits swarupecenits changed the title  [cognitiveservices] Unblock managed compute creation — fix misleading 202 / AuthorizationFailed errors (Task 5441745) [cognitiveservices] Unblock managed compute creation — fix misleading 202 / AuthorizationFailed errors (Task 5441745) Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants