Skip to content

Commit

Permalink
Merge pull request #2707 from ziv17/2697-nf-api-pagination
Browse files Browse the repository at this point in the history
2697 nf api pagination
  • Loading branch information
atalyaalon authored Oct 6, 2024
2 parents ba0d634 + 695a04b commit 4f138c6
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 9 deletions.
35 changes: 26 additions & 9 deletions anyway/views/news_flash/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
DEFAULT_NUMBER_OF_YEARS_AGO = 5
PAGE_NUMBER = "pageNumber"
PAGE_SIZE = "pageSize"
NEWS_FALSH_ID = "newsFlash_Id"
NEWS_FLASH_ID = "newsFlashId"
ID = "id"
LIMIT = "limit"
OFFSET = "offset"
Expand All @@ -51,6 +51,7 @@ class NewsFlashQuery(BaseModel):
offset: Optional[int] = DEFAULT_OFFSET_REQ_PARAMETER
pageNumber: Optional[int]
pageSize: Optional[int]
newsFlashId: Optional[int]
limit: Optional[int] = DEFAULT_LIMIT_REQ_PARAMETER
resolution: Optional[List[str]]
source: Optional[List[BE_CONST.Source]]
Expand All @@ -75,6 +76,12 @@ def check_supported_resolutions(cls, v):
raise ValueError(f"Resolution must be one of: {supported_resolutions}")
return requested_resolutions

@validator(PAGE_NUMBER)
def check_page_number(cls, v, values):
if v <= 0:
raise ValueError("pageNumber must be positive")
return v


def news_flash():
requested_query_params = normalize_query(request.args)
Expand All @@ -85,10 +92,10 @@ def news_flash():

pagination, validated_query_params = set_pagination_params(validated_query_params)

if ID in validated_query_params:
if not pagination and ID in validated_query_params:
return get_news_flash_by_id(validated_query_params[ID])

total, query = gen_news_flash_query(db.session, validated_query_params)
total, query = gen_news_flash_query(db.session, validated_query_params, pagination)
news_flashes = query.all()

news_flashes_dicts = [n.serialize() for n in news_flashes]
Expand All @@ -104,20 +111,22 @@ def news_flash():

def set_pagination_params(validated_params: dict) -> Tuple[bool, dict]:
pagination = False
if NEWS_FALSH_ID in validated_params:
validated_params[ID] = validated_params.pop(NEWS_FALSH_ID)
if PAGE_NUMBER in validated_params:
page_size = validated_params.get(PAGE_SIZE, DEFAULT_LIMIT_REQ_PARAMETER)
if NEWS_FLASH_ID in validated_params:
validated_params[ID] = validated_params.pop(NEWS_FLASH_ID)
pagination = True
elif PAGE_NUMBER in validated_params:
pagination = True
page_number = validated_params[PAGE_NUMBER]
page_size = validated_params.get(PAGE_SIZE, DEFAULT_LIMIT_REQ_PARAMETER)
validated_params[OFFSET] = (page_number - 1) * page_size
if pagination:
validated_params[LIMIT] = page_size
return pagination, validated_params


def add_pagination_to_result(validated_params: dict, news_flashes: list, num_nf: int) -> dict:
page_size = validated_params[PAGE_SIZE]
page_num = validated_params[PAGE_NUMBER]
page_num = validated_params[OFFSET] // page_size + 1
total_pages = num_nf // page_size + (1 if num_nf % page_size else 0)
return {
"data": news_flashes,
Expand All @@ -130,7 +139,7 @@ def add_pagination_to_result(validated_params: dict, news_flashes: list, num_nf:
}


def gen_news_flash_query(session, valid_params: dict) -> Tuple[int, Any]:
def gen_news_flash_query(session, valid_params: dict, pagination: bool = False) -> Tuple[int, Any]:
query = session.query(NewsFlash)
supported_resolutions = set([x.value for x in BE_CONST.SUPPORTED_RESOLUTIONS])
query = query.filter(NewsFlash.resolution.in_(supported_resolutions))
Expand All @@ -156,6 +165,14 @@ def gen_news_flash_query(session, valid_params: dict) -> Tuple[int, Any]:
not_(and_(NewsFlash.lat == None, NewsFlash.lon == None)),
)
).order_by(NewsFlash.date.desc())
if pagination and "id" in valid_params:
nf = query.filter(NewsFlash.id == valid_params["id"]).first()
if nf is None:
raise ValueError(f"{valid_params['id']}: not found")
id_offset = query.filter(NewsFlash.date > nf.date).count()
page_number = id_offset // valid_params[LIMIT]
valid_params["offset"] = page_number * valid_params["limit"]

total = query.count()
if "offset" in valid_params:
query = query.offset(valid_params["offset"])
Expand Down
45 changes: 45 additions & 0 deletions tests/test_news_flash_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
is_news_flash_resolution_supported,
gen_news_flash_query,
update_news_flash_qualifying,
add_pagination_to_result,
PAGE_SIZE,
OFFSET,
)
from anyway.backend_constants import BE_CONST
from anyway.models import LocationVerificationHistory, NewsFlash, Users
Expand Down Expand Up @@ -222,6 +225,48 @@ def test_gen_news_flash_query(self):

BE_CONST.SUPPORTED_RESOLUTIONS = orig_supported_resolutions

def test_add_pagination_to_result(self):
actual = add_pagination_to_result({PAGE_SIZE: 3, OFFSET: 0}, [], 10)
self.assertEqual(
{
"pageNumber": 1,
"pageSize": 3,
"totalPages": 4,
"totalRecords": 10
},
actual["pagination"],
"1")
actual = add_pagination_to_result({PAGE_SIZE: 3, OFFSET: 2}, [], 10)
self.assertEqual(
{
"pageNumber": 1,
"pageSize": 3,
"totalPages": 4,
"totalRecords": 10
},
actual["pagination"],
"2")
actual = add_pagination_to_result({PAGE_SIZE: 3, OFFSET: 3}, [], 10)
self.assertEqual(
{
"pageNumber": 2,
"pageSize": 3,
"totalPages": 4,
"totalRecords": 10
},
actual["pagination"],
"3")
actual = add_pagination_to_result({PAGE_SIZE: 3, OFFSET: 9}, [], 10)
self.assertEqual(
{
"pageNumber": 4,
"pageSize": 3,
"totalPages": 4,
"totalRecords": 10
},
actual["pagination"],
"4")

def tearDown(self):
self.session.close()

Expand Down

0 comments on commit 4f138c6

Please sign in to comment.