OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

Inner function as callback not called

  • Thread starter Thread starter Bloodbee
  • Start date Start date
B

Bloodbee

Guest
So i've got some classes that allow me to upload file-like/io objects to azure blob storage. My problem here is that i want to pass a callback during the export of those objects, and this callback needs to do multiple things (hence call a higher method).

Here is the code:

Code:
from azure.storage.blob import BlobServiceClient

class UploadStatus:

    def __init__(self, uploaded=0, total=None):
        self.uploaded = uploaded
        self.total = total
    
    def update(self, uploaded, total):
        if total is not None:
            self.total = self._normalize(total)
        if uploaded is not None:
            self.uploaded = self._normalize(uploaded)
    
    def progress(self):
        """Calculate the progress made for the upload incorring."""
        return 100.0 * self.uploaded / self.total if self.total > 0 else 0
    
    def _normalize(self, integer):
        return integer if integer else 0

class Resource:
    """A wrapper encapsulating an io-like object"""
    def __init__(self, ...):
        ...


class AzureBlobProxy:
    def __init__(self, client):
        self.client = client

    @classmethod
    def build(cls, params: dict):
        client = BlobServiceClient(**params)
        return cls(client)

    def blob_export(self, container: str, name: str, io, block=None) -> dict:
        """Export file-like object to a Storage.

        Args:
            container (string): Container to use
            name (string): Name to use
            io (io.IOBase): File-like io object base on IOBase.
        """
        blob_client = self.client.get_blob_client(
            container=container,
            blob=name
        )

        return blob_client.upload_blob(
            data=io,
            progress_hook=block
        )


class AzureProvider:

    def upload(self, resource, status, params={}, block=None):
        """See BaseProvider.upload() description."""
        proxy = AzureBlobProxy.build(params)
        container, name = self._extract_container_and_name_from_params(params)

        def progress_callback(sent, total):
            print(block)  # doesn't display the block function
            status.update(uploaded=sent, total=total)
            if block and callable(block):
                block.__call__(status)

        with resource.with_io() as io:
            status.update(uploaded=0, total=sys.getsizeof(io))
            proxy.blob_export(container, name, io, progress_callback)

        return self._upload_strategy()
    
    def _extract_container_and_name_from_params(self, params):
        """Return container and name for blob"""
        ...
    
    def __upload_strategy(self):
        return 'azure-blob'


def print_progress(status):
    print('PROGRESS {}%'.format(int(status.progress())))

parameters = { ... }
resource = Resource(...)
upload_status = UploadStatus()
strategy = provider.upload(resource, upload_status, parameters, print_progress)

Have a look at my inner function progress_callback that is the progress_hook passed to this final method https://learn.microsoft.com/en-us/p...hon#azure-storage-blob-blobclient-upload-blob

It should call the function print_progress but that's not the case, i don't see any printing "PROGRESS %" appearing.

I can confirm though that file-like object is exported to azure blob storage.

Do you have any idea?
<p>So i've got some classes that allow me to upload file-like/io objects to azure blob storage.
My problem here is that i want to pass a callback during the export of those objects, and this callback needs to do multiple things (hence call a higher method).</p>
<p>Here is the code:</p>
<pre><code>from azure.storage.blob import BlobServiceClient

class UploadStatus:

def __init__(self, uploaded=0, total=None):
self.uploaded = uploaded
self.total = total

def update(self, uploaded, total):
if total is not None:
self.total = self._normalize(total)
if uploaded is not None:
self.uploaded = self._normalize(uploaded)

def progress(self):
"""Calculate the progress made for the upload incorring."""
return 100.0 * self.uploaded / self.total if self.total > 0 else 0

def _normalize(self, integer):
return integer if integer else 0

class Resource:
"""A wrapper encapsulating an io-like object"""
def __init__(self, ...):
...


class AzureBlobProxy:
def __init__(self, client):
self.client = client

@classmethod
def build(cls, params: dict):
client = BlobServiceClient(**params)
return cls(client)

def blob_export(self, container: str, name: str, io, block=None) -> dict:
"""Export file-like object to a Storage.

Args:
container (string): Container to use
name (string): Name to use
io (io.IOBase): File-like io object base on IOBase.
"""
blob_client = self.client.get_blob_client(
container=container,
blob=name
)

return blob_client.upload_blob(
data=io,
progress_hook=block
)


class AzureProvider:

def upload(self, resource, status, params={}, block=None):
"""See BaseProvider.upload() description."""
proxy = AzureBlobProxy.build(params)
container, name = self._extract_container_and_name_from_params(params)

def progress_callback(sent, total):
print(block) # doesn't display the block function
status.update(uploaded=sent, total=total)
if block and callable(block):
block.__call__(status)

with resource.with_io() as io:
status.update(uploaded=0, total=sys.getsizeof(io))
proxy.blob_export(container, name, io, progress_callback)

return self._upload_strategy()

def _extract_container_and_name_from_params(self, params):
"""Return container and name for blob"""
...

def __upload_strategy(self):
return 'azure-blob'


def print_progress(status):
print('PROGRESS {}%'.format(int(status.progress())))

parameters = { ... }
resource = Resource(...)
upload_status = UploadStatus()
strategy = provider.upload(resource, upload_status, parameters, print_progress)
</code></pre>
<p>Have a look at my inner function <code>progress_callback</code> that is the progress_hook passed to this final method <a href="https://learn.microsoft.com/en-us/p...hon#azure-storage-blob-blobclient-upload-blob" rel="nofollow noreferrer">https://learn.microsoft.com/en-us/p...hon#azure-storage-blob-blobclient-upload-blob</a></p>
<p>It should call the function <code>print_progress</code> but that's not the case, i don't see any printing "PROGRESS %" appearing.</p>
<p>I can confirm though that file-like object is exported to azure blob storage.</p>
<p>Do you have any idea?</p>
 

Latest posts

Online statistics

Members online
0
Guests online
2
Total visitors
2
Ads by Eonads
Top