Skip to content

Commit afcb8c7

Browse files
committed
Abstract open method is removed from storage clients
1 parent 7b5ee07 commit afcb8c7

File tree

6 files changed

+78
-27
lines changed

6 files changed

+78
-27
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies = [
3737
"apify-client>=1.12.0",
3838
"apify-shared>=1.3.0",
3939
"cachetools>=5.5.0",
40-
"crawlee@git+https://github.com/apify/crawlee-python.git@bc50990dd09eb5c2b66783b2fa62a8bc689a7737",
40+
"crawlee@git+https://github.com/apify/crawlee-python.git@new-storage-clients",
4141
"cryptography>=42.0.0",
4242
"httpx>=0.27.0",
4343
# TODO: ensure compatibility with the latest version of lazy-object-proxy

src/apify/storage_clients/_apify/_dataset_client.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ def __init__(
7171
def metadata(self) -> DatasetMetadata:
7272
return self._metadata
7373

74-
@override
7574
@classmethod
7675
async def open(
7776
cls,
@@ -80,6 +79,28 @@ async def open(
8079
name: str | None,
8180
configuration: Configuration,
8281
) -> ApifyDatasetClient:
82+
"""Open an Apify dataset client.
83+
84+
This method creates and initializes a new instance of the Apify dataset client.
85+
It handles authentication, storage lookup/creation, and metadata retrieval.
86+
87+
Args:
88+
id: The ID of an existing dataset to open. If provided, the client will connect to this specific storage.
89+
Cannot be used together with `name`.
90+
name: The name of a dataset to get or create. If a storage with this name exists, it will be opened;
91+
otherwise, a new one will be created. Cannot be used together with `id`.
92+
configuration: The configuration object containing API credentials and settings. Must include a valid
93+
`token` and `api_base_url`. May also contain a `default_dataset_id` for fallback when neither
94+
`id` nor `name` is provided.
95+
96+
Returns:
97+
An instance for the opened or created storage client.
98+
99+
Raises:
100+
ValueError: If the configuration is missing required fields (token, api_base_url), if both `id` and `name`
101+
are provided, or if neither `id` nor `name` is provided and no default storage ID is available in
102+
the configuration.
103+
"""
83104
token = getattr(configuration, 'token', None)
84105
if not token:
85106
raise ValueError(f'Apify storage client requires a valid token in Configuration (token={token}).')

src/apify/storage_clients/_apify/_key_value_store_client.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ def __init__(
6161
def metadata(self) -> KeyValueStoreMetadata:
6262
return self._metadata
6363

64-
@override
6564
@classmethod
6665
async def open(
6766
cls,
@@ -70,6 +69,28 @@ async def open(
7069
name: str | None,
7170
configuration: Configuration,
7271
) -> ApifyKeyValueStoreClient:
72+
"""Open an Apify key-value store client.
73+
74+
This method creates and initializes a new instance of the Apify key-value store client.
75+
It handles authentication, storage lookup/creation, and metadata retrieval.
76+
77+
Args:
78+
id: The ID of an existing key-value store to open. If provided, the client will connect to this specific
79+
storage. Cannot be used together with `name`.
80+
name: The name of a key-value store to get or create. If a storage with this name exists, it will be
81+
opened; otherwise, a new one will be created. Cannot be used together with `id`.
82+
configuration: The configuration object containing API credentials and settings. Must include a valid
83+
`token` and `api_base_url`. May also contain a `default_key_value_store_id` for fallback when
84+
neither `id` nor `name` is provided.
85+
86+
Returns:
87+
An instance for the opened or created storage client.
88+
89+
Raises:
90+
ValueError: If the configuration is missing required fields (token, api_base_url), if both `id` and `name`
91+
are provided, or if neither `id` nor `name` is provided and no default storage ID is available
92+
in the configuration.
93+
"""
7394
token = getattr(configuration, 'token', None)
7495
if not token:
7596
raise ValueError(f'Apify storage client requires a valid token in Configuration (token={token}).')
@@ -201,6 +222,9 @@ async def get_public_url(self, key: str) -> str:
201222
202223
Args:
203224
key: The key for which the URL should be generated.
225+
226+
Returns:
227+
A public URL that can be used to access the value of the given key in the KVS.
204228
"""
205229
if self._api_client.resource_id is None:
206230
raise ValueError('resource_id cannot be None when generating a public URL')
@@ -209,11 +233,9 @@ async def get_public_url(self, key: str) -> str:
209233
URL(self._api_client.base_url) / 'v2' / 'key-value-stores' / self._api_client.resource_id / 'records' / key
210234
)
211235

212-
key_value_store = self.metadata
213-
214-
if key_value_store and key_value_store.model_extra:
215-
url_signing_secret_key = key_value_store.model_extra.get('urlSigningSecretKey')
216-
if url_signing_secret_key:
236+
if self.metadata.model_extra is not None:
237+
url_signing_secret_key = self.metadata.model_extra.get('urlSigningSecretKey')
238+
if url_signing_secret_key is not None:
217239
public_url = public_url.with_query(signature=create_hmac_signature(url_signing_secret_key, key))
218240

219241
return str(public_url)

src/apify/storage_clients/_apify/_request_queue_client.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ def __init__(
9191
def metadata(self) -> RequestQueueMetadata:
9292
return self._metadata
9393

94-
@override
9594
@classmethod
9695
async def open(
9796
cls,
@@ -100,6 +99,29 @@ async def open(
10099
name: str | None,
101100
configuration: Configuration,
102101
) -> ApifyRequestQueueClient:
102+
"""Open an Apify request queue client.
103+
104+
This method creates and initializes a new instance of the Apify request queue client. It handles
105+
authentication, storage lookup/creation, and metadata retrieval, and sets up internal caching and queue
106+
management structures.
107+
108+
Args:
109+
id: The ID of an existing request queue to open. If provided, the client will connect to this specific
110+
storage. Cannot be used together with `name`.
111+
name: The name of a request queue to get or create. If a storage with this name exists, it will be opened;
112+
otherwise, a new one will be created. Cannot be used together with `id`.
113+
configuration: The configuration object containing API credentials and settings. Must include a valid
114+
`token` and `api_base_url`. May also contain a `default_request_queue_id` for fallback when neither
115+
`id` nor `name` is provided.
116+
117+
Returns:
118+
An instance for the opened or created storage client.
119+
120+
Raises:
121+
ValueError: If the configuration is missing required fields (token, api_base_url), if both `id` and `name`
122+
are provided, or if neither `id` nor `name` is provided and no default storage ID is available
123+
in the configuration.
124+
"""
103125
token = getattr(configuration, 'token', None)
104126
if not token:
105127
raise ValueError(f'Apify storage client requires a valid token in Configuration (token={token}).')

tests/integration/test_actor_key_value_store.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -201,30 +201,16 @@ async def test_generate_public_url_for_kvs_record(
201201
run_actor: RunActorFunction,
202202
) -> None:
203203
async def main() -> None:
204-
import os
205-
206204
from apify._crypto import create_hmac_signature
207205

208206
async with Actor:
209207
public_api_url = Actor.config.api_public_base_url
210-
211-
default_kvs_id = (
212-
os.environ.get(
213-
'ACTOR_DEFAULT_KEY_VALUE_STORE_ID',
214-
None,
215-
)
216-
or os.environ.get(
217-
'APIFY_DEFAULT_KEY_VALUE_STORE_ID',
218-
None,
219-
)
220-
or 'default'
221-
)
222-
208+
default_kvs_id = Actor.config.default_key_value_store_id
223209
record_key = 'public-record-key'
224210

225211
kvs = await Actor.open_key_value_store()
212+
assert kvs.metadata.model_extra is not None
226213

227-
assert isinstance(kvs.metadata.model_extra, dict)
228214
url_signing_secret_key = kvs.metadata.model_extra.get('urlSigningSecretKey')
229215
assert url_signing_secret_key is not None
230216

uv.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)