feat: api continuous coverage endpoints - #1816
Conversation
| src/feeds_gen/models/source_info.py | ||
| src/feeds_gen/models/validation_report.py | ||
| src/feeds_gen/security_api.py | ||
| src/user_service/impl/__init__.py |
There was a problem hiding this comment.
These rows are not related to the current PR. However, were deleted in a previous commit by mistake
| raise_http_error(404, f"FeedOrm with id {gtfs_feed_id} not found") | ||
|
|
||
| # Replace Z with +00:00 to make the datetime object timezone aware | ||
| # Due to https://github.com/python/cpython/issues/80010, once migrate to Python 3.11, we can use fromisoformat |
There was a problem hiding this comment.
We are already in Python 3.11.
| nullable: true | ||
| description: Machine-readable error category when the check failed. | ||
| example: timeout | ||
| GtfsFeedContinuousCoverageResponse: |
There was a problem hiding this comment.
Changes to the operations API are related to the schema update. This PR doesn't implement any endpoint that uses the newly generated models.
| if downloaded_before and not valid_iso_date(downloaded_before): | ||
| raise_http_validation_error(invalid_date_message.format("downloaded_before")) | ||
|
|
||
| after_dt = datetime.fromisoformat(downloaded_after) if downloaded_after else None |
There was a problem hiding this comment.
Apparently if you have 2 dates, one naive (no timezone) and the other aware (with timezone), then comparing the two like in the following if results in a TypeError.
Since the dates are provided as parameters to the endpoint, it could happen.
There was a problem hiding this comment.
I was relying on the generated code to validate, but after further testing, there is no enforcement of the TZ. Thanks, Fixed.
| # page that is simply the next item, but the oldest item's neighbour lies outside the page, | ||
| # so it is fetched from the feed's unfiltered datasets - otherwise every page would report a | ||
| # missing overlap at its bottom edge and look like a gap. | ||
| predecessors = page[1:] + [self._previous_dataset(feed_datasets, page[-1]) if page else None] |
There was a problem hiding this comment.
Is it possible that the item inserted at the end in predecessors be one of the NULLed downloaded_at that we pushed to the end of the page in self._continuous_coverage_order()?
I don't know if it would cause a problem.
There was a problem hiding this comment.
Good catch. An undated dataset could get a positional predecessor, and a dated one right before an undated row could get that row reported as its predecessor. Fixed.
Summary:
Closes MobilityData/product-tasks#215
Adds
GET /v1/gtfs_feeds/{id}/continuous_coverage, which returns a GTFS feed's dataset history (newest to oldest, paginated) for the "continuous coverage" criterion of the Seal of Reliability.Expected behavior:
GET /v1/gtfs_feeds/{id}/continuous_coveragereturns 200 with paginateditems[]plus thelatest_*summary fields for the feed's current dataset.downloaded_after/downloaded_beforethat are malformed or out of order return 400.latest_fileslists all three tracked files as absent, and every otherlatest_*field is null.Testing tips:
./scripts/api-tests.sh --test_file api/tests/unittest/models/test_continuous_coverage.py./scripts/api-tests.sh --test_file api/tests/unittest/models/test_gtfs_feed_continuous_coverage_impl.py./scripts/api-tests.sh --test_file api/tests/unittest/test_feeds.pyscripts/api-start.sh, then hitGET localhost:8080/v1/gtfs_feeds/<id>/continuous_coveragefor a feed with several datasets; varylimit/offset/downloaded_after/downloaded_beforeand confirmlatest_*stays constant across pages whileitems[]changes.Please make sure these boxes are checked before submitting your pull request - thanks!
./scripts/api-tests.shto make sure you didn't break anything