11from __future__ import annotations
22
3- from typing import Any
3+ import json
44import time
5+ from typing import Any
56
67from apify_shared .utils import filter_out_none_values_recursively , ignore_docs , parse_date_fields
78
1213from apify_client .clients .resource_clients .log import LogClient , LogClientAsync
1314from apify_client .clients .resource_clients .request_queue import RequestQueueClient , RequestQueueClientAsync
1415
15- RUN_CHARGE_IDEMPOTENCY_HEADER = 'idempotency-key'
1616
1717class RunClient (ActorJobBaseClient ):
1818 """Sub-client for manipulating a single Actor run."""
@@ -228,6 +228,35 @@ def log(self: RunClient) -> LogClient:
228228 ** self ._sub_resource_init_options (resource_path = 'log' ),
229229 )
230230
231+ def charge (
232+ self : RunClient ,
233+ event_name : str ,
234+ count : int | None = None ,
235+ idempotency_key : str | None = None ,
236+ ) -> dict :
237+ """Charge for an event of a Pay-Per-Event Actor run.
238+
239+ TODO: docs url
240+
241+ Returns:
242+ dict: Status and message of the charge event.
243+ """
244+ if not event_name :
245+ raise ValueError ('eventName is required for charging an event' )
246+
247+ return self .http_client .call (
248+ url = self ._url ('charge' ),
249+ method = 'POST' ,
250+ headers = {
251+ 'idempotency-key' : idempotency_key or f'{ self .resource_id } -{ event_name } -{ int (time .time () * 1000 )} ' ,
252+ 'content-type' : 'application/json' ,
253+ },
254+ data = json .dumps ({
255+ 'eventName' : event_name ,
256+ 'count' : count or 1 ,
257+ })
258+ )
259+
231260
232261class RunClientAsync (ActorJobBaseClientAsync ):
233262 """Async sub-client for manipulating a single Actor run."""
@@ -445,9 +474,9 @@ def log(self: RunClientAsync) -> LogClientAsync:
445474
446475 async def charge (
447476 self : RunClient ,
448- eventName : str ,
477+ event_name : str ,
449478 count : int | None = None ,
450- idempotencyKey : str | None = None ,
479+ idempotency_key : str | None = None ,
451480 ) -> dict :
452481 """Charge for an event of a Pay-Per-Event Actor run.
453482
@@ -456,23 +485,18 @@ async def charge(
456485 Returns:
457486 dict: Status and message of the charge event.
458487 """
488+ if not event_name :
489+ raise ValueError ('eventName is required for charging an event' )
459490
460- if not eventName :
461- raise ValueError ("eventName is required for charging an event" )
462-
463- idempotencyKey = idempotencyKey or "{runId}-{eventName}-{timestamp}" .format (
464- runId = self .resource_id ,
465- eventName = eventName ,
466- timestamp = int (time .time () * 1000 ),
467- )
468-
469- response = await self .http_client .call (
491+ return await self .http_client .call (
470492 url = self ._url ('charge' ),
471493 method = 'POST' ,
472- headers = {RUN_CHARGE_IDEMPOTENCY_HEADER : idempotencyKey },
473- data = {
474- 'eventName' : eventName ,
494+ headers = {
495+ 'idempotency-key' : idempotency_key or f'{ self .resource_id } -{ event_name } -{ int (time .time () * 1000 )} ' ,
496+ 'content-type' : 'application/json' ,
497+ },
498+ data = json .dumps ({
499+ 'eventName' : event_name ,
475500 'count' : count or 1 ,
476- }
501+ })
477502 )
478- return response
0 commit comments