Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/apify_client/_http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
import impit
from apify_shared.utils import ignore_docs, is_content_type_json, is_content_type_text, is_content_type_xml

from apify_client._errors import ApifyApiError, InvalidResponseBodyError, is_retryable_error
from apify_client._logging import log_context, logger_name
from apify_client._statistics import Statistics
from apify_client._utils import retry_with_exp_backoff, retry_with_exp_backoff_async
from apify_client._utils import is_retryable_error, retry_with_exp_backoff, retry_with_exp_backoff_async
from apify_client.errors import ApifyApiError, InvalidResponseBodyError

if TYPE_CHECKING:
from collections.abc import Callable
Expand Down
18 changes: 17 additions & 1 deletion src/apify_client/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
from http import HTTPStatus
from typing import TYPE_CHECKING, Any, TypeVar, cast

import impit
from apify_shared.utils import is_file_or_bytes, maybe_extract_enum_member_value

from apify_client.errors import InvalidResponseBodyError

if TYPE_CHECKING:
from collections.abc import Awaitable

from apify_client._errors import ApifyApiError
from apify_client.errors import ApifyApiError

PARSE_DATE_FIELDS_MAX_DEPTH = 3
PARSE_DATE_FIELDS_KEY_SUFFIX = 'At'
Expand Down Expand Up @@ -149,3 +152,16 @@ def encode_key_value_store_record_value(value: Any, content_type: str | None = N
value = json.dumps(value, ensure_ascii=False, indent=2, allow_nan=False, default=str).encode('utf-8')

return (value, content_type)


def is_retryable_error(exc: Exception) -> bool:
"""Check if the given error is retryable."""
return isinstance(
exc,
(
InvalidResponseBodyError,
impit.NetworkError,
impit.TimeoutException,
impit.RemoteProtocolError,
),
)
2 changes: 1 addition & 1 deletion src/apify_client/clients/base/actor_job_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from apify_shared.consts import ActorJobStatus
from apify_shared.utils import ignore_docs, parse_date_fields

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, pluck_data
from apify_client.clients.base.resource_client import ResourceClient, ResourceClientAsync
from apify_client.errors import ApifyApiError

DEFAULT_WAIT_FOR_FINISH_SEC = 999999

Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/base/resource_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

from apify_shared.utils import ignore_docs, parse_date_fields

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, pluck_data
from apify_client.clients.base.base_client import BaseClient, BaseClientAsync
from apify_client.errors import ApifyApiError


@ignore_docs
Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/resource_clients/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from apify_shared.models import ListPage
from apify_shared.utils import filter_out_none_values_recursively, ignore_docs

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, pluck_data
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from collections.abc import AsyncIterator, Iterator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

from apify_shared.utils import filter_out_none_values_recursively, ignore_docs, parse_date_fields

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, encode_key_value_store_record_value, pluck_data
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from collections.abc import AsyncIterator, Iterator
Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/resource_clients/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

from apify_shared.utils import ignore_docs

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from collections.abc import AsyncIterator, Iterator
Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/resource_clients/request_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
from apify_shared.utils import filter_out_none_values_recursively, ignore_docs, parse_date_fields
from more_itertools import constrained_batches

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, pluck_data
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from datetime import timedelta
Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/resource_clients/schedule.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

from apify_shared.utils import filter_out_none_values_recursively, ignore_docs

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, pluck_data_as_list
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.errors import ApifyApiError


def _get_schedule_representation(
Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/resource_clients/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
parse_date_fields,
)

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, encode_webhook_list_to_base64, pluck_data
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.clients.resource_clients.run import RunClient, RunClientAsync
Expand All @@ -19,6 +18,7 @@
WebhookCollectionClient,
WebhookCollectionClientAsync,
)
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from apify_shared.consts import ActorJobStatus, MetaOrigin
Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/resource_clients/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

from apify_shared.utils import filter_out_none_values_recursively, ignore_docs, parse_date_fields

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, pluck_data
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.errors import ApifyApiError


class UserClient(ResourceClient):
Expand Down
2 changes: 1 addition & 1 deletion src/apify_client/clients/resource_clients/webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@
parse_date_fields,
)

from apify_client._errors import ApifyApiError
from apify_client._utils import catch_not_found_or_throw, pluck_data
from apify_client.clients.base import ResourceClient, ResourceClientAsync
from apify_client.clients.resource_clients.webhook_dispatch_collection import (
WebhookDispatchCollectionClient,
WebhookDispatchCollectionClientAsync,
)
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from apify_shared.consts import WebhookEventType
Expand Down
18 changes: 4 additions & 14 deletions src/apify_client/_errors.py → src/apify_client/errors.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from __future__ import annotations

import json as jsonlib
from typing import TYPE_CHECKING

import impit
from apify_shared.utils import ignore_docs

if TYPE_CHECKING:
import impit


class ApifyClientError(Exception):
"""Base class for errors specific to the Apify API Client."""
Expand Down Expand Up @@ -75,16 +78,3 @@ def __init__(self, response: impit.Response) -> None:
self.name = 'InvalidResponseBodyError'
self.code = 'invalid-response-body'
self.response = response


def is_retryable_error(exc: Exception) -> bool:
"""Check if the given error is retryable."""
return isinstance(
exc,
(
InvalidResponseBodyError,
impit.NetworkError,
impit.TimeoutException,
impit.RemoteProtocolError,
),
)
2 changes: 1 addition & 1 deletion tests/unit/test_client_errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import pytest
from werkzeug import Response

from apify_client._errors import ApifyApiError
from apify_client._http_client import HTTPClient, HTTPClientAsync
from apify_client.errors import ApifyApiError

if TYPE_CHECKING:
from collections.abc import Iterator
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_client_request_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ async def test_batch_not_processed_raises_exception_async(httpserver: HTTPServer
]
rq_client = client.request_queue(request_queue_id='whatever')

with pytest.raises(apify_client._errors.ApifyApiError):
with pytest.raises(apify_client.errors.ApifyApiError):
await rq_client.batch_add_requests(requests=requests)


Expand Down Expand Up @@ -77,7 +77,7 @@ def test_batch_not_processed_raises_exception_sync(httpserver: HTTPServer) -> No
]
rq_client = client.request_queue(request_queue_id='whatever')

with pytest.raises(apify_client._errors.ApifyApiError):
with pytest.raises(apify_client.errors.ApifyApiError):
rq_client.batch_add_requests(requests=requests)


Expand Down
Loading