Skip to content

Commit e34ee03

Browse files
committed
Fixes
1 parent fe5c92f commit e34ee03

3 files changed

Lines changed: 37 additions & 16 deletions

File tree

‎src/apify_client/_apify_client.py‎

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@
1212
DEFAULT_TIMEOUT,
1313
)
1414
from apify_client._docs import docs_group
15-
from apify_client._http_clients import (
16-
HttpClient,
17-
HttpClientAsync,
18-
ImpitHttpClient,
19-
ImpitHttpClientAsync,
20-
)
15+
from apify_client._http_clients import HttpClient, HttpClientAsync, ImpitHttpClient, ImpitHttpClientAsync
2116
from apify_client._resource_clients import (
2217
ActorClient,
2318
ActorClientAsync,
@@ -75,6 +70,7 @@
7570
WebhookDispatchCollectionClientAsync,
7671
)
7772
from apify_client._statistics import ClientStatistics
73+
from apify_client._utils import check_custom_headers
7874

7975
if TYPE_CHECKING:
8076
from datetime import timedelta
@@ -143,6 +139,9 @@ def __init__(
143139
api_url = DEFAULT_API_URL if api_url is None else api_url
144140
api_public_url = DEFAULT_API_URL if api_public_url is None else api_public_url
145141

142+
if headers:
143+
check_custom_headers(self.__class__.__name__, headers)
144+
146145
self._token = token
147146
"""Apify API token for authentication."""
148147

@@ -481,6 +480,9 @@ def __init__(
481480
api_url = DEFAULT_API_URL if api_url is None else api_url
482481
api_public_url = DEFAULT_API_URL if api_public_url is None else api_public_url
483482

483+
if headers:
484+
check_custom_headers(self.__class__.__name__, headers)
485+
484486
self._token = token
485487
"""Apify API token for authentication."""
486488

@@ -573,16 +575,6 @@ async def call(self, *, method, url, **kwargs) -> HttpResponse:
573575
instance._http_client = http_client
574576
return instance
575577

576-
@cached_property
577-
def _base_kwargs(self) -> dict:
578-
"""Base keyword arguments for resource client construction."""
579-
return {
580-
'base_url': self._base_url,
581-
'public_base_url': self._public_base_url,
582-
'http_client': self.http_client,
583-
'client_registry': self._client_registry,
584-
}
585-
586578
@property
587579
def token(self) -> str | None:
588580
"""The Apify API token used by the client."""
@@ -606,6 +598,16 @@ def http_client(self) -> HttpClientAsync:
606598
)
607599
return self._http_client
608600

601+
@cached_property
602+
def _base_kwargs(self) -> dict:
603+
"""Base keyword arguments for resource client construction."""
604+
return {
605+
'base_url': self._base_url,
606+
'public_base_url': self._public_base_url,
607+
'http_client': self.http_client,
608+
'client_registry': self._client_registry,
609+
}
610+
609611
def actor(self, actor_id: str) -> ActorClientAsync:
610612
"""Get the sub-client for a specific Actor.
611613

‎src/apify_client/_consts.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,6 @@
4747
}
4848
)
4949
"""Set of terminal Actor job statuses that indicate the job has finished."""
50+
51+
OVERRIDABLE_DEFAULT_HEADERS = {'Accept', 'Authorization', 'Accept-Encoding', 'User-Agent'}
52+
"""Headers that can be overridden by users, but will trigger a warning if they do so, as it may lead to API errors."""

‎src/apify_client/_utils.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import json
77
import string
88
import time
9+
import warnings
910
from base64 import b64encode, urlsafe_b64encode
1011
from enum import Enum
1112
from http import HTTPStatus
1213
from typing import TYPE_CHECKING, Any, Literal, TypeVar, overload
1314

1415
import impit
1516

17+
from apify_client._consts import OVERRIDABLE_DEFAULT_HEADERS
1618
from apify_client.errors import InvalidResponseBodyError
1719

1820
if TYPE_CHECKING:
@@ -346,3 +348,17 @@ def create_storage_content_signature(
346348

347349
base64url_encoded_payload = urlsafe_b64encode(f'{version}.{expires_at}.{hmac_sig}'.encode())
348350
return base64url_encoded_payload.decode('utf-8')
351+
352+
353+
def check_custom_headers(class_name: str, headers: dict[str, str]) -> None:
354+
"""Warn if custom headers override important default headers."""
355+
overwrite_headers = [key for key in headers if key.title() in OVERRIDABLE_DEFAULT_HEADERS]
356+
357+
if overwrite_headers:
358+
warnings.warn(
359+
f'{", ".join(overwrite_headers)} headers of {class_name} was overridden with an '
360+
'explicit value. A wrong header value can lead to API errors, it is recommended to use the default '
361+
f'value for following headers: {", ".join(OVERRIDABLE_DEFAULT_HEADERS)}.',
362+
category=UserWarning,
363+
stacklevel=3,
364+
)

0 commit comments

Comments
 (0)