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 +38 -0
- apify/_platform_event_manager.py +3 -3
- apify/apify_storage_client/_key_value_store_client.py +17 -2
- {apify-2.4.0b3.dist-info → apify-2.4.0b4.dist-info}/METADATA +2 -2
- {apify-2.4.0b3.dist-info → apify-2.4.0b4.dist-info}/RECORD +7 -7
- {apify-2.4.0b3.dist-info → apify-2.4.0b4.dist-info}/WHEEL +0 -0
- {apify-2.4.0b3.dist-info → apify-2.4.0b4.dist-info}/licenses/LICENSE +0 -0
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)
|
apify/_platform_event_manager.py
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
109
|
+
return str(public_url)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apify
|
|
3
|
-
Version: 2.4.
|
|
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
|
|
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=
|
|
6
|
+
apify/_crypto.py,sha256=8BgeQC0ZhYP5KdmLxxLQAW87Gq-Z4HlREbYGXr46w0U,6607
|
|
7
7
|
apify/_models.py,sha256=-Y0rljBJWxMMCp8iDCTG4UV3bEvNZzp-kx2SYbPfeIY,7919
|
|
8
|
-
apify/_platform_event_manager.py,sha256=
|
|
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=
|
|
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.
|
|
40
|
-
apify-2.4.
|
|
41
|
-
apify-2.4.
|
|
42
|
-
apify-2.4.
|
|
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,,
|
|
File without changes
|
|
File without changes
|