Hi :) Thank you for the library. I am facing an issue which I hope you could help me out.
This is my script
from fastapi_pagination import Page, Params, iterables
from fastapi import Depends, FastAPI
from pydantic import BaseModel
class User(BaseModel):
name: str
app = FastAPI()
users = (User(name="Name_"+str(i)) for i in range(1000))
@app.get(
"/",
response_model=Page[User],
)
def route(params: Params = Depends()):
#return iterables.paginate(users, params, 1000) # this works
return iterables.paginate(users, params)
Here's the traceback
WARNING: StatReload detected file change in 'pag.py'. Reloading...
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [40003]
INFO: Started server process [40028]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: 127.0.0.1:54750 - "GET /?page=2&size=50 HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/uvicorn/protocols/http/h11_impl.py", line 396, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi/applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/middleware/errors.py", line 181, in __call__
raise exc from None
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/middleware/errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/exceptions.py", line 82, in __call__
raise exc from None
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 227, in handle
await self.app(scope, receive, send)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/routing.py", line 41, in app
response = await func(request)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi/routing.py", line 201, in app
raw_response = await run_endpoint_function(
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi/routing.py", line 150, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/starlette/concurrency.py", line 34, in run_in_threadpool
return await loop.run_in_executor(None, func, *args)
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/kishore/kishore_repositories/hx/hawkeye-poc/./pag.py", line 27, in route
return iterables.paginate(users, params)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi_pagination/iterables.py", line 33, in paginate
return create_page(items, total, params) # type: ignore
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi_pagination/api.py", line 36, in create_page
return page_type.get().create(items, total, params)
File "/home/kishore/.cache/pypoetry/virtualenvs/hawkeye-xjjpv_py-py3.9/lib/python3.9/site-packages/fastapi_pagination/default.py", line 40, in create
return cls(
File "pydantic/main.py", line 406, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 1 validation error for Page
total
none is not an allowed value (type=type_error.none.not_allowed)
https://github.com/uriyyo/fastapi-pagination/blob/31a286209878e3caf2b666004fc557ec2e6e3ab3/fastapi_pagination/default.py#L34
https://github.com/uriyyo/fastapi-pagination/blob/31a286209878e3caf2b666004fc557ec2e6e3ab3/fastapi_pagination/bases.py#L89
The above two lines seem to be causing the problem if I'm not wrong.
Is it possible to have it as an optional argument total: int = None
or total: conint(ge=0) = None # type: ignore
?
If you see my example, it works when I pass the length of the generator
return iterables.paginate(users, params, 1000) # this works
My use case is returning all rows from an OLAP. Since the number of rows are around a Million, I would be returning the rows using a generator and returning maybe 50-100 rows at a time to avoid memory overhead
I can see 2 ways to solve this.
- Find the length of the generator and pass it to
iterables.paginate
and not bother modifying fastapi-pagination
. ( or for this particular use case I could get the row count and pass it without bothering to find the length of the generator)
- Modify
fastapi-pagination
to handle None
as a possible parameter for total
pages.
Please let me know your thoughts. I hope this is a reasonable feature to ask.