feat: add GeoJSON, KML, and vector tile endpoints (ERA-12686)#42
Open
JoshuaVulcan wants to merge 5 commits intomainfrom
Open
feat: add GeoJSON, KML, and vector tile endpoints (ERA-12686)#42JoshuaVulcan wants to merge 5 commits intomainfrom
JoshuaVulcan wants to merge 5 commits intomainfrom
Conversation
Add get_events_export(filter=None) to AsyncERClient for parity with the existing sync method. Because the endpoint returns a CSV file rather than JSON, a new _get_raw() helper is introduced that returns the raw httpx.Response without attempting JSON parsing while preserving the standard error-handling pipeline. Also adds comprehensive tests for both the sync and async get_events_export() methods covering success, filter forwarding, URL construction, and error cases (401, 403, 404, 500). Co-authored-by: Cursor <cursoragent@cursor.com>
JoshuaVulcan
added a commit
that referenced
this pull request
Feb 11, 2026
- Add AsyncERClient._get_raw() to return raw httpx.Response for binary endpoints - Use _get_raw in async download_choice_icons() and get_sitrep() so callers get response.content / stream instead of broken JSON parse - Update async tests to mock binary content and assert on response.content Addresses ER_CLIENT_PR_REVIEWS.md: PR #41 dependency check and get_sitrep binary response. Self-contained (no dependency on PR #42 _get_response). Co-authored-by: Cursor <cursoragent@cursor.com>
Use _get_raw (from PR #33) for raw GET responses instead of adding _get_response; rebased onto ERA-12670/async-events-export. Co-authored-by: Cursor <cursoragent@cursor.com>
afb80b3 to
4d0f937
Compare
JoshuaVulcan
added a commit
that referenced
this pull request
Feb 11, 2026
- Add AsyncERClient._get_raw() to return raw httpx.Response for binary endpoints - Use _get_raw in async download_choice_icons() and get_sitrep() so callers get response.content / stream instead of broken JSON parse - Update async tests to mock binary content and assert on response.content Addresses ER_CLIENT_PR_REVIEWS.md: PR #41 dependency check and get_sitrep binary response. Self-contained (no dependency on PR #42 _get_response). Co-authored-by: Cursor <cursoragent@cursor.com>
# Conflicts: # tests/sync_client/conftest.py
Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds new export/retrieval endpoints to the sync ERClient and async AsyncERClient for geospatial formats (GeoJSON FeatureCollections, KML/KMZ downloads, and MVT/PBF vector tiles), plus test coverage for these additions.
Changes:
- Add sync + async client methods for GeoJSON, KML/KMZ, and vector tile (PBF) endpoints.
- Add async helper
_get_raw()to returnhttpx.Responsefor non-JSON/binary endpoints (and use it for CSV/KML/PBF calls). - Add new sync + async tests validating URL construction, parameter forwarding, response types, and async error handling.
Reviewed changes
Copilot reviewed 5 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 GeoJSON/KML/tiles methods to both clients, plus async raw-response GET helper and async CSV export method. |
tests/sync_client/test_get_events_export.py |
New sync tests verifying CSV export returns raw response and raises appropriate sync exceptions. |
tests/sync_client/test_geojson_kml_tiles.py |
New sync tests for GeoJSON, KML/KMZ, and vector tile endpoints (URL/params/response type). |
tests/async_client/test_get_events_export.py |
New async tests verifying CSV export returns raw httpx.Response and error mapping via _get_raw(). |
tests/async_client/test_geojson_kml_tiles.py |
New async tests for GeoJSON/KML/tiles endpoints, including 404 error handling. |
💡 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.
Comment on lines
+1
to
+12
| import json | ||
| from unittest.mock import MagicMock, patch | ||
|
|
||
| import pytest | ||
|
|
||
| from erclient.er_errors import ( | ||
| ERClientBadCredentials, | ||
| ERClientException, | ||
| ERClientNotFound, | ||
| ERClientPermissionDenied, | ||
| ) | ||
|
|
| @@ -0,0 +1,239 @@ | |||
| """Tests for GeoJSON, KML, and vector tile endpoints in the sync ERClient.""" | |||
| import json | |||
| from unittest.mock import patch, MagicMock | |||
Comment on lines
+1060
to
+1071
| """ | ||
| Get events as a GeoJSON FeatureCollection. | ||
|
|
||
| Accepts the same filter kwargs as get_events (state, event_type, filter, etc.). | ||
| :return: GeoJSON FeatureCollection dict | ||
| """ | ||
| params = dict((k, v) for k, v in kwargs.items() if k in | ||
| ('state', 'page_size', 'page', 'event_type', 'filter', | ||
| 'include_notes', 'include_related_events', 'include_files', | ||
| 'include_details', 'updated_since', 'include_updates', | ||
| 'oldest_update_date', 'event_ids')) | ||
| return self._get('activity/events/geojson', params=params) |
Comment on lines
+1728
to
+1741
| async def get_events_geojson(self, **kwargs): | ||
| """ | ||
| Get events as a GeoJSON FeatureCollection. | ||
|
|
||
| Accepts the same filter kwargs as get_events (state, event_type, filter, etc.). | ||
| :return: GeoJSON FeatureCollection dict | ||
| """ | ||
| params = {k: v for k, v in kwargs.items() if k in | ||
| ('state', 'page_size', 'page', 'event_type', 'filter', | ||
| 'include_notes', 'include_related_events', 'include_files', | ||
| 'include_details', 'updated_since', 'include_updates', | ||
| 'oldest_update_date', 'event_ids')} | ||
| return await self._get('activity/events/geojson', params=params) | ||
|
|
| async def _get_raw(self, path, params=None, base_url=None): | ||
| """Issue a GET and return the raw httpx.Response (no JSON parsing). | ||
|
|
||
| Useful for endpoints that return non-JSON payloads (e.g. CSV, GeoJSON, KML). |
Comment on lines
+1853
to
+1854
| async def _get_raw(self, path, params=None, base_url=None): | ||
| """Issue a GET and return the raw httpx.Response (no JSON parsing). |
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
Implements format-specific export methods in both
ERClient(sync) andAsyncERClient(async):GeoJSON (returns parsed JSON):
get_events_geojson(**kwargs)— events as GeoJSON FeatureCollectionget_subjects_geojson(**kwargs)— subjects as GeoJSON FeatureCollectionKML (returns raw response with binary KMZ):
get_subjects_kml(start, end, include_inactive)— all subjects KML documentget_subject_kml(subject_id, start, end)— single subject KML documentVector tiles (returns raw response with binary PBF):
get_observation_segment_tiles(z, x, y)— observation segment MVT tilesget_spatial_feature_tiles(z, x, y)— spatial feature MVT tilesAlso adds
_get_response()async helper toAsyncERClientfor endpoints that return binary content instead of JSON.Test plan
tests/sync_client/test_geojson_kml_tiles.pytests/async_client/test_geojson_kml_tiles.pyRelated