Azure AI ML Code Review
Reviews uncommitted changes (staged and unstaged files) in the azure-ai-ml package, focusing on Azure SDK Python design guidelines, type safety, testing patterns, and API consistency.
Default Review Scope
Unless otherwise specified, review all uncommitted changes in the current branch (staged and unstaged files) within sdk/ml/azure-ai-ml/. This includes new files, modified files, and any pending changes that haven't been committed yet.
Review Focus Areas
1. Azure SDK Design Guidelines Compliance
- Check: Adherence to Azure SDK Python Design Guidelines
- Look for: Proper client naming, method patterns, parameter order
- Flag: Non-compliant naming (use
create_or_update not create_or_replace)
- Example Issue:
def get_job(name, subscription_id) should be def get_job(name, **kwargs)
Key Patterns:
- Client methods:
begin_* for LROs, list_* for paginators
- Naming: snake_case for methods, PascalCase for classes
- Parameters: Required positional, optional keyword-only
- Return types: Explicit type hints for all public APIs
2. Type Annotations & MyPy Compliance
- Check: Complete type annotations on all public APIs
- Look for: Proper use of
Optional, Union, TYPE_CHECKING
- Flag: Missing return types,
Any without justification, bare dict/list
- Example Issue:
def process_data(data) should be def process_data(data: Dict[str, Any]) -> ProcessedData
Common Fixes:
# Bad
def get_config(name):
return config
# Good
def get_config(name: str) -> Optional[Dict[str, Any]]:
return config
3. Pylint Compliance
- Check: Code passes pylint with azure-sdk-for-python rules
- Look for: Proper docstrings, no unused imports, correct argument names
- Flag: Violations of naming conventions, too many arguments (>5), long lines (>120)
- Reference: Azure Pylint Guidelines
Watch for:
client-method-should-not-use-static-method
missing-client-constructor-parameter-credential
client-method-has-more-than-5-positional-arguments
4. Async/Await Patterns
- Check: Proper async implementation in
_async modules
- Look for: Using
async with for clients, awaiting coroutines correctly
- Flag: Blocking calls in async code, missing
await, sync code in async modules
- Example Issue:
self._client.get() in async should be await self._client.get()
Pattern:
# In azure/ai/ml/aio/operations/
async def create_or_update(
self,
entity: Job,
**kwargs: Any
) -> Job:
async with self._lock:
result = await self._service_client.create_or_update(...)
return result
5. Error Handling & Validation
- Check: Proper exception handling with Azure SDK exceptions
- Look for: Use of
HttpResponseError, ResourceNotFoundError, proper validation
- Flag: Bare
except:, catching Exception without re-raising, missing validation
- Example Issue: Missing parameter validation before API calls
Pattern:
from azure.core.exceptions import ResourceNotFoundError, HttpResponseError
try:
result = self._operation.get(name)
except ResourceNotFoundError:
raise ResourceNotFoundError(f"Job '{name}' not found")
except HttpResponseError as e:
raise HttpResponseError(f"Failed to retrieve job: {e.message}")
6. API Design & Operations
- Check: Consistent CRUD patterns across operations classes
- Look for: Proper separation of sync/async, operations returning correct types
- Flag: Business logic in client, missing operations class, inconsistent method names
Structure:
azure/ai/ml/
├── operations/ # Sync operations
│ ├── job_operations.py
│ └── model_operations.py
└── aio/operations/ # Async operations (mirror structure)
├── job_operations.py
└── model_operations.py
7. Entity & Schema Patterns
- Check: Proper use of marshmallow schemas, correct entity inheritance
- Look for: Schema validation, proper serialization/deserialization
- Flag: Direct dict manipulation instead of entities, missing schema validation
Entity Pattern:
@dataclass
class Job(Resource):
"""Job entity."""
name: str
experiment_name: Optional[str] = None
def _to_rest_object(self) -> RestJob:
"""Convert to REST representation."""
...
@classmethod
def _from_rest_object(cls, obj: RestJob) -> "Job":
"""Create from REST representation."""
...
8. Testing Patterns
- Check: Proper unit tests, recorded tests for operations
- Look for: Use of
pytest, proper test isolation, fixture usage
- Flag: Missing tests for new features, tests with external dependencies, hardcoded values
Test Structure:
class TestJobOperations:
"""Test job operations."""
def test_create_job(self, client: MLClient, mock_workspace: Mock) -> None:
"""Test job creation."""
job = Job(name="test-job")
result = client.jobs.create_or_update(job)
assert result.name == "test-job"
@pytest.mark.recorded
def test_get_job_recorded(self, client: MLClient) -> None:
"""Test getting job with recording."""
...
9. Documentation & Docstrings
- Check: Complete docstrings following Google/NumPy style
- Look for: Parameter descriptions, return types, examples, raises
- Flag: Missing docstrings on public APIs, incomplete parameter docs
Docstring Pattern:
def create_or_update(
self,
job: Job,
**kwargs: Any
) -> Job:
"""Create or update a job.
:param job: The job entity to create or update.
:type job: ~azure.ai.ml.entities.Job
:keyword bool skip_validation: Skip validation of the job.
:return: The created or updated job.
:rtype: ~azure.ai.ml.entities.Job
:raises ~azure.core.exceptions.HttpResponseError: If the request fails.
.. admonition:: Example:
.. code-block:: python
from azure.ai.ml.entities import Job
job = Job(name="my-job")
result = ml_client.jobs.create_or_update(job)
"""
10. Backwards Compatibility
- Check: No breaking changes without major version bump
- Look for: Deprecated parameters, migration paths, version notes
- Flag: Removing public methods, changing signatures, removing parameters
Deprecation Pattern:
import warnings
def old_method(self, param: str) -> None:
"""Deprecated method.
.. deprecated:: 1.2.0
Use :meth:`new_method` instead.
"""
warnings.warn(
"old_method is deprecated, use new_method instead",
DeprecationWarning,
stacklevel=2
)
self.new_method(param)
11. Security & Credentials
- Check: Proper credential handling, no secrets in logs
- Look for: Use of
TokenCredential, proper token refresh, sanitized logging
- Flag: Credentials in error messages, API keys in code, secrets in tests
Pattern:
from azure.core.credentials import TokenCredential
class MLClient:
def __init__(
self,
credential: TokenCredential,
subscription_id: str,
**kwargs: Any
):
self._credential = credential # Store, don't log
# Never log credential or tokens
12. Performance & Efficiency
- Check: Efficient API calls, proper pagination, lazy loading
- Look for: Batching operations, caching where appropriate, avoiding N+1 queries
- Flag: Loading all items in memory, multiple API calls in loops, no pagination
Pagination Pattern:
def list(self, **kwargs: Any) -> Iterable[Job]:
"""List jobs with pagination.
:return: An iterable of jobs.
:rtype: ~azure.core.paging.ItemPaged[~azure.ai.ml.entities.Job]
"""
return self._operation.list(...) # Returns ItemPaged
Analysis Instructions
- Get uncommitted changes: Use git to identify modified files in
sdk/ml/azure-ai-ml/
- Read changed sections: Focus on modified lines and surrounding context
- Check each focus area: Go through all 12 areas systematically
- Priority levels: Critical (breaking/security) > High (bugs/types) > Medium (style/docs)
- Provide specific examples: Show actual code with file paths and line numbers
- Cross-reference: Check consistency across sync/async, operations/entities
Output Format
Organize findings by priority and category:
✅ Positive Observations
Good patterns worth highlighting
🔴 Critical Issues
- Breaking changes without migration path
- Missing credential validation
- Type safety violations causing runtime errors
- Security vulnerabilities
⚠️ High Priority Issues
- Missing type annotations on public APIs
- Pylint/MyPy errors
- Missing tests for new functionality
- Improper async patterns
📋 Medium Priority Issues
- Missing or incomplete docstrings
- Code style inconsistencies
- Performance optimizations
- Better error messages
💡 Suggestions
- Refactoring opportunities
- Additional test coverage
- Documentation improvements
For each issue:
- Location: File path and line numbers
- Current code: Show the problematic code
- Issue: Explain what's wrong and why
- Recommended fix: Show corrected code
- References: Link to relevant guidelines
Summary
- Total files changed: X
- Critical issues: X
- High priority: X
- Medium priority: X
- Overall assessment: Ready/Needs work/Blocked
Focus on issues that impact SDK quality, user experience, backwards compatibility, and Azure SDK guideline compliance.
1---2name: do-code-review3description: Reviews code changes in azure-ai-ml package for quality, Azure SDK compliance, and best practices. Use when reviewing code, checking pull requests, or when user asks to review changes or check code quality in azure-ai-ml.4---56# Azure AI ML Code Review78Reviews uncommitted changes (staged and unstaged files) in the azure-ai-ml package, focusing on Azure SDK Python design guidelines, type safety, testing patterns, and API consistency.910## Default Review Scope1112Unless otherwise specified, review all uncommitted changes in the current branch (staged and unstaged files) within `sdk/ml/azure-ai-ml/`. This includes new files, modified files, and any pending changes that haven't been committed yet.1314## Review Focus Areas1516### 1. Azure SDK Design Guidelines Compliance1718- **Check**: Adherence to [Azure SDK Python Design Guidelines](https://azure.github.io/azure-sdk/python_design.html)19- **Look for**: Proper client naming, method patterns, parameter order20- **Flag**: Non-compliant naming (use `create_or_update` not `create_or_replace`)21- **Example Issue**: `def get_job(name, subscription_id)` should be `def get_job(name, **kwargs)`2223**Key Patterns:**24- Client methods: `begin_*` for LROs, `list_*` for paginators25- Naming: snake_case for methods, PascalCase for classes26- Parameters: Required positional, optional keyword-only27- Return types: Explicit type hints for all public APIs2829### 2. Type Annotations & MyPy Compliance3031- **Check**: Complete type annotations on all public APIs32- **Look for**: Proper use of `Optional`, `Union`, `TYPE_CHECKING`33- **Flag**: Missing return types, `Any` without justification, bare `dict`/`list`34- **Example Issue**: `def process_data(data)` should be `def process_data(data: Dict[str, Any]) -> ProcessedData`3536**Common Fixes:**37```python38# Bad39def get_config(name):40 return config4142# Good43def get_config(name: str) -> Optional[Dict[str, Any]]:44 return config45```4647### 3. Pylint Compliance4849- **Check**: Code passes pylint with azure-sdk-for-python rules50- **Look for**: Proper docstrings, no unused imports, correct argument names51- **Flag**: Violations of naming conventions, too many arguments (>5), long lines (>120)52- **Reference**: [Azure Pylint Guidelines](https://github.com/Azure/azure-sdk-tools/blob/main/tools/pylint-extensions/azure-pylint-guidelines-checker/README.md)5354**Watch for:**55- `client-method-should-not-use-static-method`56- `missing-client-constructor-parameter-credential`57- `client-method-has-more-than-5-positional-arguments`5859### 4. Async/Await Patterns6061- **Check**: Proper async implementation in `_async` modules62- **Look for**: Using `async with` for clients, awaiting coroutines correctly63- **Flag**: Blocking calls in async code, missing `await`, sync code in async modules64- **Example Issue**: `self._client.get()` in async should be `await self._client.get()`6566**Pattern:**67```python68# In azure/ai/ml/aio/operations/69async def create_or_update(70 self,71 entity: Job,72 **kwargs: Any73) -> Job:74 async with self._lock:75 result = await self._service_client.create_or_update(...)76 return result77```7879### 5. Error Handling & Validation8081- **Check**: Proper exception handling with Azure SDK exceptions82- **Look for**: Use of `HttpResponseError`, `ResourceNotFoundError`, proper validation83- **Flag**: Bare `except:`, catching `Exception` without re-raising, missing validation84- **Example Issue**: Missing parameter validation before API calls8586**Pattern:**87```python88from azure.core.exceptions import ResourceNotFoundError, HttpResponseError8990try:91 result = self._operation.get(name)92except ResourceNotFoundError:93 raise ResourceNotFoundError(f"Job '{name}' not found")94except HttpResponseError as e:95 raise HttpResponseError(f"Failed to retrieve job: {e.message}")96```9798### 6. API Design & Operations99100- **Check**: Consistent CRUD patterns across operations classes101- **Look for**: Proper separation of sync/async, operations returning correct types102- **Flag**: Business logic in client, missing operations class, inconsistent method names103104**Structure:**105```106azure/ai/ml/107├── operations/ # Sync operations108│ ├── job_operations.py109│ └── model_operations.py110└── aio/operations/ # Async operations (mirror structure)111 ├── job_operations.py112 └── model_operations.py113```114115### 7. Entity & Schema Patterns116117- **Check**: Proper use of marshmallow schemas, correct entity inheritance118- **Look for**: Schema validation, proper serialization/deserialization119- **Flag**: Direct dict manipulation instead of entities, missing schema validation120121**Entity Pattern:**122```python123@dataclass124class Job(Resource):125 """Job entity."""126 127 name: str128 experiment_name: Optional[str] = None129 130 def _to_rest_object(self) -> RestJob:131 """Convert to REST representation."""132 ...133 134 @classmethod135 def _from_rest_object(cls, obj: RestJob) -> "Job":136 """Create from REST representation."""137 ...138```139140### 8. Testing Patterns141142- **Check**: Proper unit tests, recorded tests for operations143- **Look for**: Use of `pytest`, proper test isolation, fixture usage144- **Flag**: Missing tests for new features, tests with external dependencies, hardcoded values145146**Test Structure:**147```python148class TestJobOperations:149 """Test job operations."""150 151 def test_create_job(self, client: MLClient, mock_workspace: Mock) -> None:152 """Test job creation."""153 job = Job(name="test-job")154 result = client.jobs.create_or_update(job)155 assert result.name == "test-job"156 157 @pytest.mark.recorded158 def test_get_job_recorded(self, client: MLClient) -> None:159 """Test getting job with recording."""160 ...161```162163### 9. Documentation & Docstrings164165- **Check**: Complete docstrings following Google/NumPy style166- **Look for**: Parameter descriptions, return types, examples, raises167- **Flag**: Missing docstrings on public APIs, incomplete parameter docs168169**Docstring Pattern:**170```python171def create_or_update(172 self,173 job: Job,174 **kwargs: Any175) -> Job:176 """Create or update a job.177 178 :param job: The job entity to create or update.179 :type job: ~azure.ai.ml.entities.Job180 :keyword bool skip_validation: Skip validation of the job.181 :return: The created or updated job.182 :rtype: ~azure.ai.ml.entities.Job183 :raises ~azure.core.exceptions.HttpResponseError: If the request fails.184 185 .. admonition:: Example:186 187 .. code-block:: python188 189 from azure.ai.ml.entities import Job190 job = Job(name="my-job")191 result = ml_client.jobs.create_or_update(job)192 """193```194195### 10. Backwards Compatibility196197- **Check**: No breaking changes without major version bump198- **Look for**: Deprecated parameters, migration paths, version notes199- **Flag**: Removing public methods, changing signatures, removing parameters200201**Deprecation Pattern:**202```python203import warnings204205def old_method(self, param: str) -> None:206 """Deprecated method.207 208 .. deprecated:: 1.2.0209 Use :meth:`new_method` instead.210 """211 warnings.warn(212 "old_method is deprecated, use new_method instead",213 DeprecationWarning,214 stacklevel=2215 )216 self.new_method(param)217```218219### 11. Security & Credentials220221- **Check**: Proper credential handling, no secrets in logs222- **Look for**: Use of `TokenCredential`, proper token refresh, sanitized logging223- **Flag**: Credentials in error messages, API keys in code, secrets in tests224225**Pattern:**226```python227from azure.core.credentials import TokenCredential228229class MLClient:230 def __init__(231 self,232 credential: TokenCredential,233 subscription_id: str,234 **kwargs: Any235 ):236 self._credential = credential # Store, don't log237 # Never log credential or tokens238```239240### 12. Performance & Efficiency241242- **Check**: Efficient API calls, proper pagination, lazy loading243- **Look for**: Batching operations, caching where appropriate, avoiding N+1 queries244- **Flag**: Loading all items in memory, multiple API calls in loops, no pagination245246**Pagination Pattern:**247```python248def list(self, **kwargs: Any) -> Iterable[Job]:249 """List jobs with pagination.250 251 :return: An iterable of jobs.252 :rtype: ~azure.core.paging.ItemPaged[~azure.ai.ml.entities.Job]253 """254 return self._operation.list(...) # Returns ItemPaged255```256257## Analysis Instructions2582591. **Get uncommitted changes**: Use git to identify modified files in `sdk/ml/azure-ai-ml/`2602. **Read changed sections**: Focus on modified lines and surrounding context2613. **Check each focus area**: Go through all 12 areas systematically2624. **Priority levels**: Critical (breaking/security) > High (bugs/types) > Medium (style/docs)2635. **Provide specific examples**: Show actual code with file paths and line numbers2646. **Cross-reference**: Check consistency across sync/async, operations/entities265266## Output Format267268Organize findings by priority and category:269270### ✅ Positive Observations271Good patterns worth highlighting272273### 🔴 Critical Issues274- Breaking changes without migration path275- Missing credential validation276- Type safety violations causing runtime errors277- Security vulnerabilities278279### ⚠️ High Priority Issues280- Missing type annotations on public APIs281- Pylint/MyPy errors282- Missing tests for new functionality283- Improper async patterns284285### 📋 Medium Priority Issues286- Missing or incomplete docstrings287- Code style inconsistencies288- Performance optimizations289- Better error messages290291### 💡 Suggestions292- Refactoring opportunities293- Additional test coverage294- Documentation improvements295296For each issue:2971. **Location**: File path and line numbers2982. **Current code**: Show the problematic code2993. **Issue**: Explain what's wrong and why3004. **Recommended fix**: Show corrected code3015. **References**: Link to relevant guidelines302303### Summary304305- Total files changed: X306- Critical issues: X307- High priority: X 308- Medium priority: X309- Overall assessment: Ready/Needs work/Blocked310311Focus on issues that impact SDK quality, user experience, backwards compatibility, and Azure SDK guideline compliance.