feat: [FC-86] add new version of course discovery API - #227
Conversation
|
Thanks for the pull request, @Serj-N! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
15c7542 to
f5f7711
Compare
f5f7711 to
d1ecf82
Compare
brian-smith-tcril
left a comment
There was a problem hiding this comment.
I left a couple comments with questions about test changes that aren't mentioned in the PR description.
| Integration tests using real Meilisearch engine. | ||
| """ | ||
|
|
||
| meilisearch_client = get_meilisearch_client() |
There was a problem hiding this comment.
Could you provide some context as to why this is being moved up here instead of following the previous pattern of calling get_meilisearch_client() in tearDown and wait_for_meilisearch_indexing?
There was a problem hiding this comment.
This is a slight optimization: instead of calling get_meilisearch_client() multiple times, we call it once, store the return value on the test class and then reuse it whenever necessary.
| def tearDown(self): # pragma: no cover | ||
| try: | ||
| self.meilisearch_client.index(TEST_INDEX_NAME).delete() | ||
| except Exception: # pylint: disable=broad-exception-caught |
There was a problem hiding this comment.
A few questions here:
- Why wasn't this try/except needed before?
- Should we really be catching everything?
- Instead of just
passing here, should we log something?
There was a problem hiding this comment.
- Technically, it was needed - to ensure a proper teardown after each test so that we start the following test with a clean slate. This makes our test suite more robust and futureproof (i.e. in case more test methods are added or tests are rearranged).
- and 3. All we care about is to delete the index if it exists, and if an exception is caught - that is okay, and expected, if the index didn't exist in the first place.
There was a problem hiding this comment.
I think we should at least log the exceptions. If there's a bunch of exceptions happening during a test case, that usually indicates some code issue that needs to be cleaned up, and it's better to know about it than quietly ignore it.
| if not task: | ||
| return |
There was a problem hiding this comment.
Why wasn't this needed before?
There was a problem hiding this comment.
This is to ensure that no error is raised in cases where we try to get the last task after all tasks have been completed. Such cases may never occur, but it is a nice-to-have safeguard.
There was a problem hiding this comment.
It would be much more robust to pass in the ID of a specific task to wait for, rather than to generically wait for the most recent task. But I guess this is fine for test purposes.
There was a problem hiding this comment.
Totally agree, and it was my initial intention, but the problem is that create_indexes() does not return anything
|
@bradenmacdonald Hi! This PR is ready for review. When you have a moment, I’d really appreciate it if you could take a look 💯 |
|
@PKulkoRaccoonGang I'll gladly take a look, but I have about 6-8 PRs ahead of this in my review queue so it may take a couple days. |
|
Is it too late to call this API something different btw? "Course Discovery" is a fine name, but makes me think this API is related to the Discovery Service. I would prefer "Course Search API" but I guess that is also easily confused with the "Courseware Search API". Maybe "Course List Search API" ? 😬 |
Personally, I like the suggestion. I have fallen into this trap several times by mixing it with Discovery... |
@bradenmacdonald @sarina @cmltaWt0 @PKulkoRaccoonGang
|
|
My vote would be to
and to file a DEPR for the legacy endpoint, which we could remove once the MFE is default. BUT please let @bradenmacdonald and/or @feanil weigh in on this. |
|
I agree with DEPR the old endpoint without renaming it, and rename the new endpoint. I would also prefer to mark the new endpoint as unstable/v0 because I'm hoping we'll redevelop the whole edx-search API in the future. But I guess we can always DEPR it if and when we get there. |
|
@bradenmacdonald Done, the new endpoint is now |
|
Hi @bradenmacdonald - I know you've got a lot on your plate. So we can effectively plan, could you kindly provide an estimate of when we might expect a review, so we can plan to be prompt on responding? Thanks! |
bradenmacdonald
left a comment
There was a problem hiding this comment.
The main code looks fine. Just some questions about the tests.
I'm wondering, could we combine the test cases and use ddt or pytest.mark.parametrize to switch between the search engines, while still using the same basic data, query, and aggregation test code ?
Also, I haven't tried running this yet. Is there anything I should do to test it in particular, or just verify no regressions with the current API?
| try: | ||
| self.meilisearch_client.get_index(TEST_INDEX_NAME).delete() | ||
| except Exception: # pylint: disable=broad-exception-caught | ||
| pass |
There was a problem hiding this comment.
pylint is right: We should only pass if this is an expected exception like IndexDoesNotExistException . Otherwise, it's not good to suppress the error here.
There was a problem hiding this comment.
Changed, now catching MeilisearchApiError
|
|
||
| def tearDown(self): # pragma: no cover | ||
| try: | ||
| self.meilisearch_client.index(TEST_INDEX_NAME).delete() |
There was a problem hiding this comment.
I don't think we need to delete the index in the tearDown and the setUp. Why not just in the setUp ?
| try: | ||
| self.meilisearch_client.get_index(TEST_INDEX_NAME).delete() | ||
| except Exception: # pylint: disable=broad-exception-caught | ||
| pass |
There was a problem hiding this comment.
Now catching specifically MeilisearchApiError
|
@bradenmacdonald For better or for worse, I reworked test_course_discovery_views.py to combine tests by single-value and multi-value and switch engines via As for testing anything in particular, I believe some basic api calls via Postman should be enough. |
e358f6a to
74739ab
Compare
74739ab to
db57f57
Compare
|
@bradenmacdonald I refactored the tests once more. Short summary:
|
It's probably more a limitation of the current edx-search API? Our Meilisearch code in https://github.com/openedx/edx-platform/blob/master/openedx/core/djangoapps/content/search/api.py waits as needed for tasks just fine - see any usage of |
bradenmacdonald
left a comment
There was a problem hiding this comment.
Thanks for those test refactors. This is good with me.
|
@bradenmacdonald can I put in a nomination to expand your merge rights to this repo? 🙏🏻 |
|
@sarina It would be helpful to have merge rights, yes. Thanks! |
PR Summary
Implement a new API endpoint to support multi-value faceted search for course discovery.
Key Changes:
unstable/v0/course_list_search/Note
Related to: #213