scrapely-client-python 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of scrapely-client-python might be problematic. Click here for more details.

Files changed (65) hide show
  1. scrapely_client/__init__.py +30 -0
  2. scrapely_client/_charging.py +186 -0
  3. scrapely_client/_client_registry.py +136 -0
  4. scrapely_client/_consts.py +96 -0
  5. scrapely_client/_docs.py +37 -0
  6. scrapely_client/_literals.py +539 -0
  7. scrapely_client/_logging.py +180 -0
  8. scrapely_client/_models.py +4172 -0
  9. scrapely_client/_pagination.py +220 -0
  10. scrapely_client/_resource_clients/__init__.py +84 -0
  11. scrapely_client/_resource_clients/_resource_client.py +567 -0
  12. scrapely_client/_resource_clients/actor.py +1042 -0
  13. scrapely_client/_resource_clients/actor_collection.py +377 -0
  14. scrapely_client/_resource_clients/actor_env_var.py +154 -0
  15. scrapely_client/_resource_clients/actor_env_var_collection.py +165 -0
  16. scrapely_client/_resource_clients/actor_version.py +254 -0
  17. scrapely_client/_resource_clients/actor_version_collection.py +232 -0
  18. scrapely_client/_resource_clients/build.py +244 -0
  19. scrapely_client/_resource_clients/build_collection.py +164 -0
  20. scrapely_client/_resource_clients/dataset.py +1151 -0
  21. scrapely_client/_resource_clients/dataset_collection.py +244 -0
  22. scrapely_client/_resource_clients/key_value_store.py +906 -0
  23. scrapely_client/_resource_clients/key_value_store_collection.py +243 -0
  24. scrapely_client/_resource_clients/log.py +225 -0
  25. scrapely_client/_resource_clients/request_queue.py +1167 -0
  26. scrapely_client/_resource_clients/request_queue_collection.py +240 -0
  27. scrapely_client/_resource_clients/run.py +875 -0
  28. scrapely_client/_resource_clients/run_collection.py +226 -0
  29. scrapely_client/_resource_clients/schedule.py +243 -0
  30. scrapely_client/_resource_clients/schedule_collection.py +260 -0
  31. scrapely_client/_resource_clients/store_collection.py +242 -0
  32. scrapely_client/_resource_clients/task.py +793 -0
  33. scrapely_client/_resource_clients/task_collection.py +322 -0
  34. scrapely_client/_resource_clients/user.py +262 -0
  35. scrapely_client/_resource_clients/webhook.py +292 -0
  36. scrapely_client/_resource_clients/webhook_collection.py +281 -0
  37. scrapely_client/_resource_clients/webhook_dispatch.py +84 -0
  38. scrapely_client/_resource_clients/webhook_dispatch_collection.py +158 -0
  39. scrapely_client/_scrapely_client.py +837 -0
  40. scrapely_client/_statistics.py +29 -0
  41. scrapely_client/_status_message_watcher.py +197 -0
  42. scrapely_client/_streamed_log.py +250 -0
  43. scrapely_client/_typeddicts.py +408 -0
  44. scrapely_client/_utils/__init__.py +0 -0
  45. scrapely_client/_utils/crypto.py +87 -0
  46. scrapely_client/_utils/encoding.py +133 -0
  47. scrapely_client/_utils/errors.py +33 -0
  48. scrapely_client/_utils/http.py +137 -0
  49. scrapely_client/_utils/time.py +32 -0
  50. scrapely_client/_utils/try_import.py +61 -0
  51. scrapely_client/errors.py +190 -0
  52. scrapely_client/http_clients/__init__.py +10 -0
  53. scrapely_client/http_clients/_base.py +430 -0
  54. scrapely_client/http_clients/_impit.py +598 -0
  55. scrapely_client/http_compressors/__init__.py +18 -0
  56. scrapely_client/http_compressors/_base.py +25 -0
  57. scrapely_client/http_compressors/_brotli.py +38 -0
  58. scrapely_client/http_compressors/_gzip.py +38 -0
  59. scrapely_client/http_compressors/_resolve.py +38 -0
  60. scrapely_client/py.typed +0 -0
  61. scrapely_client/types.py +52 -0
  62. scrapely_client_python-1.0.0.dist-info/METADATA +244 -0
  63. scrapely_client_python-1.0.0.dist-info/RECORD +65 -0
  64. scrapely_client_python-1.0.0.dist-info/WHEEL +4 -0
  65. scrapely_client_python-1.0.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,243 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from scrapely_client._docs import docs_group
