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

Page with original response structure #1327

Open
mattibo opened this issue Oct 10, 2024 · 1 comment
Open

Page with original response structure #1327

mattibo opened this issue Oct 10, 2024 · 1 comment
Assignees
Labels
question Further information is requested

Comments

@mattibo
Copy link

mattibo commented Oct 10, 2024

Hi @uriyyo,

I would like to have a pagination style like the GitHub REST API (using link in reponse header) but with the original content as the response (and not the content nested inside e.g. items list with the default Page). Is this possible?

@uriyyo uriyyo self-assigned this Oct 10, 2024
@uriyyo uriyyo added the question Further information is requested label Oct 10, 2024
@uriyyo
Copy link
Owner

uriyyo commented Oct 13, 2024

Hi @mattibo,

Unfortunately, there is no easy solution like just import stmh like UseHeaderLinks but you can implement you own Page:

from typing import Any, Sequence, TypeVar

from fastapi.applications import FastAPI
from pydantic import RootModel
from typing_extensions import Self

from fastapi_pagination import Page, add_pagination, paginate, response
from fastapi_pagination.bases import AbstractPage, AbstractParams
from fastapi_pagination.links import Page as LinksPage

app = FastAPI()
add_pagination(app)

T = TypeVar("T")


class FlatPage(RootModel[list[T]], AbstractPage[T]):
    __params_type__ = Page.__params_type__

    @classmethod
    def create(
        cls,
        items: Sequence[T],
        params: AbstractParams,
        **kwargs: Any,
    ) -> Self:
        with_links = LinksPage.create(items, params, **kwargs)

        links = []
        for rel, link in (
            ("first", with_links.links.first),
            ("last", with_links.links.last),
            ("next", with_links.links.next),
            ("prev", with_links.links.prev),
        ):
            if link is not None:
                links.append(f'<{link}>; rel="{rel}"')

        if links:
            rsp = response()
            rsp.headers["Link"] = ", ".join(links)

        return cls(with_links.items)


@app.get("/items")
async def read_items() -> FlatPage[int]:
    return paginate(range(1_000))


if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app)

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

No branches or pull requests

2 participants