pyramid_openapi3
pyramid_openapi3 copied to clipboard
Pagination
@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.