Skip to content

Commit f846386

Browse files
committed
update types
1 parent d73f5ba commit f846386

File tree

2 files changed

+45
-33
lines changed

2 files changed

+45
-33
lines changed

src/apify/_charging.py

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from dataclasses import dataclass
66
from datetime import datetime, timezone
77
from decimal import Decimal
8-
from typing import TYPE_CHECKING, Any, Protocol
8+
from typing import TYPE_CHECKING, Protocol, TypedDict
99

1010
from pydantic import TypeAdapter
1111

@@ -181,6 +181,9 @@ async def __aenter__(self) -> None:
181181

182182
# Set up charging log dataset for local development
183183
if not self._is_at_home and self._pricing_model == 'PAY_PER_EVENT':
184+
# We are not running on the Apify platform, but PPE is enabled for testing - open a dataset that
185+
# will contain a log of all charge calls for debugging purposes.
186+
184187
if self._purge_charging_log_dataset:
185188
dataset = await Dataset.open(name=self.LOCAL_CHARGING_LOG_DATASET_NAME)
186189
await dataset.drop()
@@ -334,31 +337,15 @@ def get_charged_event_count(self, event_name: str) -> int:
334337
def get_max_total_charge_usd(self) -> Decimal:
335338
return self._max_total_charge_usd
336339

337-
async def _fetch_pricing_info(self) -> dict[str, Any]:
340+
async def _fetch_pricing_info(self) -> _FetchedPricingInfoDict:
338341
"""Fetch pricing information from environment variables or API."""
339342
# Check if pricing info is available via environment variables
340343
if self._configuration.actor_pricing_info and self._configuration.charged_event_counts:
341-
charged_counts = json.loads(self._configuration.charged_event_counts)
342-
343-
# Validate pricing info with proper discriminator support
344-
pricing_info_adapter: TypeAdapter[
345-
FreeActorPricingInfo
346-
| FlatPricePerMonthActorPricingInfo
347-
| PricePerDatasetItemActorPricingInfo
348-
| PayPerEventActorPricingInfo
349-
] = TypeAdapter(
350-
FreeActorPricingInfo
351-
| FlatPricePerMonthActorPricingInfo
352-
| PricePerDatasetItemActorPricingInfo
353-
| PayPerEventActorPricingInfo
344+
return _FetchedPricingInfoDict(
345+
pricing_info=self._configuration.actor_pricing_info,
346+
charged_event_counts=json.loads(self._configuration.charged_event_counts),
347+
max_total_charge_usd=self._configuration.max_total_charge_usd or Decimal('inf'),
354348
)
355-
pricing_info = pricing_info_adapter.validate_json(self._configuration.actor_pricing_info)
356-
357-
return {
358-
'pricing_info': pricing_info,
359-
'charged_event_counts': charged_counts,
360-
'max_total_charge_usd': self._configuration.max_total_charge_usd or Decimal('inf'),
361-
}
362349

363350
# Fall back to API call
364351
if self._is_at_home:
@@ -369,18 +356,18 @@ async def _fetch_pricing_info(self) -> dict[str, Any]:
369356
if run is None:
370357
raise RuntimeError('Actor run not found')
371358

372-
return {
373-
'pricing_info': run.pricing_info,
374-
'charged_event_counts': run.charged_event_counts or {},
375-
'max_total_charge_usd': run.options.max_total_charge_usd or Decimal('inf'),
376-
}
359+
return _FetchedPricingInfoDict(
360+
pricing_info=run.pricing_info,
361+
charged_event_counts=run.charged_event_counts or {},
362+
max_total_charge_usd=run.options.max_total_charge_usd or Decimal('inf'),
363+
)
377364

378365
# Local development without environment variables
379-
return {
380-
'pricing_info': None,
381-
'charged_event_counts': {},
382-
'max_total_charge_usd': self._configuration.max_total_charge_usd or Decimal('inf'),
383-
}
366+
return _FetchedPricingInfoDict(
367+
pricing_info=None,
368+
charged_event_counts={},
369+
max_total_charge_usd=self._configuration.max_total_charge_usd or Decimal('inf'),
370+
)
384371

385372

386373
@dataclass
@@ -393,3 +380,15 @@ class ChargingStateItem:
393380
class PricingInfoItem:
394381
price: Decimal
395382
title: str
383+
384+
385+
class _FetchedPricingInfoDict(TypedDict):
386+
pricing_info: (
387+
FreeActorPricingInfo
388+
| FlatPricePerMonthActorPricingInfo
389+
| PricePerDatasetItemActorPricingInfo
390+
| PayPerEventActorPricingInfo
391+
| None
392+
)
393+
charged_event_counts: dict[str, int]
394+
max_total_charge_usd: Decimal

src/apify/_configuration.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import json
34
from datetime import datetime, timedelta
45
from decimal import Decimal
56
from logging import getLogger
@@ -14,6 +15,12 @@
1415
from crawlee._utils.urls import validate_http_url
1516
from crawlee.configuration import Configuration as CrawleeConfiguration
1617

18+
from apify._models import (
19+
FlatPricePerMonthActorPricingInfo,
20+
FreeActorPricingInfo,
21+
PayPerEventActorPricingInfo,
22+
PricePerDatasetItemActorPricingInfo,
23+
)
1724
from apify._utils import docs_group
1825

1926
logger = getLogger(__name__)
@@ -410,11 +417,17 @@ class Configuration(CrawleeConfiguration):
410417
] = None
411418

412419
actor_pricing_info: Annotated[
413-
str | None,
420+
FreeActorPricingInfo
421+
| FlatPricePerMonthActorPricingInfo
422+
| PricePerDatasetItemActorPricingInfo
423+
| PayPerEventActorPricingInfo
424+
| None,
414425
Field(
415426
alias='apify_actor_pricing_info',
416427
description='JSON string with prising info of the actor',
428+
discriminator='pricing_model',
417429
),
430+
BeforeValidator(lambda data: json.loads(data) if data else None),
418431
] = None
419432

420433
charged_event_counts: Annotated[

0 commit comments

Comments
 (0)