ERA-12650: Add full patrol CRUD to both sync and async clients#28
Open
JoshuaVulcan wants to merge 7 commits intomainfrom
Open
ERA-12650: Add full patrol CRUD to both sync and async clients#28JoshuaVulcan wants to merge 7 commits intomainfrom
JoshuaVulcan wants to merge 7 commits intomainfrom
Conversation
5 tasks
JoshuaVulcan
added a commit
that referenced
this pull request
Feb 11, 2026
…g to _call() - Async _delete() now delegates to _call(path=path, payload=None, method='DELETE', params=params) - Add 204 / empty-body handling in async _call() so DELETE responses don't trigger JSON parse - Aligns with PR review: use _call() delegation pattern like PRs #28, #29, #34; reduces merge conflict Co-authored-by: Cursor <cursoragent@cursor.com>
Adds comprehensive patrol endpoint coverage to ERClient and AsyncERClient: Sync client additions: - get_patrol(), patch_patrol() (single patrol detail/update) - Patrol types CRUD (get/post/patch/delete) - Patrol segments CRUD + get_patrol_segment_events() - Patrol notes CRUD - Patrol files (get/post/get single) - get_patrol_trackedby() schema endpoint Async client additions (all patrol methods, achieving full parity): - get_patrols() as async generator with pagination - get_patrol(), post_patrol(), patch_patrol(), delete_patrol() - All patrol types, segments, notes, files methods - add_events_to_patrol_segment() - _delete() helper method on AsyncERClient Includes 33 new tests (async + sync) covering success, pagination, error handling, and all CRUD operations. Co-authored-by: Cursor <cursoragent@cursor.com>
- Make async post_patrol_file(patrol_id, filepath, comment) take filepath and open file internally to match sync client and post_event_file() pattern - Update async test_post_patrol_file to use tmp_path filepath instead of BytesIO - Add get_patrol 403 (forbidden) tests for both sync and async - Add delete_patrol 404/403 tests for async; add full delete_patrol tests for sync (success, not_found, forbidden) Co-authored-by: Cursor <cursoragent@cursor.com>
- Add responses>=0.24 to test optional deps and dev dependency group - Replace patch.object/MagicMock with @responses.activate and responses.get/post/patch/delete to validate full URL construction - Add _url() helper to build API URLs like ERClient._er_url() - Assert request URLs where useful (get_patrol, delete_patrol, add_events) Co-authored-by: Cursor <cursoragent@cursor.com>
f1e01b6 to
e6bc343
Compare
# Conflicts: # tests/sync_client/conftest.py
…root Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds full patrol CRUD coverage across the sync (ERClient) and async (AsyncERClient) clients to achieve endpoint parity, along with new sync/async test suites and required test dependencies.
Changes:
- Added patrol endpoints for types/segments/notes/files/tracked-by to
ERClientandAsyncERClient, plus async pagination viaget_patrols(). - Added new patrol-focused test suites for both sync (
responses) and async (respx) clients. - Added
responsesas a dev/test dependency (pyproject + lockfile updates).
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
erclient/client.py |
Adds new sync + async patrol methods (CRUD + related endpoints). |
tests/sync_client/test_patrols.py |
New sync patrol test coverage using responses. |
tests/async_client/test_patrols.py |
New async patrol test coverage using respx, including pagination and error handling. |
pyproject.toml |
Adds responses to dev/test dependencies. |
uv.lock |
Locks responses dependency. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| import responses | ||
|
|
||
| from erclient import ERClientNotFound, ERClientPermissionDenied | ||
| from erclient.client import ERClient |
Comment on lines
+1
to
+3
| import pytest | ||
| import responses | ||
|
|
|
|
||
| def delete_patrol_type(self, patrol_type_id): | ||
| """Delete a patrol type.""" | ||
| return self._delete(f'activity/patrols/types/{patrol_type_id}') |
Comment on lines
+686
to
+694
| def post_patrol_file(self, patrol_id, filepath, comment=''): | ||
| """Upload a file to a patrol.""" | ||
| with open(filepath, 'rb') as f: | ||
| files = {'filecontent.file': f} | ||
| return self._post_form( | ||
| f'activity/patrols/{patrol_id}/files/', | ||
| body={'comment': comment}, | ||
| files=files, | ||
| ) |
Comment on lines
+1746
to
+1748
| async def delete_patrol(self, patrol_id): | ||
| """Delete a patrol.""" | ||
| return await self._delete(f'activity/patrols/{patrol_id}/') |
Comment on lines
+1828
to
+1836
| async def post_patrol_file(self, patrol_id, filepath, comment=''): | ||
| """Upload a file to a patrol.""" | ||
| with open(filepath, 'rb') as f: | ||
| files = {'filecontent.file': f} | ||
| return await self._post_form( | ||
| f'activity/patrols/{patrol_id}/files/', | ||
| body={'comment': comment}, | ||
| files=files, | ||
| ) |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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
ERClient(sync) andAsyncERClient, achieving full sync/async parity for patrol operations_delete()helper toAsyncERClientto enable DELETE operations (previously missing)respx+ sync viaunittest.mock) covering success paths, pagination, error handling, and all CRUD operationsNew Methods
Sync
ERClient(new):get_patrol(id),patch_patrol(id, data)get_patrol_types(),get_patrol_type(id),post_patrol_type(),patch_patrol_type(),delete_patrol_type()get_patrol_segments(),get_patrol_segment(id),post_patrol_segment(),patch_patrol_segment(),get_patrol_segment_events()get_patrol_notes(),post_patrol_note(),patch_patrol_note(),delete_patrol_note()get_patrol_files(),post_patrol_file(),get_patrol_file()get_patrol_trackedby()Async
AsyncERClient(new):get_patrols()(async generator with pagination),get_patrol(),post_patrol(),patch_patrol(),delete_patrol()add_events_to_patrol_segment()Test Plan
Jira
ERA-12650