-
Notifications
You must be signed in to change notification settings - Fork 28
feat(entities): support havingFilter post-aggregation filter [DS-9078] #1863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
978051a
0406ac3
00313b6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1475,6 +1475,91 @@ def test_query_v2_when_binnings_provided( | |
| assert sent is not None | ||
| assert "/v2/EntityService/" in str(sent.url) | ||
|
|
||
| def test_query_having_filter_sent_in_body( | ||
| self, | ||
| httpx_mock: HTTPXMock, | ||
| service: EntitiesService, | ||
| base_url: str, | ||
| org: str, | ||
| tenant: str, | ||
| version: str, | ||
| ) -> None: | ||
| """``having_filter`` is serialized with camelCase wire keys.""" | ||
| from uipath.platform.entities import ( | ||
| EntityAggregate, | ||
| EntityAggregateFunction, | ||
| EntityHavingCondition, | ||
| EntityHavingFilter, | ||
| EntityHavingOperator, | ||
| LogicalOperator, | ||
| ) | ||
|
|
||
| entity_key = uuid.uuid4() | ||
| httpx_mock.add_response( | ||
| url=re.compile( | ||
| rf"{base_url}{org}{tenant}/datafabric_/api/EntityService/entity/{entity_key}/query.*" | ||
| ), | ||
| status_code=200, | ||
| json={"value": [{"status": "active", "total": 12}], "totalRecordCount": 1}, | ||
| ) | ||
|
|
||
| service.retrieve_records( | ||
| entity_key=str(entity_key), | ||
| selected_fields=["status"], | ||
| group_by=["status"], | ||
| aggregates=[ | ||
| EntityAggregate( | ||
| function=EntityAggregateFunction.Count, | ||
| field="Id", | ||
| alias="total", | ||
| ) | ||
| ], | ||
| having_filter=EntityHavingFilter( | ||
| logical_operator=LogicalOperator.And, | ||
| aggregate_filters=[ | ||
| EntityHavingCondition( | ||
| aggregate_alias="total", | ||
| operator=EntityHavingOperator.GreaterThan, | ||
| value="5", | ||
| ) | ||
| ], | ||
| ), | ||
| ) | ||
|
|
||
| sent = httpx_mock.get_request() | ||
| assert sent is not None | ||
| body = json.loads(sent.content) | ||
| assert body["havingFilter"] == { | ||
| "logicalOperator": 0, | ||
| "aggregateFilters": [ | ||
| {"aggregateAlias": "total", "operator": ">", "value": "5"} | ||
| ], | ||
| } | ||
|
Comment on lines
+1531
to
+1537
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The hard-coded 0 is deliberate here: this test pins the exact wire contract the server sees. If it asserted LogicalOperator.And.value, the test would keep passing even if the enum's value were accidentally changed, which is precisely the regression it should catch. |
||
|
|
||
| def test_query_having_filter_requires_aggregates_and_group_by( | ||
| self, | ||
| service: EntitiesService, | ||
| ) -> None: | ||
| """``having_filter`` without aggregates + group_by fails locally, no HTTP.""" | ||
| from uipath.platform.entities import ( | ||
| EntityHavingCondition, | ||
| EntityHavingFilter, | ||
| EntityHavingOperator, | ||
| ) | ||
|
|
||
| having = EntityHavingFilter( | ||
| aggregate_filters=[ | ||
| EntityHavingCondition( | ||
| aggregate_alias="total", | ||
| operator=EntityHavingOperator.GreaterThan, | ||
| value="5", | ||
| ) | ||
| ], | ||
| ) | ||
|
|
||
| with pytest.raises(ValueError, match="aggregates and group_by"): | ||
| service.retrieve_records(entity_key="ent-1", having_filter=having) | ||
|
|
||
| def test_upload_attachment_sends_multipart( | ||
| self, | ||
| httpx_mock: HTTPXMock, | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call. Dropped the version bump (and lockfile updates) from this PR, so merging no longer publishes anything; the 0.2.19 bump will go in a small follow-up PR once the backend rollout completes. Updated the PR description to match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: the split does not work in this repo. The check-version-availability gate fails any PR whose package files change without an unpublished version in pyproject.toml, so the bump has to ride along. Restored it and kept the do-not-merge hold in the description instead.