You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[ML] Add experimental data storage path resolution - #49801
Adds experimental MLClient.data.resolve_path(path, *, follow_mltable=True) and public ResolvedDataPath to resolve short or fully qualified AML datastore URIs without notebook globals or service-to-service credentials.
Blob-backed MLTable definitions are followed recursively. result.uri remains the definition location; actual data locations are in result.sources. Each node retains its own transformations, including Delta version_as_of snapshots.
Uses the MLClient credential or existing datastore-secret APIs for authenticated definition reads, without closing caller credentials or generating SAS URLs.
follow_mltable=False performs metadata-only resolution, without storage access or datastore-secret retrieval.
Includes API documentation, a sample, changelog, and focused regression tests. No new runtime dependencies or server-side API changes.
MLTable definition discovery currently supports Blob-backed definitions only. External physical sources and patterns are preserved, not expanded.
Definition reads are bounded to 1 MiB, nesting to eight levels, and cycles are rejected. Only optional BlobNotFound discovery misses are treated as absent definitions; authorization and container failures propagate.
Resolves locations and preserves MLTable metadata; does not execute transformations or grant storage access.
Validation
97 passing tests, including 52 resolver cases plus existing data operations, data utilities, and datastore operations regression suites.
95% coverage across the new resolver and result class (resolver 95%; result class 100%). An initial coverage invocation encountered a local native-module import conflict; rerunning with filesystem-based source scopes succeeded.
MyPy passes for five changed SDK/sample files; Black checks pass for all six changed Python files.
SDK pylint with repository-pinned guidelines checker 0.5.7 passes, scoring 10.00/10.
Read-only live smoke checks resolved an existing Blob CSV and a Blob-backed MLTable pointing to Fabric OneLake; retained Delta version_as_of: 0 and verified caller credentials remained usable.
Staged whitespace validation passed.
Local validation used Python 3.9.5 and compatible pylint 3.3.9, rather than CI's pylint 4.0.4. Full package CI, additional supported Python versions, Sphinx build, and experimental public API approval remain for review/CI. This draft is not intended for automatic merge.
Authored-by: GitHub Copilot CLI 1.0.105
Model: GPT-6.1 Sol (gpt-6.1-sol)
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.
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Unvalidated datastore endpoints can expose storage credentials to attacker-controlled hosts, while repeated MLTable references allow unbounded downloads and source-tree expansion.
A definition at data//definition/MLTable containing file: ./a.csv resolves to data/definition/a.csv, not data//definition/a.csv. Normalizing the joined path collapses the Blob parent's internal separators, so discovery reads the correct definition but returns a different data location. Preserve those separators while resolving relative dot segments, and extend the duplicate-separator regression to cover a relative source.
Honor folder flag when resolving explicit MLTable definitions
A folder URI ending in MLTable/, or an MLTable folder reference named MLTable, is treated as an explicit definition even when folder=True. For example, root/MLTable/ downloads root/MLTable instead of root/MLTable/MLTable, raising BlobNotFound when the nested definition exists. Honor the folder flag when identifying explicit definitions and when selecting the relative-source parent at line 159; add regressions for both folder forms.
Pipeline "python - pullrequest" (job: Build Analyze) failed — build 7028936. The CSpell (spell-check) validation step reported 6 unknown-word errors across 3 files introduced by this PR. No test failures were reported for this run.
Relevant pipeline output
##[error]sdk/ml/azure-ai-ml/CHANGELOG.md:6:119 - Unknown word (ABFSS)
##[error]sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_data_path_resolver.py:84:17 - Unknown word (abfss)
##[error]sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_data_path_resolver.py:92:21 - Unknown word (abfss)
##[error]sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_data_path_resolver.py:173:52 - Unknown word (abfss)
##[error]sdk/ml/azure-ai-ml/azure/ai/ml/_utils/_data_path_resolver.py:173:61 - Unknown word (wasbs)
##[error]sdk/ml/azure-ai-ml/azure/ai/ml/operations/_data_operations.py:141:64 - Unknown word (ABFSS)
##[error]PowerShell exited with code '1'.
Root cause
ABFSS, abfss, and wasbs are valid Azure storage URI scheme identifiers ((redacted) for ADLS Gen2/Fabric OneLake, (redacted) for legacy Azure Blob) used by the new data-path-resolution feature, but they aren't present in the repository's cspell dictionary allowlist.
Recommended next steps
Add ABFSS, abfss, and wasbs to the repository's cspell word allowlist (the words array in the repo's cspell configuration, typically .vscode/cspell.json), alongside existing entries for similar scheme terms (e.g. abfs, wasb).
Re-run npx cspell lint --config ./.vscode/cspell.json --no-must-find-files --root . <changed-files> locally to confirm the fix.
Use the owning MLClient cloud for endpoint fallback and trust checks.
Cover mixed sovereign/public clients and nested datastore resolution.
Register storage URI schemes in the ML spelling dictionary for CI.
Authored-by: GitHub Copilot CLI 1.0.105
Model: GPT-6.1 Sol (gpt-6.1-sol)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5ff91386-9727-4ae0-914b-39e54a9549d5
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The resolver still shares mutable transformation metadata across repeated references, misclassifies folders named MLTable, and collapses significant empty Blob path segments, causing incorrect read semantics or path-resolution failures.
No open issues 🎉
3 previously missed issues
In code that hasn't changed since last review
Deep-copy cached transformations for repeated MLTable references
Repeated references to the same MLTable create distinct source nodes but assign them the same cached transformation list. Changing one node's nested version_as_of therefore also changes its sibling's read semantics. Deep-copy the transformation metadata for each result node, and extend the repeated-reference regression to verify that nested transformation dictionaries are independent.
Preserve empty Blob path segments in relative sources
Relative sources still lose significant empty Blob path segments. If data//definition/MLTable contains file: ./a.csv, this call returns .../data/definition/a.csv instead of .../data//definition/a.csv, potentially pointing to a different blob. Resolve relative dot segments without collapsing empty segments in the definition's Blob prefix, and add a regression with a relative source under that prefix.
Respect folder flags when resolving MLTable definitions
A folder named MLTable is treated as an explicit definition even when folder=True, whether indicated by a trailing slash or a nested folder entry. Resolving .../paths/root/MLTable/ downloads root/MLTable instead of root/MLTable/MLTable and raises BlobNotFound even when the definition exists. Respect the folder flag when detecting explicit definitions, and apply the same distinction to the relative-source parent calculation at line 162.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds experimental
MLClient.data.resolve_path(path, *, follow_mltable=True)and publicResolvedDataPathto resolve short or fully qualified AML datastore URIs without notebook globals or service-to-service credentials.result.uriremains the definition location; actual data locations are inresult.sources. Each node retains its own transformations, including Deltaversion_as_ofsnapshots.follow_mltable=Falseperforms metadata-only resolution, without storage access or datastore-secret retrieval.Scope and limits
BlobNotFounddiscovery misses are treated as absent definitions; authorization and container failures propagate.Validation
version_as_of: 0and verified caller credentials remained usable.Local validation used Python 3.9.5 and compatible pylint 3.3.9, rather than CI's pylint 4.0.4. Full package CI, additional supported Python versions, Sphinx build, and experimental public API approval remain for review/CI. This draft is not intended for automatic merge.
Authored-by: GitHub Copilot CLI 1.0.105
Model: GPT-6.1 Sol (gpt-6.1-sol)