6
+ from scrapely_client._models import (
7
+ KeyValueStore,
8
+ KeyValueStoreResponse,
9
+ ListOfKeyValueStores,
10
+ ListOfKeyValueStoresResponse,
11
+ )
12
+ from scrapely_client._pagination import get_items_iterator, get_items_iterator_async
13
+ from scrapely_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync
14
+
15
+ if TYPE_CHECKING:
16
+ from collections.abc import AsyncIterator, Iterator
17
+
18
+ from scrapely_client._literals import StorageOwnership
19
+ from scrapely_client.types import Timeout
20
+
21
+
22
+ @docs_group('Resource clients')
23
+ class KeyValueStoreCollectionClient(ResourceClient):
24
+ """Sub-client for the key-value store collection.
25
+
26
+ Provides methods to manage the key-value store collection, e.g. list or create key-value stores. Obtain an instance
27
+ via an appropriate method on the `ApifyClient` class.
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ *,
33
+ resource_path: str = 'key-value-stores',
34
+ **kwargs: Any,
35
+ ) -> None:
36
+ super().__init__(
37
+ resource_path=resource_path,
38
+ **kwargs,
39
+ )
40
+
41
+ def list(
42
+ self,
43
+ *,
44
+ unnamed: bool | None = None,
45
+ limit: int | None = None,
46
+ offset: int | None = None,
47
+ desc: bool | None = None,
48
+ ownership: StorageOwnership | None = None,
49
+ timeout: Timeout = 'medium',
50
+ ) -> ListOfKeyValueStores:
51
+ """List the available key-value stores.
52
+
53
+
54
+ Args:
55
+ unnamed: Whether to include unnamed key-value stores in the list.
56
+ limit: How many key-value stores to retrieve.
57
+ offset: What key-value store to include as first when retrieving the list.
58
+ desc: Whether to sort the key-value stores in descending order based on their modification date.
59
+ ownership: Filter by ownership. `'ownedByMe'` returns only user's own key-value stores,
60
+ `'sharedWithMe'` returns only key-value stores shared with the user.
61
+ timeout: Timeout for the API HTTP request.
62
+
63
+ Returns:
64
+ The list of available key-value stores matching the specified filters.
65
+ """
66
+ result = self._list(
67
+ timeout=timeout,
68
+ unnamed=unnamed,
69
+ limit=limit,
70
+ offset=offset,
71
+ desc=desc,
72
+ ownership=ownership,
73
+ )
74
+ return ListOfKeyValueStoresResponse.model_validate(result).data
75
+
76
+ def iterate(
77
+ self,
78
+ *,
79
+ unnamed: bool | None = None,
80
+ limit: int | None = None,
81
+ offset: int | None = None,
82
+ desc: bool | None = None,
83
+ ownership: StorageOwnership | None = None,
84
+ timeout: Timeout = 'medium',
85
+ ) -> Iterator[KeyValueStore]:
86
+ """Iterate over the available key-value stores.
87
+
88
+ Simple `list` does only one API call, possibly not listing all items matching the criteria. This method
89
+ returns an iterator that is capable of making multiple API calls to retrieve all items matching the criteria.
90
+
91
+
92
+ Args:
93
+ unnamed: Whether to include unnamed key-value stores in the list.
94
+ limit: How many key-value stores to retrieve.
95
+ offset: What key-value store to include as first when retrieving the list.
96
+ desc: Whether to sort the key-value stores in descending order based on their modification date.
97
+ ownership: Filter by ownership. 'ownedByMe' returns only user's own key-value stores,
98
+ 'sharedWithMe' returns only key-value stores shared with the user.
99
+ timeout: Timeout for the API HTTP request.
100
+
101
+ Yields:
102
+ The available key-value stores matching the specified filters.
103
+ """
104
+
105
+ def _callback(*, limit: int | None = None, offset: int | None = None) -> ListOfKeyValueStores:
106
+ return self.list(
107
+ unnamed=unnamed, limit=limit, offset=offset, desc=desc, ownership=ownership, timeout=timeout
108
+ )
109
+
110
+ return get_items_iterator(_callback, limit=limit, offset=offset)
111
+
112
+ def get_or_create(
113
+ self,
114
+ *,
115
+ name: str | None = None,
116
+ schema: dict | None = None,
117
+ timeout: Timeout = 'short',
118
+ ) -> KeyValueStore:
119
+ """Retrieve a named key-value store, or create a new one when it doesn't exist.
120
+
121
+
122
+ Args:
123
+ name: The name of the key-value store to retrieve or create.
124
+ schema: The schema of the key-value store.
125
+ timeout: Timeout for the API HTTP request.
126
+
127
+ Returns:
128
+ The retrieved or newly-created key-value store.
129
+ """
130
+ result = self._get_or_create(timeout=timeout, name=name, resource_fields={'schema': schema})
131
+ return KeyValueStoreResponse.model_validate(result).data
132
+
133
+
134
+ @docs_group('Resource clients')
135
+ class KeyValueStoreCollectionClientAsync(ResourceClientAsync):
136
+ """Sub-client for the key-value store collection.
137
+
138
+ Provides methods to manage the key-value store collection, e.g. list or create key-value stores. Obtain an instance
139
+ via an appropriate method on the `ApifyClientAsync` class.
140
+ """
141
+
142
+ def __init__(
143
+ self,
144
+ *,
145
+ resource_path: str = 'key-value-stores',
146
+ **kwargs: Any,
147
+ ) -> None:
148
+ super().__init__(
149
+ resource_path=resource_path,
150
+ **kwargs,
151
+ )
152
+
153
+ async def list(
154
+ self,
155
+ *,
156
+ unnamed: bool | None = None,
157
+ limit: int | None = None,
158
+ offset: int | None = None,
159
+ desc: bool | None = None,
160
+ ownership: StorageOwnership | None = None,
161
+ timeout: Timeout = 'medium',
162
+ ) -> ListOfKeyValueStores:
163
+ """List the available key-value stores.
164
+
165
+
166
+ Args:
167
+ unnamed: Whether to include unnamed key-value stores in the list.
168
+ limit: How many key-value stores to retrieve.
169
+ offset: What key-value store to include as first when retrieving the list.
170
+ desc: Whether to sort the key-value stores in descending order based on their modification date.
171
+ ownership: Filter by ownership. `'ownedByMe'` returns only user's own key-value stores,
172
+ `'sharedWithMe'` returns only key-value stores shared with the user.
173
+ timeout: Timeout for the API HTTP request.
174
+
175
+ Returns:
176
+ The list of available key-value stores matching the specified filters.
177
+ """
178
+ result = await self._list(
179
+ timeout=timeout,
180
+ unnamed=unnamed,
181
+ limit=limit,
182
+ offset=offset,
183
+ desc=desc,
184
+ ownership=ownership,
185
+ )
186
+ return ListOfKeyValueStoresResponse.model_validate(result).data
187
+
188
+ def iterate(
189
+ self,
190
+ *,
191
+ unnamed: bool | None = None,
192
+ limit: int | None = None,
193
+ offset: int | None = None,
194
+ desc: bool | None = None,
195
+ ownership: StorageOwnership | None = None,
196
+ timeout: Timeout = 'medium',
197
+ ) -> AsyncIterator[KeyValueStore]:
198
+ """Iterate over the available key-value stores.
199
+
200
+ Simple `list` does only one API call, possibly not listing all items matching the criteria. This method
201
+ returns an iterator that is capable of making multiple API calls to retrieve all items matching the criteria.
202
+
203
+
204
+ Args:
205
+ unnamed: Whether to include unnamed key-value stores in the list.
206
+ limit: How many key-value stores to retrieve.
207
+ offset: What key-value store to include as first when retrieving the list.
208
+ desc: Whether to sort the key-value stores in descending order based on their modification date.
209
+ ownership: Filter by ownership. 'ownedByMe' returns only user's own key-value stores,
210
+ 'sharedWithMe' returns only key-value stores shared with the user.
211
+ timeout: Timeout for the API HTTP request.
212
+
213
+ Yields:
214
+ The available key-value stores matching the specified filters.
215
+ """
216
+
217
+ async def _callback(*, limit: int | None = None, offset: int | None = None) -> ListOfKeyValueStores:
218
+ return await self.list(
219
+ unnamed=unnamed, limit=limit, offset=offset, desc=desc, ownership=ownership, timeout=timeout
220
+ )
221
+
222
+ return get_items_iterator_async(_callback, limit=limit, offset=offset)
223
+
224
+ async def get_or_create(
225
+ self,
226
+ *,
227
+ name: str | None = None,
228
+ schema: dict | None = None,
229
+ timeout: Timeout = 'short',
230
+ ) -> KeyValueStore:
231
+ """Retrieve a named key-value store, or create a new one when it doesn't exist.
232
+
233
+
234
+ Args:
235
+ name: The name of the key-value store to retrieve or create.
236
+ schema: The schema of the key-value store.
237
+ timeout: Timeout for the API HTTP request.
238
+
239
+ Returns:
240
+ The retrieved or newly-created key-value store.
241
+ """
242
+ result = await self._get_or_create(timeout=timeout, name=name, resource_fields={'schema': schema})
243
+ return KeyValueStoreResponse.model_validate(result).data
@@ -0,0 +1,225 @@
1
+ from __future__ import annotations
2
+
3
+ from contextlib import asynccontextmanager, contextmanager
4
+ from typing import TYPE_CHECKING, Any
5
+
6
+ from scrapely_client._docs import docs_group
7
+ from scrapely_client._resource_clients._resource_client import ResourceClient, ResourceClientAsync
8
+ from scrapely_client._utils.errors import catch_not_found_for_resource_or_throw
9
+ from scrapely_client.errors import ApifyApiError
10
+
11
+ if TYPE_CHECKING:
12
+ from collections.abc import AsyncIterator, Iterator
13
+
14
+ from scrapely_client.http_clients import HttpResponse
15
+ from scrapely_client.types import Timeout
16
+
17
+
18
+ @docs_group('Resource clients')
19
+ class LogClient(ResourceClient):
20
+ """Sub-client for managing a specific log.
21
+
22
+ Provides methods to manage logs, e.g. get or stream them. Obtain an instance via an appropriate method on the
23
+ `ApifyClient` class.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ *,
29
+ resource_path: str = 'logs',
30
+ **kwargs: Any,
31
+ ) -> None:
32
+ super().__init__(
33
+ resource_path=resource_path,
34
+ **kwargs,
35
+ )
36
+
37
+ def get(self, *, raw: bool = False, timeout: Timeout = 'long') -> str | None:
38
+ """Retrieve the log as text.
39
+
40
+
41
+ 404s collapse to `None` only when this client targets a specific log by ID (e.g. `client.log(run_id).get()`).
42
+ For chained clients without a `resource_id` (e.g. `run.log().get()`), a 404 is ambiguous and propagates.
43
+
44
+ Args:
45
+ raw: If true, the log will include formatting. For example, coloring character sequences.
46
+ timeout: Timeout for the API HTTP request.
47
+
48
+ Returns:
49
+ The retrieved log, or None, if it does not exist.
50
+ """
51
+ try:
52
+ response = self._http_client.call(
53
+ url=self._build_url(),
54
+ method='GET',
55
+ params=self._build_params(raw=raw),
56
+ timeout=timeout,
57
+ )
58
+
59
+ return response.text # noqa: TRY300
60
+
61
+ except ApifyApiError as exc:
62
+ catch_not_found_for_resource_or_throw(exc, self._resource_id)
63
+
64
+ return None
65
+
66
+ def get_as_bytes(self, *, raw: bool = False, timeout: Timeout = 'long') -> bytes | None:
67
+ """Retrieve the log as raw bytes.
68
+
69
+
70
+ Args:
71
+ raw: If true, the log will include formatting. For example, coloring character sequences.
72
+ timeout: Timeout for the API HTTP request.
73
+
74
+ Returns:
75
+ The retrieved log as raw bytes, or None, if it does not exist.
76
+ """
77
+ try:
78
+ response = self._http_client.call(
79
+ url=self._build_url(),
80
+ method='GET',
81
+ params=self._build_params(raw=raw),
82
+ timeout=timeout,
83
+ )
84
+
85
+ return response.content # noqa: TRY300
86
+
87
+ except ApifyApiError as exc:
88
+ catch_not_found_for_resource_or_throw(exc, self._resource_id)
89
+
90
+ return None
91
+
92
+ @contextmanager
93
+ def stream(self, *, raw: bool = False, timeout: Timeout = 'long') -> Iterator[HttpResponse | None]:
94
+ """Retrieve the log as a stream.
95
+
96
+
97
+ Args:
98
+ raw: If true, the log will include formatting. For example, coloring character sequences.
99
+ timeout: Timeout for the API HTTP request.
100
+
101
+ Returns:
102
+ The retrieved log as a context-managed streaming `Response`, or None, if it does not exist.
103
+ """
104
+ response = None
105
+ try:
106
+ response = self._http_client.call(
107
+ url=self._build_url(),
108
+ method='GET',
109
+ params=self._build_params(stream=True, raw=raw),
110
+ stream=True,
111
+ timeout=timeout,
112
+ )
113
+
114
+ yield response
115
+ except ApifyApiError as exc:
116
+ catch_not_found_for_resource_or_throw(exc, self._resource_id)
117
+ yield None
118
+ finally:
119
+ if response:
120
+ response.close()
121
+
122
+
123
+ @docs_group('Resource clients')
124
+ class LogClientAsync(ResourceClientAsync):
125
+ """Sub-client for managing a specific log.
126
+
127
+ Provides methods to manage logs, e.g. get or stream them. Obtain an instance via an appropriate method on the
128
+ `ApifyClientAsync` class.
129
+ """
130
+
131
+ def __init__(
132
+ self,
133
+ *,
134
+ resource_path: str = 'logs',
135
+ **kwargs: Any,
136
+ ) -> None:
137
+ super().__init__(
138
+ resource_path=resource_path,
139
+ **kwargs,
140
+ )
141
+
142
+ async def get(self, *, raw: bool = False, timeout: Timeout = 'long') -> str | None:
143
+ """Retrieve the log as text.
144
+
145
+
146
+ 404s collapse to `None` only when this client targets a specific log by ID (e.g. `client.log(run_id).get()`).
147
+ For chained clients without a `resource_id` (e.g. `run.log().get()`), a 404 is ambiguous and propagates.
148
+
149
+ Args:
150
+ raw: If true, the log will include formatting. For example, coloring character sequences.
151
+ timeout: Timeout for the API HTTP request.
152
+
153
+ Returns:
154
+ The retrieved log, or None, if it does not exist.
155
+ """
156
+ try:
157
+ response = await self._http_client.call(
158
+ url=self._build_url(),
159
+ method='GET',
160
+ params=self._build_params(raw=raw),
161
+ timeout=timeout,
162
+ )
163
+
164
+ return response.text # noqa: TRY300
165
+
166
+ except ApifyApiError as exc:
167
+ catch_not_found_for_resource_or_throw(exc, self._resource_id)
168
+
169
+ return None
170
+
171
+ async def get_as_bytes(self, *, raw: bool = False, timeout: Timeout = 'long') -> bytes | None:
172
+ """Retrieve the log as raw bytes.
173
+
174
+
175
+ Args:
176
+ raw: If true, the log will include formatting. For example, coloring character sequences.
177
+ timeout: Timeout for the API HTTP request.
178
+
179
+ Returns:
180
+ The retrieved log as raw bytes, or None, if it does not exist.
181
+ """
182
+ try:
183
+ response = await self._http_client.call(
184
+ url=self._build_url(),
185
+ method='GET',
186
+ params=self._build_params(raw=raw),
187
+ timeout=timeout,
188
+ )
189
+
190
+ return response.content # noqa: TRY300
191
+
192
+ except ApifyApiError as exc:
193
+ catch_not_found_for_resource_or_throw(exc, self._resource_id)
194
+
195
+ return None
196
+
197
+ @asynccontextmanager
198
+ async def stream(self, *, raw: bool = False, timeout: Timeout = 'long') -> AsyncIterator[HttpResponse | None]:
199
+ """Retrieve the log as a stream.
200
+
201
+
202
+ Args:
203
+ raw: If true, the log will include formatting. For example, coloring character sequences.
204
+ timeout: Timeout for the API HTTP request.
205
+
206
+ Returns:
207
+ The retrieved log as a context-managed streaming `Response`, or None, if it does not exist.
208
+ """
209
+ response = None
210
+ try:
211
+ response = await self._http_client.call(
212
+ url=self._build_url(),
213
+ method='GET',
214
+ params=self._build_params(stream=True, raw=raw),
215
+ stream=True,
216
+ timeout=timeout,
217
+ )
218
+
219
+ yield response
220
+ except ApifyApiError as exc:
221
+ catch_not_found_for_resource_or_throw(exc, self._resource_id)
222
+ yield None
223
+ finally:
224
+ if response:
225
+ await response.aclose()