Repository: PrefectHQ/prefect

Issue:
Azure BlobStorageUpload doesn't allow for overwriting blobs
## Current behavior

You get an error if you try to upload the same file name

```
azure.core.exceptions.ResourceExistsError: The specified blob already exists.
RequestId:5bef0cf1-b01e-002e-6
```

## Proposed behavior

The task should take in an `overwrite` argument and pass it to [this line](https://github.com/PrefectHQ/prefect/blob/6cd24b023411980842fa77e6c0ca2ced47eeb83e/src/prefect/tasks/azure/blobstorage.py#L131).




Discussion:
See similar implementation in https://github.com/PrefectHQ/prefect/pull/5103
Hey can I please try to solve this problem....?

Go for it @4bhishek10 ! 
@4bhishek10 are you still working on this? 
@kvnkho if @4bhishek10 isn't working on this, can I take it up?
I haven't heard from him so I guess give it a shot 👍 

Resolving patch:
diff --git a/src/prefect/tasks/azure/blobstorage.py b/src/prefect/tasks/azure/blobstorage.py
--- a/src/prefect/tasks/azure/blobstorage.py
+++ b/src/prefect/tasks/azure/blobstorage.py
@@ -75,6 +75,8 @@ class BlobStorageUpload(Task):
         - azure_credentials_secret (str, optional): the name of the Prefect Secret
             that stores your Azure credentials; this Secret must be an Azure connection string
         - container (str, optional): the name of the Azure Blob Storage to upload to
+        - overwrite (bool, optional): if `True`, an existing blob with the same name will be overwritten.
+            Defaults to `False` and an error will be thrown if the blob already exists.
         - **kwargs (dict, optional): additional keyword arguments to pass to the
             Task constructor
     """
@@ -83,19 +85,22 @@ def __init__(
         self,
         azure_credentials_secret: str = "AZ_CONNECTION_STRING",
         container: str = None,
+        overwrite: bool = False,
         **kwargs
     ) -> None:
         self.azure_credentials_secret = azure_credentials_secret
         self.container = container
+        self.overwrite = overwrite
         super().__init__(**kwargs)
 
-    @defaults_from_attrs("azure_credentials_secret", "container")
+    @defaults_from_attrs("azure_credentials_secret", "container", "overwrite")
     def run(
         self,
         data: str,
         blob_name: str = None,
         azure_credentials_secret: str = "AZ_CONNECTION_STRING",
         container: str = None,
+        overwrite: bool = False,
     ) -> str:
         """
         Task run method.
@@ -107,6 +112,8 @@ def run(
             - azure_credentials_secret (str, optional): the name of the Prefect Secret
             that stores your Azure credentials; this Secret must be an Azure connection string
             - container (str, optional): the name of the Blob Storage container to upload to
+        - overwrite (bool, optional): if `True`, an existing blob with the same name will be overwritten.
+            Defaults to `False` and an error will be thrown if the blob already exists.
 
         Returns:
             - str: the name of the blob the data payload was uploaded to
@@ -128,6 +135,6 @@ def run(
 
         client = blob_service.get_blob_client(container=container, blob=blob_name)
 
-        client.upload_blob(data)
+        client.upload_blob(data, overwrite=overwrite)
 
         return blob_name


Test patch:
diff --git a/tests/tasks/azure/test_blobstorage.py b/tests/tasks/azure/test_blobstorage.py
--- a/tests/tasks/azure/test_blobstorage.py
+++ b/tests/tasks/azure/test_blobstorage.py
@@ -2,7 +2,6 @@
 
 import pytest
 
-import azure.storage.blob
 import prefect
 from prefect.tasks.azure import BlobStorageDownload, BlobStorageUpload
 from prefect.utilities.configuration import set_temporary_config
@@ -62,3 +61,23 @@ def test_connection_string_creds_are_pulled_from_secret_and_runs(self, monkeypat
         with set_temporary_config({"cloud.use_local_secrets": True}):
             with prefect.context(secrets=dict(AZ_CONNECTION_STRING="conn")):
                 assert task.run(data="")
+
+    def test_overwrite_passed_to_upload_blob(self, monkeypatch):
+        task = BlobStorageUpload(container="bob", overwrite=True)
+
+        data = "blob_data"
+        upload_blob = MagicMock()
+        blob_client = MagicMock(upload_blob=upload_blob)
+        blob_service_client = MagicMock(
+            get_blob_client=MagicMock(return_value=blob_client)
+        )
+        from_connection_string = MagicMock(return_value=blob_service_client)
+        blob = MagicMock(
+            BlobServiceClient=MagicMock(from_connection_string=from_connection_string)
+        )
+        monkeypatch.setattr("prefect.tasks.azure.blobstorage.azure.storage.blob", blob)
+
+        with set_temporary_config({"cloud.use_local_secrets": True}):
+            with prefect.context(secrets=dict(AZ_CONNECTION_STRING="conn")):
+                assert task.run(data=data)
+                upload_blob.assert_called_once_with(data, overwrite=True)