Skip to content

Commit 8a8306f

Browse files
committed
fix: Handle truncated unique_key in list_head by fetching full request data
Closes: #627
1 parent af01e50 commit 8a8306f

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

src/apify/storage_clients/_apify/_request_queue_single_client.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,14 @@ async def _list_head(self) -> None:
236236

237237
# Update the cached data
238238
for request_data in response.get('items', []):
239+
# Due to https://github.com/apify/apify-core/blob/v0.1377.0/src/api/src/lib/request_queues/request_queue.ts#L53,
240+
# the list_head endpoint may return truncated fields for long requests (e.g., long URLs or unique keys).
241+
# If truncation is detected, fetch the full request data by its ID from the API.
242+
# This is a temporary workaround - the caching will be refactored to use request IDs instead of unique keys.
243+
# See https://github.com/apify/apify-sdk-python/issues/630 for details.
244+
if '[truncated]' in request_data['uniqueKey'] or '[truncated]' in request_data['url']:
245+
request_data = await self._api_client.get_request(request_id=request_data['id']) # noqa: PLW2901
246+
239247
request = Request.model_validate(request_data)
240248

241249
if request.unique_key in self._requests_in_progress:
@@ -248,15 +256,14 @@ async def _list_head(self) -> None:
248256
# Only fetch the request if we do not know it yet.
249257
if request.unique_key not in self._requests_cache:
250258
request_id = unique_key_to_request_id(request.unique_key)
251-
complete_request_data = await self._api_client.get_request(request_id)
252-
253-
if complete_request_data is not None:
254-
request = Request.model_validate(complete_request_data)
255-
self._requests_cache[request.unique_key] = request
256-
else:
259+
if request_data is not None and request_id != request_data['id']:
257260
logger.warning(
258-
f'Could not fetch request data for unique_key=`{request.unique_key}` (id=`{request_id}`)'
261+
f'Request ID mismatch: {request_id} != {request_data["id"]}, '
262+
'this may cause unexpected behavior.'
259263
)
264+
full_request_data = await self._api_client.get_request(request_id)
265+
request = Request.model_validate(full_request_data)
266+
self._requests_cache[request.unique_key] = request
260267

261268
# Add new requests to the end of the head, unless already present in head
262269
if request.unique_key not in self._head_requests:

tests/integration/test_actor_request_queue.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,3 +489,41 @@ async def main() -> None:
489489
run_result = await run_actor(actor)
490490

491491
assert run_result.status == 'SUCCEEDED'
492+
493+
494+
@pytest.mark.only
495+
async def test_rq_long_url(
496+
make_actor: MakeActorFunction,
497+
run_actor: RunActorFunction,
498+
) -> None:
499+
async def main() -> None:
500+
from apify import Actor, Request
501+
from apify.storage_clients._apify._utils import unique_key_to_request_id
502+
503+
url = 'https://portal.isoss.gov.cz/irj/portal/anonymous/mvrest?path=/eosm-public-offer&officeLabels=%7B%7D&page=1&pageSize=100000&sortColumn=zdatzvsm&sortOrder=-1'
504+
505+
async with Actor:
506+
request = Request.from_url(
507+
url=url,
508+
use_extended_unique_key=True,
509+
always_enqueue=True,
510+
)
511+
512+
rq = await Actor.open_request_queue(force_cloud=True)
513+
request_id = unique_key_to_request_id(request.unique_key)
514+
515+
processed_request = await rq.add_request(request)
516+
assert processed_request.id == request_id
517+
518+
request_obtained = await rq.fetch_next_request()
519+
assert request_obtained is not None
520+
521+
await rq.mark_request_as_handled(request_obtained)
522+
523+
is_finished = await rq.is_finished()
524+
assert is_finished
525+
526+
actor = await make_actor(label='long-url', main_func=main)
527+
run_result = await run_actor(actor)
528+
529+
assert run_result.status == 'SUCCEEDED'

0 commit comments

Comments
 (0)