Skip to content

Commit

Permalink
feat: add new config variables to Actor.config (#351)
Browse files Browse the repository at this point in the history
We have added a few new environment variables:
- `ACTOR_BUILD_TAGS`
- `ACTOR_FULL_NAME`
- `ACTOR_MAX_TOTAL_CHARGE_USD`

This adds corresponding config variables to `Actor.config`.
`ACTOR_BUILD_TAGS` is a comma-separated list of build tags, so I've
added a mechanism to parse the string environment variable into a list.
  • Loading branch information
fnesveda authored Dec 11, 2024
1 parent c4805dc commit 7b6478c
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 7 deletions.
8 changes: 4 additions & 4 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ keywords = [
[tool.poetry.dependencies]
python = "^3.9"
apify-client = ">=1.8.1"
apify-shared = ">=1.1.2"
apify-shared = ">=1.2.1"
crawlee = "~0.4.0"
cryptography = ">=42.0.0"
# TODO: relax the upper bound once the issue is resolved:
Expand Down
34 changes: 33 additions & 1 deletion src/apify/_configuration.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from datetime import datetime, timedelta
from typing import Annotated
from typing import Annotated, Any

from pydantic import AliasChoices, BeforeValidator, Field
from typing_extensions import deprecated
Expand All @@ -13,6 +13,14 @@
from apify._utils import docs_group


def _transform_to_list(value: Any) -> list[str] | None:
if value is None:
return None
if not value:
return []
return value if isinstance(value, list) else str(value).split(',')


@docs_group('Classes')
class Configuration(CrawleeConfiguration):
"""A class for specifying the configuration of an Actor.
Expand All @@ -33,6 +41,13 @@ class Configuration(CrawleeConfiguration):
),
] = None

actor_full_name: Annotated[
str | None,
Field(
description='Full name of the Actor',
),
] = None

actor_run_id: Annotated[
str | None,
Field(
Expand Down Expand Up @@ -67,6 +82,14 @@ class Configuration(CrawleeConfiguration):
),
] = None

actor_build_tags: Annotated[
list[str] | None,
Field(
description='Build tags of the Actor build used in the run',
),
BeforeValidator(_transform_to_list),
] = None

actor_task_id: Annotated[
str | None,
Field(
Expand Down Expand Up @@ -185,6 +208,15 @@ class Configuration(CrawleeConfiguration):
BeforeValidator(lambda val: val or None),
] = None

max_total_charge_usd: Annotated[
float | None,
Field(
alias='actor_max_total_charge_usd',
description='For pay-per-event Actors, the user-set limit on total charges. Do not exceed this limit',
),
BeforeValidator(lambda val: val or None),
] = None

meta_origin: Annotated[
str | None,
Field(
Expand Down
23 changes: 22 additions & 1 deletion tests/unit/actor/test_actor_env_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from apify_shared.consts import (
BOOL_ENV_VARS,
COMMA_SEPARATED_LIST_ENV_VARS,
DATETIME_ENV_VARS,
FLOAT_ENV_VARS,
INTEGER_ENV_VARS,
Expand Down Expand Up @@ -108,9 +109,29 @@ async def test_get_env_with_randomized_env_vars(monkeypatch: pytest.MonkeyPatch)
continue

string_get_env_var = string_env_var.name.lower()
expected_get_env[string_get_env_var] = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
expected_value = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
# URLs have to be valid
if string_get_env_var.endswith('url'):
expected_value = f'http://example.com/{expected_value}'
expected_get_env[string_get_env_var] = expected_value
monkeypatch.setenv(string_env_var, expected_get_env[string_get_env_var])

for list_env_var in COMMA_SEPARATED_LIST_ENV_VARS:
if list_env_var in ignored_env_vars:
continue

available_values = ['val1', 'val2']

list_get_env_var = list_env_var.name.lower()
expected_value_count = random.randint(0, len(available_values))
expected_get_env[list_get_env_var] = random.sample(available_values, expected_value_count)
monkeypatch.setenv(list_env_var, ','.join(expected_get_env[list_get_env_var]))

# Test behavior with mising env var in case of empty list
if expected_value_count == 0 and random.random() < 0.5:
monkeypatch.delenv(list_env_var)
expected_get_env[list_get_env_var] = None

# We need this override so that the actor doesn't fail when connecting to the platform events websocket
monkeypatch.delenv(ActorEnvVars.EVENTS_WEBSOCKET_URL)
monkeypatch.delenv(ApifyEnvVars.ACTOR_EVENTS_WS_URL)
Expand Down

0 comments on commit 7b6478c

Please sign in to comment.