1212from crawlee .storage_clients .models import KeyValueStoreRecord , KeyValueStoreRecordMetadata
1313
1414from ._models import ApifyKeyValueStoreMetadata , KeyValueStoreListKeysPage
15+ from ._utils import resolve_alias_to_id , store_alias_mapping
1516from apify ._crypto import create_hmac_signature
1617
1718if TYPE_CHECKING :
@@ -58,6 +59,7 @@ async def open(
5859 * ,
5960 id : str | None ,
6061 name : str | None ,
62+ alias : str | None ,
6163 configuration : Configuration ,
6264 ) -> ApifyKeyValueStoreClient :
6365 """Open an Apify key-value store client.
@@ -67,21 +69,27 @@ async def open(
6769
6870 Args:
6971 id: The ID of an existing key-value store to open. If provided, the client will connect to this specific
70- storage. Cannot be used together with `name`.
72+ storage. Cannot be used together with `name` or `alias` .
7173 name: The name of a key-value store to get or create. If a storage with this name exists, it will be
72- opened; otherwise, a new one will be created. Cannot be used together with `id`.
74+ opened; otherwise, a new one will be created. Cannot be used together with `id` or `alias`.
75+ alias: The alias of a key-value store for unnamed storages. If a storage with this alias exists, it will
76+ be opened; otherwise, a new one will be created and the alias will be saved. Cannot be used together
77+ with `id` or `name`.
7378 configuration: The configuration object containing API credentials and settings. Must include a valid
7479 `token` and `api_base_url`. May also contain a `default_key_value_store_id` for fallback when
75- neither `id` nor `name ` is provided.
80+ neither `id`, `name`, nor `alias ` is provided.
7681
7782 Returns:
7883 An instance for the opened or created storage client.
7984
8085 Raises:
81- ValueError: If the configuration is missing required fields (token, api_base_url), if both `id` and `name`
82- are provided, or if neither `id` nor `name ` is provided and no default storage ID is available
86+ ValueError: If the configuration is missing required fields (token, api_base_url), if more than one of
87+ `id`, `name`, or `alias ` is provided, or if none are provided and no default storage ID is available
8388 in the configuration.
8489 """
90+ if sum (1 for param in [id , name , alias ] if param is not None ) > 1 :
91+ raise ValueError ('Only one of "id", "name", or "alias" can be specified, not multiple.' )
92+
8593 token = configuration .token
8694 if not token :
8795 raise ValueError (f'Apify storage client requires a valid token in Configuration (token={ token } ).' )
@@ -107,27 +115,32 @@ async def open(
107115 )
108116 apify_kvss_client = apify_client_async .key_value_stores ()
109117
110- # If both id and name are provided, raise an error.
111- if id and name :
112- raise ValueError ('Only one of "id" or "name" can be specified, not both.' )
113-
114- # If id is provided, get the storage by ID.
115- if id and name is None :
116- apify_kvs_client = apify_client_async .key_value_store (key_value_store_id = id )
118+ # Handle alias resolution
119+ if alias :
120+ # Try to resolve alias to existing storage ID
121+ resolved_id = await resolve_alias_to_id (alias , 'key_value_store' , configuration )
122+ if resolved_id :
123+ id = resolved_id
124+ else :
125+ # Create a new storage and store the alias mapping
126+ new_storage_metadata = ApifyKeyValueStoreMetadata .model_validate (
127+ await apify_kvss_client .get_or_create (),
128+ )
129+ id = new_storage_metadata .id
130+ await store_alias_mapping (alias , 'key_value_store' , id , configuration )
117131
118132 # If name is provided, get or create the storage by name.
119- if name and id is None :
133+ elif name :
120134 id = ApifyKeyValueStoreMetadata .model_validate (
121135 await apify_kvss_client .get_or_create (name = name ),
122136 ).id
123- apify_kvs_client = apify_client_async .key_value_store (key_value_store_id = id )
124137
125- # If both id and name are None, try to get the default storage ID from environment variables.
126- # The default storage ID environment variable is set by the Apify platform. It also contains
127- # a new storage ID after Actor's reboot or migration.
128- if id is None and name is None :
138+ # If none are provided, try to get the default storage ID from environment variables.
139+ elif id is None :
129140 id = configuration .default_key_value_store_id
130- apify_kvs_client = apify_client_async .key_value_store (key_value_store_id = id )
141+
142+ # Now create the client for the determined ID
143+ apify_kvs_client = apify_client_async .key_value_store (key_value_store_id = id )
131144
132145 # Fetch its metadata.
133146 metadata = await apify_kvs_client .get ()
@@ -142,7 +155,7 @@ async def open(
142155 # Verify that the storage exists by fetching its metadata again.
143156 metadata = await apify_kvs_client .get ()
144157 if metadata is None :
145- raise ValueError (f'Opening key-value store with id={ id } and name={ name } failed.' )
158+ raise ValueError (f'Opening key-value store with id={ id } , name={ name } , and alias= { alias } failed.' )
146159
147160 return cls (
148161 api_client = apify_kvs_client ,
0 commit comments