Comments (9)
Building a UI for one example.
from server-client-python.
You can't remove them. By default, you get 100 items per page and without this return value you won't know if you got all of the items / how many items there are. The only way to "get rid of it" would be if we didn't return a list but instead some more complicated object which, as you called get-next eventually asked for the next page as needed. This, however, is something I would build on top of this low level api.
from server-client-python.
to clarify, total is total_available, not how many were returned so it does not necessarily match len(all_workbooks)
from server-client-python.
Thanks for your reply.
I didn't realize that .get doesn't get all resources in the collection by default!
I still think it's very weird to expose this implementation detail do the high-level get call.
When 99% of the time folks are ignoring a return value maybe we don't need to return it.
But your comments make me wonder if there's a different route for me to propose -- should .get
by default get all resources. That's a different issue that I can file.
For now, what about just reversing the return order?
all_workbooks, _ = server.workbooks.get()
from server-client-python.
I've got a working decorator.
It obeys the request options if you specify them, else it just loops at the default size.
I can do a bit more to make this happen by default, but can disable it if you'd like after I learn more about decorator patterns in Python.
I'll get some working code up for a PR with a test but I need to learn how to use the test framework first.
Here's a preview
def paginate(get_call):
from math import ceil
from ..request_options import RequestOptions
def wrapper(self, opts):
all_things = []
# First call
print("FIRST CALL")
res, PI = get_call(self, opts)
all_things.extend(res)
print("ALL THINGS HAS: " + str(len(all_things)))
# Build loop Conditions
number_of_workbooks = PI.total_available
pageSize = PI.page_size
print("TOTAL AVAILABLE: " + str(number_of_workbooks))
print("PAGESIZE: " + str(pageSize))
# Do it
if number_of_workbooks > pageSize: # Need to page through responses
print("NEED TO LOOP")
number_of_pages = ceil(number_of_workbooks / pageSize)
print("THERE ARE THIS MANY PAGES: " + str(number_of_pages))
for pageNum in range(2, number_of_pages + 1):
opts = RequestOptions(pageNum, pageSize)
res, _ = get_call(self, opts)
all_things.extend(res)
return all_things
return wrapper
Then the get call on the workbooks_endpoint just becomes:
@paginate
def get(self, req_options=None):
logger.info('Querying all workbooks on site')
url = self._construct_url()
server_response = self.get_request(url, req_options)
pagination_item = PaginationItem.from_response(server_response.content)
all_workbook_items = WorkbookItem.from_response(server_response.content)
return all_workbook_items, pagination_item
/cc @RussTheAerialist @shinchris @LGraber
from server-client-python.
Couple of comments:
- I was thinking that I wanted a class which could be used to "stream" the list back and hide the pagination, but not necessarily get them all at once. This is a layer on top of what we have and similar to yours above, is only really one class, but this one exposes the list and as you iterate, if it runs out but knows that there are more on the server, it will go and get them. It is useful for building "infinite" scroll experiences. This class could be used to preload everything if we wanted, also. I am not saying we have to do one or the other and not both but we should consider all of the use cases.
- Your decorator always pulls all items which is not something our library should do by default. If we want to key this off of them setting the page_size to "ALL" or something like that, okay, but we should not enforce a behavior that is not always desirable
- There are actually better ways to do "ALL". Specifically, I think a larger page size (perhaps the max of 1000) would be advisable. if they indicate "ALL" we should probably be increasing the page size to try and optimize the interaction with the server. Network latency is not an issue since they will block until we get all of them anyways.
from server-client-python.
Definitely a valid approach, and we could do one or both.
But I really don't see the use case for not wanting them all by default, or with lazy loading them, as far as the complexity it could introduce into the code.
When getting a list of all workbooks you're likely going to do something to that list shortly after, either a bulk update or a bulk filter/map/read type operation. I don't think we save much time by calling them lazily if most code will be:
wbs = server.workbooks.get()
for w in wbs:
do_stuff(w)
We have other methods to get a specific workbook (get_workbook_by_id
). I think this endpoint really implies 'all'. Maybe that's the philosophical question to resolve.
Consider the case where I build a RequestOptions with a filter and a sort and forget to change the default page size, I don't realize my 100 results aren't all of them, without all my calling code checking total_available. But why would I ever not want all my search results?
It's possible I just can't think of the use cases around this -- anyone have any that I'm missing?
from server-client-python.
@t8y8 Are you content with the implementation of the Pager object wrt to this Design Proposal? If so, can you close this issue?
from server-client-python.
Yup, it’s been working smoothly for months. I didn’t address tags or the need to copy objects but I think paging is much saner now, I’m happy.
from server-client-python.
Related Issues (20)
- Update node in actions
- Urllib3 vulnerability HOT 1
- Replace custom time handling with datetime/timedelta
- 0.29 Release: NotSignedInError - Intermittent issue pulling PDFs HOT 4
- When downloading the flow, a KeyError: 'content-disposition' occurs. HOT 13
- Refreshing Datasources results in 409093 EXTRACT_OPERATION_ALREADY_QUEUED HOT 5
- Unauthorized Access error when signing out (either explicitly or at the end of a `with` block) HOT 8
- cgi is deprecated, and will be removed in 3.13 HOT 1
- Schedule Type enum doesn't seem to include 'System'
- Error Code 401002 Unauthorized Access at end of authentication loop or upon sign-out HOT 1
- Internal Server Error when publishing a data source size is > 64 MB HOT 1
- [Type 1] [Set workbook description on publish] HOT 2
- server.tasks.get() call does not properly handle interval of 24 for daily refresh tasks in Tableau Cloud HOT 1
- Schedules cannot handle valid monthly schedules HOT 1
- TYPE 3 - ADD GRANTEE NAME TO GRANTEE OBJECT
- Getting internal server error 503
- AttributeError: 'NoneType' object has no attribute 'id' HOT 3
- Retrieving subscriptions failed for frequency = Daily, hour (interval) = 24 HOT 2
- Invalid interval value for a monthly frequency: Customized Monthly. HOT 2
- [TYPE 3] [Query View Data - Select sheet in dashboard]
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from server-client-python.