Repository: apify/crawlee-python
File: src/crawlee/storages/_creation_management.py (Python)

Code before:
        cached_storage = _get_from_cache_by_id(storage_class=storage_class, id=id)
        if cached_storage:
            return cached_storage

    # Purge on start if configured
    if configuration.purge_on_start:
        await storage_client.purge_on_start()

    # Lock and create new storage
    async with _creation_lock:
        if id and not is_default_on_memory:
            resource_client = _get_resource_client(storage_class, storage_client, id)
            storage_info = await resource_client.get()
            if not storage_info:
                raise RuntimeError(f'{storage_class.__name__} with id "{id}" does not exist!')

        elif is_default_on_memory:
            resource_collection_client = _get_resource_collection_client(storage_class, storage_client)
            storage_info = await resource_collection_client.get_or_create(name=name, id=id)

        else:
            resource_collection_client = _get_resource_collection_client(storage_class, storage_client)
            storage_info = await resource_collection_client.get_or_create(name=name)

        storage = storage_class(
            id=storage_info.id, name=storage_info.name, storage_client=storage_client, storage_object=storage_info
        )

        # Cache the storage by ID and name
        _add_to_cache_by_id(storage.id, storage)
        if storage.name is not None:
            _add_to_cache_by_name(storage.name, storage)

    return storage


def remove_storage_from_cache(
    *,
    storage_class: type,
    id: str | None = None,
    name: str | None = None,
) -> None:
    """Remove a storage from cache by ID or name."""
    if id:
        _rm_from_cache_by_id(storage_class=storage_class, id=id)

    if name:
        _rm_from_cache_by_name(storage_class=storage_class, name=name)


def _get_resource_client(

Review comment (suggestion):
It looks kind of strange as the arguments for the `__init__`  are now redundant as the storage_info contains first two args as well. Maybe it would be more suitable to create an alternate constructor. 

(Btw. there is a risk that redundant and directly passed arguments `id` or `name` would not match `id`and `name` from `storage_metadata`, so that is another argument for not having redundant inputs in the constructor)

Example of suggested alternate constructor call:

`storage=storage_class.from_storage_info(storage_client=storage_client, storage_object=storage_info)`


Code after:
        cached_storage = _get_from_cache_by_id(storage_class=storage_class, id=id)
        if cached_storage:
            return cached_storage

    # Purge on start if configured
    if configuration.purge_on_start:
        await storage_client.purge_on_start()

    # Lock and create new storage
    async with _creation_lock:
        if id and not is_default_on_memory:
            resource_client = _get_resource_client(storage_class, storage_client, id)
            storage_object = await resource_client.get()
            if not storage_object:
                raise RuntimeError(f'{storage_class.__name__} with id "{id}" does not exist!')

        elif is_default_on_memory:
            resource_collection_client = _get_resource_collection_client(storage_class, storage_client)
            storage_object = await resource_collection_client.get_or_create(name=name, id=id)

        else:
            resource_collection_client = _get_resource_collection_client(storage_class, storage_client)
            storage_object = await resource_collection_client.get_or_create(name=name)

        storage = storage_class.from_storage_object(storage_client=storage_client, storage_object=storage_object)

        # Cache the storage by ID and name
        _add_to_cache_by_id(storage.id, storage)
        if storage.name is not None:
            _add_to_cache_by_name(storage.name, storage)

    return storage


def remove_storage_from_cache(
    *,
    storage_class: type,
    id: str | None = None,
    name: str | None = None,
) -> None:
    """Remove a storage from cache by ID or name."""
    if id:
        _rm_from_cache_by_id(storage_class=storage_class, id=id)

    if name:
        _rm_from_cache_by_name(storage_class=storage_class, name=name)


def _get_resource_client(
    storage_class: type[TResource],
    storage_client: StorageClient,