apify 2.4.0b3__py3-none-any.whl → 2.4.0b4__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 apify might be problematic. Click here for more details.

apify/_crypto.py CHANGED
@@ -1,6 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import base64
4
+ import hashlib
5
+ import hmac
6
+ import string
4
7
  from typing import Any
5
8
 
6
9
  from cryptography.exceptions import InvalidTag as InvalidTagException
@@ -153,3 +156,38 @@ def decrypt_input_secrets(private_key: rsa.RSAPrivateKey, input_data: Any) -> An
153
156
  )
154
157
 
155
158
  return input_data
159
+
160
+
161
+ CHARSET = string.digits + string.ascii_letters
162
+
163
+
164
+ def encode_base62(num: int) -> str:
165
+ """Encode the given number to base62."""
166
+ if num == 0:
167
+ return CHARSET[0]
168
+
169
+ res = ''
170
+ while num > 0:
171
+ num, remainder = divmod(num, 62)
172
+ res = CHARSET[remainder] + res
173
+ return res
174
+
175
+
176
+ @ignore_docs
177
+ def create_hmac_signature(secret_key: str, message: str) -> str:
178
+ """Generate an HMAC signature and encodes it using Base62. Base62 encoding reduces the signature length.
179
+
180
+ HMAC signature is truncated to 30 characters to make it shorter.
181
+
182
+ Args:
183
+ secret_key: Secret key used for signing signatures.
184
+ message: Message to be signed.
185
+
186
+ Returns:
187
+ Base62 encoded signature.
188
+ """
189
+ signature = hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256).hexdigest()[:30]
190
+
191
+ decimal_signature = int(signature, 16)
192
+
193
+ return encode_base62(decimal_signature)
@@ -4,7 +4,7 @@ import asyncio
4
4
  from datetime import datetime
5
5
  from typing import TYPE_CHECKING, Annotated, Any, Literal, Union
6
6
 
7
- import websockets.client
7
+ import websockets.asyncio.client
8
8
  from pydantic import BaseModel, Discriminator, Field, TypeAdapter
9
9
  from typing_extensions import Self, Unpack, override
10
10
 
@@ -143,7 +143,7 @@ class PlatformEventManager(EventManager):
143
143
  but instead use it via the `Actor.on()` and `Actor.off()` methods.
144
144
  """
145
145
 
146
- _platform_events_websocket: websockets.client.WebSocketClientProtocol | None = None
146
+ _platform_events_websocket: websockets.asyncio.client.ClientConnection | None = None
147
147
  _process_platform_messages_task: asyncio.Task | None = None
148
148
  _send_system_info_interval_task: asyncio.Task | None = None
149
149
  _connected_to_platform_websocket: asyncio.Future = asyncio.Future()
@@ -196,7 +196,7 @@ class PlatformEventManager(EventManager):
196
196
 
197
197
  async def _process_platform_messages(self, ws_url: str) -> None:
198
198
  try:
199
- async with websockets.client.connect(ws_url) as websocket:
199
+ async with websockets.asyncio.client.connect(ws_url) as websocket:
200
200
  self._platform_events_websocket = websocket
201
201
  self._connected_to_platform_websocket.set_result(True)
202
202
 
@@ -4,10 +4,13 @@ from contextlib import asynccontextmanager
4
4
  from typing import TYPE_CHECKING, Any
5
5
 
6
6
  from typing_extensions import override
7
+ from yarl import URL
7
8
 
8
9
  from crawlee.storage_clients._base import KeyValueStoreClient as BaseKeyValueStoreClient
9
10
  from crawlee.storage_clients.models import KeyValueStoreListKeysPage, KeyValueStoreMetadata, KeyValueStoreRecord
10
11
 
12
+ from apify._crypto import create_hmac_signature
13
+
11
14
  if TYPE_CHECKING:
12
15
  from collections.abc import AsyncIterator
13
16
  from contextlib import AbstractAsyncContextManager
@@ -89,6 +92,18 @@ class KeyValueStoreClient(BaseKeyValueStoreClient):
89
92
  Args:
90
93
  key: The key for which the URL should be generated.
91
94
  """
92
- public_api_url = self._api_public_base_url
95
+ if self._client.resource_id is None:
96
+ raise ValueError('resource_id cannot be None when generating a public URL')
97
+
98
+ public_url = (
99
+ URL(self._api_public_base_url) / 'v2' / 'key-value-stores' / self._client.resource_id / 'records' / key
100
+ )
101
+
102
+ key_value_store = await self.get()
103
+
104
+ if key_value_store is not None and isinstance(key_value_store.model_extra, dict):
105
+ url_signing_secret_key = key_value_store.model_extra.get('urlSigningSecretKey')
106
+ if url_signing_secret_key:
107
+ public_url = public_url.with_query(signature=create_hmac_signature(url_signing_secret_key, key))
93
108
 
94
- return f'{public_api_url}/v2/key-value-stores/{self._client.resource_id}/records/{key}'
109
+ return str(public_url)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: apify
3
- Version: 2.4.0b3
3
+ Version: 2.4.0b4
4
4
  Summary: Apify SDK for Python
5
5
  Project-URL: Homepage, https://docs.apify.com/sdk/python/
6
6
  Project-URL: Apify homepage, https://apify.com
@@ -231,7 +231,7 @@ Requires-Dist: httpx>=0.27.0
231
231
  Requires-Dist: lazy-object-proxy>=1.10.0
232
232
  Requires-Dist: more-itertools>=10.2.0
233
233
  Requires-Dist: typing-extensions>=4.1.0
234
- Requires-Dist: websockets<14.0.0,>=10.0
234
+ Requires-Dist: websockets>=14.0
235
235
  Provides-Extra: scrapy
236
236
  Requires-Dist: scrapy>=2.11.0; extra == 'scrapy'
237
237
  Description-Content-Type: text/markdown
@@ -3,9 +3,9 @@ apify/_actor.py,sha256=PQqFDpAqSbh_aP3EjD8yLGYOmLZMo1qLzqrbVT2KjWE,49697
3
3
  apify/_charging.py,sha256=m7hJIQde4M7vS4g_4hsNRP5xHNXjYQ8MyqOEGeNb7VY,12267
4
4
  apify/_configuration.py,sha256=yidcWHsu-IJ2mmLmXStKq_HHcdfQxZq7koYjlZfRnQ8,11128
5
5
  apify/_consts.py,sha256=_Xq4hOfOA1iZ3n1P967YWdyncKivpbX6RTlp_qanUoE,330
6
- apify/_crypto.py,sha256=e0_aM3l9_5Osk-jszYOOjrAKK60OggSHbiw5c30QnsU,5638
6
+ apify/_crypto.py,sha256=8BgeQC0ZhYP5KdmLxxLQAW87Gq-Z4HlREbYGXr46w0U,6607
7
7
  apify/_models.py,sha256=-Y0rljBJWxMMCp8iDCTG4UV3bEvNZzp-kx2SYbPfeIY,7919
8
- apify/_platform_event_manager.py,sha256=44xyV0Lpzf4h4VZ0rkyYg_nhbQkEONNor8_Z9gIKO40,7899
8
+ apify/_platform_event_manager.py,sha256=k1e5ruSJdcMKr6j-_XIF-gfhrgyMzdSenYW0QoJROu8,7916
9
9
  apify/_proxy_configuration.py,sha256=c-O6_PZ9pUD-i4J0RFEKTtfyJPP2rTRJJA1TH8NVsV8,13189
10
10
  apify/_utils.py,sha256=92byxeXTpDFwhBq7ZS-obeXKtKWvVzCZMV0Drg3EjhQ,1634
11
11
  apify/log.py,sha256=j-E4t-WeA93bc1NCQRG8sTntehQCiiN8ia-MdQe3_Ts,1291
@@ -14,7 +14,7 @@ apify/apify_storage_client/__init__.py,sha256=-UbR68bFsDR6ln8OFs4t50eqcnY36hujO-
14
14
  apify/apify_storage_client/_apify_storage_client.py,sha256=qeWYsEQGeyyhJzS9TZTQFNqdSl8JzHz_4_HDKGY4I_Y,2736
15
15
  apify/apify_storage_client/_dataset_client.py,sha256=9RxxhrJMic5QRJn2Vl4J-FnSlEigIpYW5Z_2B1dcRzM,5597
16
16
  apify/apify_storage_client/_dataset_collection_client.py,sha256=gf5skMTkfpGhEscRy5bgo13vznxGZrSd7w9Ivh3Usyc,1516
17
- apify/apify_storage_client/_key_value_store_client.py,sha256=vreaFLAhyzuHwnvRfNVEy4N-VqEHa7ybSiS82TIgqbk,3386
17
+ apify/apify_storage_client/_key_value_store_client.py,sha256=OCFUAW0o-8KQvUpL8zmlZrpU3yRmDKdsO2529H2v40I,4002
18
18
  apify/apify_storage_client/_key_value_store_collection_client.py,sha256=zjsbRW4zjme6dIzxxlHyCW3voBA5489MUhdjl5YMaro,1596
19
19
  apify/apify_storage_client/_request_queue_client.py,sha256=cNMhXz85s1ZtjLpVqkduYl1y6o9QyNdcIGoy6ccD-h0,5178
20
20
  apify/apify_storage_client/_request_queue_collection_client.py,sha256=MTLM2cG0txAe3cSjkGbXyq2Ek0R7wlsMbGGULmQGD3I,1603
@@ -36,7 +36,7 @@ apify/scrapy/pipelines/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
36
36
  apify/storages/__init__.py,sha256=FW-z6ubuPnHGM-Wp15T8mR5q6lnpDGrCW-IkgZd5L30,177
37
37
  apify/storages/_request_list.py,sha256=7WpcdWvT3QxEBthynBpTVCSNDLXq6UbpQQmfUVyJ1jE,5849
38
38
  apify/storages/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
39
- apify-2.4.0b3.dist-info/METADATA,sha256=gir7JYFqfowdPkukMySYVZBX2jU3FY_pYh3_ox6CvRQ,21566
40
- apify-2.4.0b3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
- apify-2.4.0b3.dist-info/licenses/LICENSE,sha256=AsFjHssKjj4LGd2ZCqXn6FBzMqcWdjQre1byPPSypVw,11355
42
- apify-2.4.0b3.dist-info/RECORD,,
39
+ apify-2.4.0b4.dist-info/METADATA,sha256=euAPCSZDsD14y2c1WnbKu9qMyXYHLQkeHZJ2Pzpnxvk,21558
40
+ apify-2.4.0b4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ apify-2.4.0b4.dist-info/licenses/LICENSE,sha256=AsFjHssKjj4LGd2ZCqXn6FBzMqcWdjQre1byPPSypVw,11355
42
+ apify-2.4.0b4.dist-info/RECORD,,