Skip to content

Blob.from_string(gs_url, client=client): TypeError: Client.__init__() got an unexpected keyword argument 'parent' #6

@fnkr

Description

@fnkr

In the current version, when creating a blob using Blob.from_string() and specifying the gs://bucket/path URL as well as the client, the following error is thrown once we want to retrieve the object (e.g. using blob.download_to_file()):

Traceback (most recent call last):
  File "/workspace/project/foo3.py", line 28, in <module>
    blob.download_to_file(stream)
  File "/workspace/venv/lib/python3.12/site-packages/google/cloud/storage/blob.py", line 1160, in download_to_file
    self._prep_and_do_download(
  File "/workspace/venv/lib/python3.12/site-packages/google/cloud/storage/blob.py", line 4338, in _prep_and_do_download
    download_url = self._get_download_url(
                   ^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspace/venv/lib/python3.12/site-packages/google/cloud/storage/blob.py", line 862, in _get_download_url
    hostname = _get_host_name(client._connection)
                              ^^^^^^^^^^^^^^^^^^
  File "/usr/local/python/current/lib/python3.12/unittest/mock.py", line 678, in __getattr__
    result = self._get_child_mock(
             ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/python/current/lib/python3.12/unittest/mock.py", line 1055, in _get_child_mock
    return klass(**kw)
           ^^^^^^^^^^^
TypeError: Client.__init__() got an unexpected keyword argument 'parent'

Example code:

import io

import google.cloud.storage
import google.cloud.storage.blob
from cloud_storage_mocker import Mount
from cloud_storage_mocker import patch as gcs_patch

storage_dir = "."
bucket_name = "b"


with gcs_patch([Mount(bucket_name, storage_dir, readable=True, writable=True)]):
    client = google.cloud.storage.Client()

blob_name = "hello.txt"

# Write object
blob = client.bucket(bucket_name).blob(blob_name)
blob.upload_from_string("world")

# Make object using `Blob.from_string()` and `gs://` URL
blob = google.cloud.storage.blob.Blob.from_string(f"gs://{bucket_name}/{blob_name}", client=client)

# Workaround: Recreate blob using `client.bucket().blob()`
# blob = client.bucket(blob.bucket.name).blob(blob.name)

# Read object
stream = io.BytesIO()
blob.download_to_file(stream) # <-- throws exception
stream.seek(0)

There's a workaround though: after parsing the gs:// URL using Blob.from_string(), we can create a new blob using client.bucket(bucket).blob(blob), which works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions