[Translation] Update azure-ai-translation-document to 2026-03-01 API version#47837
[Translation] Update azure-ai-translation-document to 2026-03-01 API version#47837jrjrguo wants to merge 22 commits into
Conversation
Adds custom translation model deployment name support (deployment_name on TranslationTarget/begin_translation, DocumentStatus, and single-document translate) and image translation support (translate_text_within_image plus image-scan reporting fields). Introduces the BatchOptions model, sets the default service API version to 2026-03-01, adds samples and unit tests, and bumps the version to 1.2.0b1.
… test harness Adds deployment_name and image-translation live tests (sync + async) and the image test document. Refactors the test storage helpers to authenticate to Azure Storage with a token credential (DefaultAzureCredential) and pass plain container URLs to the Document Translation service (accessed via the Translator resource's managed identity), so tests run without account-key/shared-key access.
…key preparer var Lowers operation/document counts in the list_translations and list_document_statuses tests (no tests removed, assertions unchanged) to cut live re-recording time, and removes the now-unused DOCUMENT_TRANSLATION_STORAGE_KEY requirement from the preparer (storage now uses Entra ID auth).
…it tests Removes the overloaded-inputs, overloaded-single-input, and single-input-with-kwargs live tests (which validate SDK request dispatch/serialization, not service behavior) and re-adds them as fast unit tests over the shared get_translation_input builder. Mirrors the .NET suite (DocumentTranslationMockTests) and trims live re-recording time. No SDK coverage lost.
…s skip; drop obsolete unsupported-files test - Publish re-recorded live-test sessions (assets.json -> new tag) - Fix async test_list_document_statuses_mixed_filters (skip 3->1 for docs_count=5) - Remove test_use_supported_and_unsupported_files (sync+async): .jpg is now a supported image format and unsupported files are no longer silently dropped under api-version 2026-03-01, so the scenario is obsolete
There was a problem hiding this comment.
Pull request overview
This PR updates azure-ai-translation-document to the Document Translation 2026-03-01 service API version (now the default) and releases it as the 2.0.0 GA. It surfaces two new service capabilities — custom-model deployment name routing and image translation — across the sync/async clients, models, samples, tests, and docs. The change is applied as a targeted delta on top of the generated + _patch.py customization layer rather than a full re-emit.
Changes:
- Bumped default API version
2024-05-01→2026-03-01(breaking) and version to2.0.0; addeddeployment_name(onTranslationTarget,begin_translation,translate, andDocumentStatus) andtranslate_text_within_imagesupport plus the newBatchOptionsmodel and image-scan reporting fields. - Migrated storage-dependent tests from account-key SAS to Entra ID (
DefaultAzureCredential) plain container URLs, replaced live overload/serialization tests with offline dispatch/model tests, reduced list operation counts, and added image/deployment tests. - Added sync + async samples and README entries for the two new features.
Reviewed changes
Copilot reviewed 30 out of 31 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
.../document/_patch.py |
Adds deployment_name/translate_text_within_image to begin_translation + get_translation_input; new API-version enum value |
.../document/aio/_patch.py |
Async begin_translation keywords + api-version docstring |
.../document/_operations/_patch.py, aio/_operations/_patch.py |
translate single-doc keywords wired to request builder |
.../document/_operations/_operations.py |
Serializes new query params; default api-version bump |
.../document/models/_models.py, models/_patch.py, models/__init__.py |
BatchOptions, new DocumentStatus/TranslationTarget/TranslationStatusSummary fields + exports |
.../document/_configuration.py, aio/_configuration.py, _client.py, aio/_client.py |
Default api-version → 2026-03-01 |
.../document/_version.py, CHANGELOG.md, tsp-location.yaml, assets.json |
Version 2.0.0, changelog, spec pointer, recordings tag |
tests/testcase.py, preparer.py |
Entra-ID storage auth; drop storage-key/SAS helpers |
tests/test_translation*.py, test_model_updates.py, test_list_* |
New deployment/image tests, offline dispatch tests, reduced counts |
samples/**, samples/README.md |
New deployment + image translation samples (sync/async) |
…r batch list inputs; fix async list-skip test counter - get_translation_input: apply BatchOptions(translate_text_within_image=...) for the List[DocumentTranslationInput] batch form (was only read on the single-URL form and silently dropped otherwise) - Add offline regression test for the batch-form image-translation option - Fix accidental all_operations_count init (2 -> 0) in async test_list_translations_with_skip
…rtedFormats + glossary fix) - Update tsp-location commit to 9b0510f (2026-03-01 spec) - FileFormatType enum values corrected to PascalCase (Document/Glossary) - get_supported_formats 'type' query param now required - Adapt customizations to new emitter module layout (_utils package) - Update get_supported_glossary/document_formats to pass FileFormatType enum - Restore doc/*.rst include in MANIFEST.in
…0.63.2) The regenerated code uses the newer typespec-python emitter which renames the generated operations mixins (underscore prefix), relocates internal modules to _utils/, makes begin_translation/translate public, and drops the category-> category_id client name mapping. Adapt the hand-written customizations: - Re-wire the custom DocumentTranslationClientOperationsMixin (custom LRO poller) into both sync/async clients via inheritance; fix _begin_translation_initial call. - Update imports to _utils.model_base / _utils.utils; remove stale modules. - Add type: ignore[override]/[arg-type] and pylint arguments-renamed suppressions for the intentionally-divergent public begin_translation/translate signatures. - Restore public TranslationTarget.category_id as an alias of the generated 'category' field; fix positional __init__ for TranslationTarget/TranslationGlossary under the stricter new model base. Static checks pass (pylint 10.00, mypy, black, sphinx). Offline unit tests pass. Recorded tests require re-recording due to request-shape changes (Accept header, PascalCase FileFormatType) introduced by the new emitter/spec.
…tcher - Re-recorded test_supported_formats (sync+async) for the PascalCase FileFormatType query values (type=Document/Glossary); asset tag updated to _6c2363121f. - Exclude the 'Accept' header in the translation-flow test matcher so the existing recordings remain valid after the new emitter dropped 'Accept: application/json' on begin_translation. Full recorded suite passes (76 passed, 18 skipped).
…ler.id - Regenerate api.md/api.metadata.yml to match the new emitter surface (_Model, list[]). - Add package-level cspell.json allowing 'deser' (from generated _utils/model_base.py _xml_deser_* helpers) instead of editing the repo-wide .vscode/cspell.json. - Harden DocumentTranslationLROPoller.id (sync+async): fall back to the immutable initial-response Operation-Location header when the current polling body has no id, fixing a macos311 race where a background poll replaced the response with an id-less body.
The background LRO polling thread can observe a non-success response (e.g. a transient service error, or an unrecorded status GET during recorded 'wait=False' tests). Previously that error body was parsed as the current TranslationStatus, corrupting poller.status(), poller.done(), poller.id, and poller.details (leading to a macos311 flake where poller.details.documents_total_count raised TypeError on a None summary). _current_body now returns an empty TranslationStatus for any non-2xx response, so the poller falls back to the immutable initial response for id and keeps a correct not-done status until a successful poll arrives.
…te overloads The emitter migration left the public SingleDocumentTranslationClient bound to the generated operations mixin, whose two translate overloads both render as DocumentTranslateContent (a Model and a same-named TypedDict) in APIView, and left the patched multipart translate implementation as dead code. Re-wire the public sync and async SingleDocumentTranslationClient to the patched SingleDocumentTranslationClientOperationsMixin (matching how DocumentTranslationClient is handled) so the clean DocumentTranslateContent/JSON overloads and custom implementation are restored, and update api.md accordingly.
Models are now importable only from azure.ai.translation.document.models, matching the azure-ai-translation-text convention. Removed the 8 backward-compat re-exports (TranslationGlossary, TranslationTarget, DocumentTranslationInput, TranslationStatus, DocumentStatus, DocumentTranslationError, DocumentTranslationFileFormat, StorageInputType) from the top-level __all__; clients, DocumentTranslationApiVersion, and DocumentTranslationLROPoller remain top-level. Updated tests, samples, README snippets, and Sphinx docstring cross-references to the .models path, regenerated api.md/api.metadata.yml, and documented the breaking change in the CHANGELOG with a 2.0.0 (2026-08-01) release date. Playback tests: 76 passed, 18 skipped.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 62 out of 63 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (5)
sdk/translation/azure-ai-translation-document/azure/ai/translation/document/types.py:44
- This new module uses PEP 585 built-in generics (for example,
list[...]) at runtime, but the package still declares Python 3.8 support insetup.py:45,72. Python 3.8 cannot evaluate these annotations, so importing the package fails before any client can be used;_utils/serialization.pyalso introduces Python 3.9-only dict union operations. Either retain Python 3.8-compatible typing/operations throughout the regenerated files or consistently raise the package's minimum Python version and document that breaking requirement.
sdk/translation/azure-ai-translation-document/tests/test_list_translations.py:54 - This test now creates only two operations but still skips five and asserts that exactly five items disappeared. In an isolated test resource, both listings contain at most two created operations, so the assertion fails (or passes only because unrelated historical operations exist). Keep
skipbelow the number created.
sdk/translation/azure-ai-translation-document/tests/test_list_translations_async.py:56 - The async skip test also creates two operations while requesting
skip=5, so its count-difference assertion fails on a clean test resource and depends on unrelated service history. Keepskipbelow the number created.
sdk/translation/azure-ai-translation-document/azure/ai/translation/document/_operations/_patch.py:553 prepare_multipart_form_datanow returns a single list, but this override still unpacks it as the old(files, data)tuple and forwards the obsoletedatavalue. A normal document-only request produces a one-element list and raisesValueErrorbefore sending; other part counts are also misinterpreted. Match the regenerated operation's new call shape.
files=_files,
data=_data,
sdk/translation/azure-ai-translation-document/azure/ai/translation/document/aio/_operations/_patch.py:464
- The async override has the same stale tuple unpacking and obsolete
dataforwarding even thoughprepare_multipart_form_datanow returns only the files list. Document-only calls therefore raiseValueErrorbefore reaching the service, and requests with glossaries are assembled incorrectly. Match the regenerated async operation's new call shape.
files=_files,
data=_data,
prepare_multipart_form_data now returns a single files list, but the custom sync and async translate mixins still unpacked it as (_files, _data) and passed data=_data, raising ValueError before any request was sent. Since SingleDocumentTranslationClient is now wired to the custom mixin, this broke all single-document translations. Assign only _files and drop the removed data argument, matching the regenerated operation. Verified both sync and async translate build requests correctly for document-only and glossary (multi-file) bodies. Playback: 76 passed, 18 skipped.
[Pilot] PR Pipeline Failure AnalysisA CI pipeline failed on this pull request. Here is an automated analysis of what went wrong and how to get the build green. What failedThe changelog verification step failed for Build: https://dev.azure.com/azure-sdk/public/_build/results?buildId=6604241 Recommended next steps
Raw pipeline analysis (azsdk ci analyze)
|
The generated types module uses builtin generics (list[...]) evaluated at import time, which are unavailable on Python 3.8, so importing the package failed on 3.8. Bump python_requires to >=3.9, drop the 3.8 classifier, and note the dropped 3.8 support in the CHANGELOG.
No user-facing bug fixes relative to 1.1.0 — the multipart/overload regressions were introduced and fixed within the unreleased 2.0.0 cycle and no public type changed, so there is nothing to document. Drop the empty section to match the convention of keeping only non-empty sections.
The custom sync/async translate implementations win MRO dispatch over the generated operations but lacked the generated @api_version_validation decorator, so deployment_name and translate_text_within_image were sent even on API versions that predate them (e.g. the documented 2024-05-01 fallback) instead of raising the intended version-specific error. Add the same validation metadata to both overrides. Verified: 2024-05-01 + deployment_name/translate_text_within_image now raises ValueError; default version still succeeds. Playback: 76 passed, 18 skipped.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 63 out of 64 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
sdk/translation/azure-ai-translation-document/azure/ai/translation/document/_operations/_patch.py:476
- This customized
translateoverrides the generated method, so the generated@api_version_validationat_operations/_operations.py:1284never runs. A client configured withapi_version="2024-05-01"will therefore senddeploymentNameortranslateTextWithinImageeven though those parameters are unavailable in that version, instead of raising the intended version error. Apply the same API-version validator to this override.
deployment_name: Optional[str] = None,
allow_fallback: Optional[bool] = None,
translate_text_within_image: Optional[bool] = None,
sdk/translation/azure-ai-translation-document/azure/ai/translation/document/aio/_operations/_patch.py:387
- The async customized
translatealso bypasses the generated method's@api_version_validation(aio/_operations/_operations.py:1031). Consequently, the new query options are sent withapi_version="2024-05-01"rather than being rejected as unavailable. Add the same version validator to this override.
deployment_name: Optional[str] = None,
allow_fallback: Optional[bool] = None,
translate_text_within_image: Optional[bool] = None,
New-field deserialization coverage stopped at DocumentStatus; there was no test asserting the three new TranslationStatusSummary image totals. Add an offline payload test covering the wire-name mappings totalImageScansSucceeded, totalImageScansFailed, and totalImageCharged -> total_image_scans_succeeded, total_image_scans_failed, total_images_charged.
Summary
Updates
azure-ai-translation-documentto the Document Translation2026-03-01service API version, mirroring the .NET regeneration in Azure/azure-sdk-for-net#60219. Released as the 2.0.0 GA for Python.Features Added
deployment_nameonTranslationTargetand as a keyword onbegin_translation(batch).deployment_namekeyword onSingleDocumentTranslationClient.translate(single document).deployment_nameonDocumentStatus(the deployment used).translate_text_within_imagekeyword onbegin_translationandtranslate.BatchOptionsmodel (carriestranslate_text_within_image) onStartTranslationDetails.options.DocumentStatus(image_characters_detected,images_charged,total_image_scans_succeeded,total_image_scans_failed) andTranslationStatusSummary(total_image_scans_succeeded,total_image_scans_failed,total_images_charged).Breaking Changes
2024-05-01to2026-03-01. Passapi_version="2024-05-01"to retain the previous behavior.azure.ai.translation.documentnamespace and must be imported fromazure.ai.translation.document.models. This affectsTranslationGlossary,TranslationTarget,DocumentTranslationInput,TranslationStatus,DocumentStatus,DocumentTranslationError,DocumentTranslationFileFormat, andStorageInputType(e.g.from azure.ai.translation.document.models import TranslationStatus). The clients (DocumentTranslationClient,SingleDocumentTranslationClient),DocumentTranslationApiVersion, andDocumentTranslationLROPollerremain at the top level. This aligns the package with theazure-ai-translation-textconvention (models only under.models).typesmodule uses builtin generics that require 3.9+.Other
2.0.0(GA);tsp-location.yamlupdated to the 2026-03-01 spec. Note: Python follows its own version line (previous GA was 1.1.0), so this is 2.0.0 rather than matching .NET's 3.0.0.Notes for reviewers
typespec-pythonemitter restructures the client and would break this package's customizations. A follow-up full regeneration will require aligning the emitter with the customization layer.