@@ -49,6 +49,7 @@ def __init__(self, configuration: Configuration, client: ApifyClientAsync) -> No
4949 self ._not_ppe_warning_printed = False
5050
5151 async def init (self ) -> None :
52+ """Initialize the charging manager - this is called by the `Actor` class and shouldn't be invoked manually."""
5253 self ._charging_state = {}
5354
5455 if self ._is_at_home :
@@ -86,15 +87,21 @@ async def init(self) -> None:
8687 self ._charging_log_dataset = await Dataset .open (name = self .LOCAL_CHARGING_LOG_DATASET_NAME )
8788
8889 async def charge (self , event_name : str , count : int = 1 ) -> ChargeResult :
90+ """Charge for a specified number of events - sub-operations of the Actor.
91+
92+ This is relevant only for the pay-per-event pricing model.
93+ """
8994 if self ._charging_state is None :
9095 raise RuntimeError ('Charging manager is not initialized' )
9196
9297 def calculate_chargeable () -> dict [str , int | None ]:
98+ """Calculate the maximum number of events of each type that can be charged within the current budget."""
9399 return {
94100 event_name : self .calculate_max_event_charge_count_within_limit (event_name )
95101 for event_name in self ._pricing_info
96102 }
97103
104+ # For runs that do not use the pay-per-event pricing model, just print a warning and return
98105 if self ._pricing_model != 'PAY_PER_EVENT' :
99106 if not self ._not_ppe_warning_printed :
100107 logger .warning (
@@ -109,6 +116,8 @@ def calculate_chargeable() -> dict[str, int | None]:
109116 )
110117
111118 # START OF CRITICAL SECTION - no awaits here
119+
120+ # Determine the maximum amount of events that can be charged within the budget
112121 charged_count = min (count , self .calculate_max_event_charge_count_within_limit (event_name ) or count )
113122
114123 if charged_count == 0 :
@@ -130,11 +139,14 @@ def calculate_chargeable() -> dict[str, int | None]:
130139 ),
131140 )
132141
142+ # Update the charging state
133143 self ._charging_state .setdefault (event_name , ChargingStateItem (0 , Decimal ()))
134144 self ._charging_state [event_name ].charge_count += charged_count
135145 self ._charging_state [event_name ].total_charged_amount += charged_count * pricing_info .price
136146
137147 # END OF CRITICAL SECTION
148+
149+ # If running on the platform, call the charge endpoint
138150 if self ._is_at_home :
139151 if self ._actor_run_id is None :
140152 raise RuntimeError ('Actor run ID not configured' )
@@ -144,6 +156,7 @@ def calculate_chargeable() -> dict[str, int | None]:
144156 else :
145157 logger .warning (f"Attempting to charge for an unknown event '{ event_name } '" )
146158
159+ # Log the charged operation (if enabled)
147160 if self ._charging_log_dataset :
148161 await self ._charging_log_dataset .push_data (
149162 {
@@ -155,6 +168,7 @@ def calculate_chargeable() -> dict[str, int | None]:
155168 }
156169 )
157170
171+ # If it is not possible to charge the full amount, log that fact
158172 if charged_count < count :
159173 subject = 'instance' if count == 1 else 'instances'
160174 logger .info (
@@ -171,6 +185,7 @@ def calculate_chargeable() -> dict[str, int | None]:
171185 )
172186
173187 def calculate_total_charged_amount (self ) -> Decimal :
188+ """Calculate the total amount of money charged for pay-per-event events."""
174189 if self ._charging_state is None :
175190 raise RuntimeError ('Charging manager is not initialized' )
176191
@@ -180,6 +195,7 @@ def calculate_total_charged_amount(self) -> Decimal:
180195 )
181196
182197 def calculate_max_event_charge_count_within_limit (self , event_name : str ) -> int | None :
198+ """Calculate how many instances of an event can be charged before we reach the configured limit."""
183199 if self ._charging_state is None :
184200 raise RuntimeError ('Charging manager is not initialized' )
185201
@@ -199,6 +215,7 @@ def calculate_max_event_charge_count_within_limit(self, event_name: str) -> int
199215 return math .floor (result ) if result .is_finite () else None
200216
201217 def get_pricing_info (self ) -> ActorPricingInfo :
218+ """Retrieve detailed infor about the effective pricing of the current Actor run."""
202219 if self ._charging_state is None :
203220 raise RuntimeError ('Charging manager is not initialized' )
204221
0 commit comments