Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 7 additions & 2 deletions src/apify/_actor.py
Original file line number Diff line number Diff line change
Expand Up @@ -597,22 +597,26 @@ def new_client(
*,
token: str | None = None,
api_url: str | None = None,
api_public_url: str | None = None,
max_retries: int | None = None,
min_delay_between_retries: timedelta | None = None,
timeout: timedelta | None = None,
) -> ApifyClientAsync:
"""Return a new instance of the Apify API client.

The `ApifyClientAsync` class is provided by the [apify-client](https://github.com/apify/apify-client-python)
package, and it is automatically configured using the `APIFY_API_BASE_URL` and `APIFY_TOKEN` environment
variables.
package, and it is automatically configured using the `APIFY_API_BASE_URL`, `APIFY_API_PUBLIC_BASE_URL` and
`APIFY_TOKEN` environment variables.

You can override the token via the available options. That's useful if you want to use the client
as a different Apify user than the SDK internals are using.

Args:
token: The Apify API token.
api_url: The URL of the Apify API server to which to connect to. Defaults to https://api.apify.com.
api_public_url: The globally accessible URL of the Apify API server, used to build public URLs of
resources. Defaults to the `APIFY_API_PUBLIC_BASE_URL` environment variable, or to
https://api.apify.com when it is not set.
max_retries: How many times to retry a failed request at most.
min_delay_between_retries: How long will the client wait between retrying requests
(increases exponentially from this value).
Expand All @@ -626,6 +630,7 @@ def new_client(
client_kwargs: dict[str, Any] = {
'token': token or self.configuration.token,
'api_url': api_url or self.configuration.api_base_url,
'api_public_url': api_public_url or self.configuration.api_public_base_url,
'compression': 'brotli',
}
if max_retries is not None:
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/actor/test_actor_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from apify_client import ApifyClientAsync
from apify_client._models import Run
from apify_client._resource_clients import KeyValueStoreClientAsync
from crawlee.events._types import Event

from apify import Actor, Webhook
Expand Down Expand Up @@ -85,6 +86,25 @@ async def test_new_client_config_creation(monkeypatch: pytest.MonkeyPatch) -> No
await my_actor.exit()


async def test_new_client_uses_configured_api_public_base_url(monkeypatch: pytest.MonkeyPatch) -> None:
"""`new_client` builds public URLs on the configured `api_public_base_url` host."""
monkeypatch.setenv(ApifyEnvVars.API_BASE_URL, 'http://internal-api.example.com')
monkeypatch.setenv(ApifyEnvVars.API_PUBLIC_BASE_URL, 'https://public-api.example.com')
monkeypatch.setattr(KeyValueStoreClientAsync, 'get', AsyncMock(return_value=None))
my_actor = _ActorType()
await my_actor.init()

client = my_actor.new_client()
public_url = await client.key_value_store('store-id').get_record_public_url('key')
assert public_url == 'https://public-api.example.com/v2/key-value-stores/store-id/records/key'

client_with_override = my_actor.new_client(api_public_url='https://override.example.com')
public_url = await client_with_override.key_value_store('store-id').get_record_public_url('key')
assert public_url == 'https://override.example.com/v2/key-value-stores/store-id/records/key'

await my_actor.exit()


async def test_call_actor(apify_client_async_patcher: ApifyClientAsyncPatcher, fake_actor_run: Run) -> None:
apify_client_async_patcher.patch('actor', 'call', return_value=fake_actor_run)
actor_id = 'some-actor-id'
Expand Down
Loading