Skip to content

Commit 3bd6bbb

Browse files
Jkuzzvdusek
andauthored
feat: Add charge method to the run client for "pay per event" (#304)
Resolves apify/apify-core#18593 by adding the charge endpoint to the run client. Issue to add docs URL #305 --------- Co-authored-by: Vlada Dusek <[email protected]>
1 parent 272bf5e commit 3bd6bbb

File tree

1 file changed

+76
-0
lines changed
  • src/apify_client/clients/resource_clients

1 file changed

+76
-0
lines changed

src/apify_client/clients/resource_clients/run.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
from __future__ import annotations
22

3+
import json
4+
import random
5+
import string
6+
import time
37
from typing import Any
48

59
from apify_shared.utils import filter_out_none_values_recursively, ignore_docs, parse_date_fields
@@ -226,6 +230,42 @@ def log(self: RunClient) -> LogClient:
226230
**self._sub_resource_init_options(resource_path='log'),
227231
)
228232

233+
def charge(
234+
self: RunClient,
235+
event_name: str,
236+
count: int | None = None,
237+
idempotency_key: str | None = None,
238+
) -> dict:
239+
"""Charge for an event of a Pay-Per-Event Actor run.
240+
241+
https://docs.apify.com/api/v2#/reference/actor-runs/charge-run/charge-run
242+
243+
Returns:
244+
dict: Status and message of the charge event.
245+
"""
246+
if not event_name:
247+
raise ValueError('event_name is required for charging an event')
248+
249+
idempotency_key = idempotency_key or (
250+
f'{self.resource_id}-{event_name}-{int(time.time() * 1000)}-{"".join(random.choices(string.ascii_letters + string.digits, k=6))}'
251+
)
252+
253+
response = self.http_client.call(
254+
url=self._url('charge'),
255+
method='POST',
256+
headers={
257+
'idempotency-key': idempotency_key,
258+
'content-type': 'application/json',
259+
},
260+
data=json.dumps(
261+
{
262+
'eventName': event_name,
263+
'count': count or 1,
264+
}
265+
),
266+
)
267+
return parse_date_fields(pluck_data(response.json()))
268+
229269

230270
class RunClientAsync(ActorJobBaseClientAsync):
231271
"""Async sub-client for manipulating a single Actor run."""
@@ -440,3 +480,39 @@ def log(self: RunClientAsync) -> LogClientAsync:
440480
return LogClientAsync(
441481
**self._sub_resource_init_options(resource_path='log'),
442482
)
483+
484+
async def charge(
485+
self: RunClientAsync,
486+
event_name: str,
487+
count: int | None = None,
488+
idempotency_key: str | None = None,
489+
) -> dict:
490+
"""Charge for an event of a Pay-Per-Event Actor run.
491+
492+
https://docs.apify.com/api/v2#/reference/actor-runs/charge-run/charge-run
493+
494+
Returns:
495+
dict: Status and message of the charge event.
496+
"""
497+
if not event_name:
498+
raise ValueError('event_name is required for charging an event')
499+
500+
idempotency_key = idempotency_key or (
501+
f'{self.resource_id}-{event_name}-{int(time.time() * 1000)}-{"".join(random.choices(string.ascii_letters + string.digits, k=6))}'
502+
)
503+
504+
response = await self.http_client.call(
505+
url=self._url('charge'),
506+
method='POST',
507+
headers={
508+
'idempotency-key': idempotency_key,
509+
'content-type': 'application/json',
510+
},
511+
data=json.dumps(
512+
{
513+
'eventName': event_name,
514+
'count': count or 1,
515+
}
516+
),
517+
)
518+
return parse_date_fields(pluck_data(response.json()))

0 commit comments

Comments
 (0)