Skip to content
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

Pagination #155

Open
zupo opened this issue Sep 15, 2021 · 0 comments
Open

Pagination #155

zupo opened this issue Sep 15, 2021 · 0 comments

Comments

@zupo
Copy link
Collaborator

zupo commented Sep 15, 2021

@miohtama asked me if I have any examples of how to do pagination with pyramid_openapi3.

I don't, but I have some private code that I could potentially share. Ideally, this would be added to README, or be made in to a tutorial. But until this time, let's at least have some information about pagination in this ticket here.

So, firstly, we have this in kafkai.com's openapi.yaml:

        - name: page
          in: query
          description: Page number (default is 1)
          required: false
          schema:
            type: integer
            default: 1
            minimum: 1
        - name: pageSize
          in: query
          description: Limit number of articles returned (default is 20)
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 100

Then we have the following in the view that handles the /articles endpoint:

page = request.openapi_validated.parameters["query"].get("page", 1)
page_size = request.openapi_validated.parameters["query"].get("pageSize", 20)

return Article.current_user_by(
    request=request,
    page=page,
    page_size=page_size,
    search=search,
    niches=niches,
    ratings=ratings,
    states=states,
    article_ids=article_ids,
    db=request.db,
)

The current_used_by() gets an article from Postgres with SQLAlchemy with the currently logged-in user as context:

@classmethod
def current_user_by(
    cls: t.Type[Article],
    request: Request,
    page: int,
    page_size: int,
    search: str,
    niches: t.List[Niche],
    states: t.List[ArticleState],
    ratings: t.List[Rating],
    article_ids: t.List[str],
    db: Session,
) -> Articles:
    """Get Articles in given states if it matches current user."""

q = query_current_user(cls, request)

[... snip ...]

count = q.count()
results_per_page = q.offset(page_size * (page - 1)).limit(page_size)

return {
    "articles": results_per_page.all(),
    "page": page,
    "pageCount": math.ceil(count / page_size),
    "pageSize": page_size,
    "total": count,
}

And this is it. Hopefully it helps someone. And hopefully someone (me?) finds time in the near future to create an example-app for pagination.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant