Conversation
📝 WalkthroughWalkthroughThe pull request introduces a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
eb44376 to
24d6213
Compare
24d6213 to
0f44322
Compare
|
There was a problem hiding this comment.
🧹 Nitpick comments (3)
mpt_api_client/http/query_options.py (1)
4-8: Consider makingQueryOptionsimmutable to prevent accidental mutations.
QueryOptionsis shared across query state propagation and multiple mixins. While no direct mutations are currently present, freezing the dataclass prevents future accidental side effects in shared state scenarios.Proposed change
-@dataclass +@dataclass(frozen=True, slots=True) class QueryOptions: """Options for query state.""" render: bool = False🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@mpt_api_client/http/query_options.py` around lines 4 - 8, Change the QueryOptions dataclass to be immutable by declaring it as a frozen dataclass (e.g., `@dataclass`(frozen=True)) so instances cannot be mutated after creation; update any code that attempted to modify QueryOptions attributes to instead construct a new QueryOptions instance (refer to the QueryOptions class definition and any callers that propagate or modify its fields).tests/e2e/audit/records/test_sync_records.py (1)
81-89: Assertactorin the combined render+select test.
select=["object", "actor", "details"]is requested, butactoris not verified in this test. Adding that assertion would make the case fully aligned with its intent.Suggested patch
def test_get_record_with_render_and_select(mpt_vendor: MPTClient, audit_record_id) -> None: @@ result = service.get(audit_record_id, select=["object", "actor", "details"]) assert result.id == audit_record_id assert result.object is not None + assert result.actor is not None assert not any(char in result.details for char in template_chars)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/e2e/audit/records/test_sync_records.py` around lines 81 - 89, The test function test_get_record_with_render_and_select requests select=["object", "actor", "details"] but never asserts actor; update the test to verify the actor field is returned by adding an assertion (e.g., assert result.actor is not None or an appropriate value) after the existing asserts so that the selected "actor" field is validated when calling service.get(audit_record_id, select=[...]) with render enabled.tests/e2e/audit/records/test_async_records.py (1)
83-93: Assertactorin the combined render+select case.Line 89 requests
"actor"inselect, but the test does not verify it. Add an explicit assertion so this case validates all requested fields.Suggested patch
async def test_get_record_with_render_and_select( async_mpt_vendor: AsyncMPTClient, audit_record_id: str ) -> None: @@ result = await service.get(audit_record_id, select=["object", "actor", "details"]) assert result.id == audit_record_id assert result.object is not None + assert result.actor is not None assert not any(char in result.details for char in template_chars)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/e2e/audit/records/test_async_records.py` around lines 83 - 93, The test test_get_record_with_render_and_select requests "actor" in the select but never checks it; update the assertion block after calling service.get(audit_record_id, select=["object", "actor", "details"]) to explicitly assert the actor value (e.g., assert result.actor is not None or equals the expected actor) so the combined render+select case validates the requested field (referencing result.actor and the service created by async_mpt_vendor.audit.records.options(render=True)).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@mpt_api_client/http/query_options.py`:
- Around line 4-8: Change the QueryOptions dataclass to be immutable by
declaring it as a frozen dataclass (e.g., `@dataclass`(frozen=True)) so instances
cannot be mutated after creation; update any code that attempted to modify
QueryOptions attributes to instead construct a new QueryOptions instance (refer
to the QueryOptions class definition and any callers that propagate or modify
its fields).
In `@tests/e2e/audit/records/test_async_records.py`:
- Around line 83-93: The test test_get_record_with_render_and_select requests
"actor" in the select but never checks it; update the assertion block after
calling service.get(audit_record_id, select=["object", "actor", "details"]) to
explicitly assert the actor value (e.g., assert result.actor is not None or
equals the expected actor) so the combined render+select case validates the
requested field (referencing result.actor and the service created by
async_mpt_vendor.audit.records.options(render=True)).
In `@tests/e2e/audit/records/test_sync_records.py`:
- Around line 81-89: The test function test_get_record_with_render_and_select
requests select=["object", "actor", "details"] but never asserts actor; update
the test to verify the actor field is returned by adding an assertion (e.g.,
assert result.actor is not None or an appropriate value) after the existing
asserts so that the selected "actor" field is validated when calling
service.get(audit_record_id, select=[...]) with render enabled.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Pro
Run ID: 6b4da42e-3b3b-4fd1-b0fe-036fcbdbec3f
📒 Files selected for processing (18)
mpt_api_client/http/async_client.pympt_api_client/http/client.pympt_api_client/http/client_utils.pympt_api_client/http/mixins/get_mixin.pympt_api_client/http/mixins/queryable_mixin.pympt_api_client/http/query_options.pympt_api_client/http/query_state.pympt_api_client/http/resource_accessor.pytests/e2e/audit/records/test_async_records.pytests/e2e/audit/records/test_sync_records.pytests/unit/http/mixins/test_get_mixin.pytests/unit/http/mixins/test_queryable_mixin.pytests/unit/http/test_async_client.pytests/unit/http/test_client.pytests/unit/http/test_client_utils.pytests/unit/http/test_query_options.pytests/unit/http/test_query_state.pytests/unit/http/test_resource_accessor.py



This pull request introduces a new
QueryOptionsclass to centralize and extend query option handling (such as therender()parameter) across the HTTP client, resource accessor, and query mixin layers. The change replaces the previous use of a simplerenderboolean with a more extensible options object, allowing for cleaner and more maintainable code as more query options are added in the future. The codebase is refactored to passQueryOptionsthroughout the request lifecycle and to generate query strings accordingly.Key changes in this pull request:
Query Options Infrastructure
QueryOptionsclass (aNamedTuplewith arenderflag) inmpt_api_client/http/query_options.pyto encapsulate query-related options.QueryStateto accept and store aQueryOptionsobject instead of a rawrenderboolean, and refactored its usage and property accessors accordingly. [1] [2] [3] [4]Client and Resource Accessor Refactoring
client.py,async_client.py) and resource accessor methods to accept and propagate the newoptionsparameter of typeQueryOptions, ensuring options flow through all request layers. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16] [17]Query String Generation
get_query_paramsutility inclient_utils.pyto build query strings from both parameters andQueryOptions, including logic for appending therender()function when requested. [1] [2]Mixins and Queryable API
GetMixin,QueryableMixin) to use and propagateQueryOptionsinstead of the previousrenderflag, including in method signatures and calls to resource accessors. [1] [2] [3] [4] [5] [6] [7]Closes MPT-19073
Release Notes
QueryOptionsdataclass to encapsulate query rendering behavior with a configurablerenderboolean flagQueryStateto accept and storeQueryOptionsinstead of a barerenderboolean parameterHTTPClient.request()andAsyncHTTPClient.request()) to accept an optionaloptionsparameter and forward it through the request lifecycleget_query_params()utility function to build URL-encoded query strings from parameters andQueryOptions, conditionally appendingrender()when requestedResourceAccessor.get(),AsyncResourceAccessor.get(), and related internal methods) to accept and propagateQueryOptionsthrough the request chainGetMixin,QueryableMixin) to propagateQueryOptionsinstead of standalonerenderflagsQueryOptions,get_query_params(), and query rendering behavior in HTTP clients and resource accessorsrenderandselectquery options with audit records in both sync and async contexts