55from dataclasses import dataclass
66from datetime import datetime , timezone
77from decimal import Decimal
8- from typing import TYPE_CHECKING , Any , Protocol
8+ from typing import TYPE_CHECKING , Protocol , TypedDict
99
1010from 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:
393380class 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
0 commit comments