ej2 / python-quickbooks

A Python library for accessing the Quickbooks API.
MIT License
394 stars 193 forks source link

Include a paginate decorator #343

Closed tubaman closed 5 months ago

tubaman commented 6 months ago

It would be handy to include a decorator to automatically paginate things like Purchase.all(). I've been using something like:

def paginate(page_size=1000):
    logger.debug("page_size: %r", page_size)
    def decorator(f):
        cls = f.__self__
        @wraps(f)
        def wrapper(*args, **kwargs):
            if 'start_position' in kwargs:
                raise ValueError("You can't paginate and specify start_position")
            if 'max_results' in kwargs:
                raise ValueError("You can't paginate and specify max_results")
            total = cls.count(*args, **kwargs)
            start_position = 1
            remaining = total - start_position - 1
            while remaining > 0:
                logger.debug("remaining: %r", remaining)
                logger.debug("start_position: %r", start_position)
                objects = f(*args, start_position=start_position, max_results=page_size, **kwargs)
                logger.debug("len(objects): %r", len(objects))
                remaining -= len(objects)
                start_position += len(objects)
                yield from objects
        return wrapper
    return decorator

...to do things like:

for purchase in paginate()(Purchase.all)(qb=client.qb):
    print(purchase)
tubaman commented 6 months ago

Using pagination method documented here: https://developer.intuit.com/app/developer/qbo/docs/learn/explore-the-quickbooks-online-api/data-queries#server-response

ej2 commented 5 months ago

If you want to put a PR together for this, I will review it.