-
Notifications
You must be signed in to change notification settings - Fork 64
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
Add pagination and search functionality to job collection API #1029
base: master
Are you sure you want to change the base?
Conversation
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.
i'm assuming this is related to the hackathon efforts last year to come up with a new tron ui, but adding additional context into the description would be nice (in case i'm wrong or for folks that don't have that knowledge)
and sidenote: how are we envisioning the search function being used? i noticed that it's not currently being paged - is that an oversight or something for future us to handle?
return respond(request=request, response=response) | ||
|
||
@AsyncResource.bounded | ||
def render_SEARCH(self, request): |
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.
my understanding is that the render_*
functions are named after the HTTP request method used for the request that's being handled and that that SEARCH is not standard HTTP method and that we probably want QUERY? that said, not sure if that's still a draft RFC or if it's actually part of the standard
but just to confirm: the intent is that we'll have the troncli/ui use SEARCH/QUERY verbs to hit this new function?
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.
Yes your understanding is correct and I did added SEARCH
as a custom http verb and it is not part of the standard, I don't even think it's part of a draft. It did't felt wrong when I was doing it but also all of this code is from a hackathon project so I was more focus on getting something built fast.
I'm more than happy to take suggestions on what endpoint we can drop the search at or we can have a discussion about if it makes sense to have the custom http verb
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.
TIL: HTTP SEARCH verb is a thing
if page < 1 or page_size < 1: | ||
return respond( | ||
request=request, | ||
response={"error": "page and page_size must be positive integers"}, | ||
code=http.BAD_REQUEST, | ||
) | ||
if page > math.ceil(total / page_size): | ||
return respond( | ||
request=request, | ||
response={"error": "page out of range"}, | ||
code=http.BAD_REQUEST, | ||
) |
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.
might be nice to have a validate function so that we can do something like:
request_ok, request_error = self.job_collection.validate_paging_params(page, page_size)
if not request_ok:
return respond(
request=request
response={"error": request_error},
code=http.BAD_REQUEST,
)
page, | ||
page_size, |
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.
we're using page/page_size here before validating them - is that intentional?
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.
Great catch!!! this is a good point!!! most of the page validation happens a bit after on the code, handling exceptions here makes more sense.
jobs = self.job_collection.get_jobs() | ||
if page is not None and page_size is not None: | ||
start = (page - 1) * page_size | ||
jobs = jobs[start : start + page_size] |
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.
jobs = self.job_collection.get_jobs() | |
if page is not None and page_size is not None: | |
start = (page - 1) * page_size | |
jobs = jobs[start : start + page_size] | |
if page is not None and page_size is not None: | |
jobs = self.job_collection.get_jobs_by_page( | |
page, | |
page_size, | |
) | |
else: | |
jobs = self.job_collection.get_jobs() |
might make testing easier (since then we can test the paging logic without testing the rest of get_data
)
assert "jobs" in result | ||
|
||
def test_render_SEARCH(self): | ||
request = build_request(query="test") | ||
job1 = MagicMock() |
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.
nit: we should probably set the spec
on these to whatever the real type of these is so that the tests better match reality (e.g., so that the mocks fail should we ever remove get_name
from the actual type, etc)
response = dict(jobs=jobs, pagination=dict(page=page, page_size=page_size, total=total)) | ||
else: | ||
response = dict(jobs=jobs) |
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.
imo, inlining the dicts rather than calling the dict constructor would be more modern/easier to read - that said, we have pretty mixed usage of dict/{} in this file already so not a blocker
|
||
@AsyncResource.bounded | ||
def render_SEARCH(self, request): | ||
query = requestargs.get_string(request, "query") |
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.
do we need to do any validation on the query
data?
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.
Search is currently very basic we could maybe limit the length of the string 🤷🏽 we also don't use it in a way that could lead to SQL injections
All your assumptions are correct:
|
This pull request introduces pagination and search functionality to the
tron/api/resource.py
module and updates the corresponding tests. These changes are efforts to enhance tronweb responsiveness by having pagination on the main dashboard. The most important changes include adding pagination parameters to theget_data
method, modifying therender_GET
method to handle pagination, and introducing a newrender_SEARCH
method to support search queries.Enhancements to
tron/api/resource.py
:page
andpage_size
parameters to theget_data
method to support pagination.render_GET
method to handle pagination logic, including validation and response formatting.render_SEARCH
method to filter jobs based on a search query.Updates to tests:
test_render_GET
method intests/api/resource_test.py
to include new pagination parameters in theassert_call
function.test_render_SEARCH
method to test the search functionality.Additional imports:
math
module import intron/api/resource.py
to support pagination calculations.