azblob

package module
v1.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 8, 2024 License: MIT Imports: 14 Imported by: 290

README

Azure Blob Storage module for Go

Service Version: 2023-11-03

Azure Blob Storage is Microsoft's object storage solution for the cloud. Blob Storage is optimized for storing massive amounts of unstructured data - data that does not adhere to a particular data model or definition, such as text or binary data. For more information, see Introduction to Azure Blob Storage.

Use the Azure Blob Storage client module github.com/Azure/azure-sdk-for-go/sdk/storage/azblob to:

  • Authenticate clients with Azure Blob Storage
  • Manipulate containers and blobs in an Azure storage account

Key links:

Source code | API reference documentation | REST API documentation | Product documentation | Samples

Getting started

Prerequisites
az storage account create --name MyStorageAccount --resource-group MyResourceGroup --location westus --sku Standard_LRS
Install the package

Install the Azure Blob Storage client module for Go with go get:

go get github.com/Azure/azure-sdk-for-go/sdk/storage/azblob

If you plan to authenticate with Azure Active Directory (recommended), also install the azidentity module.

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
Authenticate the client

To interact with the Azure Blob Storage service, you'll need to create an instance of the azblob.Client type. The azidentity module makes it easy to add Azure Active Directory support for authenticating Azure SDK clients with their corresponding Azure services.

// create a credential for authenticating with Azure Active Directory
cred, err := azidentity.NewDefaultAzureCredential(nil)
// TODO: handle err

// create an azblob.Client for the specified storage account that uses the above credential
client, err := azblob.NewClient("https://MYSTORAGEACCOUNT.blob.core.windows.net/", cred, nil)
// TODO: handle err

Learn more about enabling Azure Active Directory for authentication with Azure Storage:

Other options for authentication include connection strings, shared key, shared access signatures (SAS), and anonymous public access. Use the appropriate client constructor function for the authentication mechanism you wish to use. For examples, see:

Key concepts

Blob Storage is designed for:

  • Serving images or documents directly to a browser.
  • Storing files for distributed access.
  • Streaming video and audio.
  • Writing to log files.
  • Storing data for backup and restore, disaster recovery, and archiving.
  • Storing data for analysis by an on-premises or Azure-hosted service.

Blob Storage offers three types of resources:

  • The storage account
  • One or more containers in a storage account
  • One or more blobs in a container

Instances of the azblob.Client type provide methods for manipulating containers and blobs within a storage account. The storage account is specified when the azblob.Client is constructed.

Specialized clients

The Azure Blob Storage client module for Go also provides specialized clients in various subpackages. Use these clients when you need to interact with a specific kind of blob. Learn more about block blobs, append blobs, and page blobs.

The blob package contains APIs common to all blob types. This includes APIs for deleting and undeleting a blob, setting metadata, and more.

The lease package contains clients for managing leases on blobs and containers. See the REST API reference for general information on leases.

The container package contains APIs specific to containers. This includes APIs for setting access policies or properties, and more.

The service package contains APIs specific to the Blob service. This includes APIs for manipulating containers, retrieving account information, and more.

The sas package contains utilities to aid in the creation and manipulation of shared access signature (SAS) tokens. See the package's documentation for more information.

Goroutine safety

We guarantee that all client instance methods are goroutine-safe and independent of each other (see guideline). This ensures that the recommendation to reuse client instances is always safe, even across goroutines.

Blob metadata

Blob metadata name-value pairs are valid HTTP headers and should adhere to all restrictions governing HTTP headers. Metadata names must be valid HTTP header names, may contain only ASCII characters, and should be treated as case-insensitive. Base64-encode or URL-encode metadata values containing non-ASCII characters.

Additional concepts

Client options | Accessing the response | Handling failures | Logging

Examples

Upload a blob
const (
	account       = "https://MYSTORAGEACCOUNT.blob.core.windows.net/"
	containerName = "sample-container"
	blobName      = "sample-blob"
	sampleFile    = "path/to/sample/file"
)

// authenticate with Azure Active Directory
cred, err := azidentity.NewDefaultAzureCredential(nil)
// TODO: handle error

// create a client for the specified storage account
client, err := azblob.NewClient(account, cred, nil)
// TODO: handle error

// open the file for reading
file, err := os.OpenFile(sampleFile, os.O_RDONLY, 0)
// TODO: handle error
defer file.Close()

// upload the file to the specified container with the specified blob name
_, err = client.UploadFile(context.TODO(), containerName, blobName, file, nil)
// TODO: handle error
Download a blob
// this example accesses a public blob via anonymous access, so no credentials are required
client, err := azblob.NewClientWithNoCredential("https://azurestoragesamples.blob.core.windows.net/", nil)
// TODO: handle error

// create or open a local file where we can download the blob
file, err := os.Create("cloud.jpg")
// TODO: handle error
defer file.Close()

// download the blob
_, err = client.DownloadFile(context.TODO(), "samples", "cloud.jpg", file, nil)
// TODO: handle error
Enumerate blobs
const (
	account       = "https://MYSTORAGEACCOUNT.blob.core.windows.net/"
	containerName = "sample-container"
)

// authenticate with Azure Active Directory
cred, err := azidentity.NewDefaultAzureCredential(nil)
// TODO: handle error

// create a client for the specified storage account
client, err := azblob.NewClient(account, cred, nil)
// TODO: handle error

// blob listings are returned across multiple pages
pager := client.NewListBlobsFlatPager(containerName, nil)

// continue fetching pages until no more remain
for pager.More() {
  // advance to the next page
	page, err := pager.NextPage(context.TODO())
	// TODO: handle error

	// print the blob names for this page
	for _, blob := range page.Segment.BlobItems {
		fmt.Println(*blob.Name)
	}
}

Troubleshooting

All Blob service operations will return an *azcore.ResponseError on failure with a populated ErrorCode field. Many of these errors are recoverable. The bloberror package provides the possible Storage error codes along with helper facilities for error handling.

const (
	connectionString = "<connection_string>"
	containerName    = "sample-container"
)

// create a client with the provided connection string
client, err := azblob.NewClientFromConnectionString(connectionString, nil)
// TODO: handle error

// try to delete the container, avoiding any potential race conditions with an in-progress or completed deletion
_, err = client.DeleteContainer(context.TODO(), containerName, nil)

if bloberror.HasCode(err, bloberror.ContainerBeingDeleted, bloberror.ContainerNotFound) {
	// ignore any errors if the container is being deleted or already has been deleted
} else if err != nil {
	// TODO: some other error
}

Next steps

Get started with our Blob samples. They contain complete examples of the above snippets and more.

Contributing

See the Storage CONTRIBUTING.md for details on building, testing, and contributing to this library.

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit cla.microsoft.com.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

Impressions

Documentation

Overview

Example

This example is a quick-starter and demonstrates how to get started using the Azure Blob Storage SDK for Go.

package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"os"
	"strings"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// Your account name and key can be obtained from the Azure Portal.
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}

	accountKey, ok := os.LookupEnv("AZURE_STORAGE_PRIMARY_ACCOUNT_KEY")
	if !ok {
		panic("AZURE_STORAGE_PRIMARY_ACCOUNT_KEY could not be found")
	}
	cred, err := azblob.NewSharedKeyCredential(accountName, accountKey)
	handleError(err)

	// The service URL for blob endpoints is usually in the form: http(s)://<account>.blob.core.windows.net/
	client, err := azblob.NewClientWithSharedKeyCredential(fmt.Sprintf("https://%s.blob.core.windows.net/", accountName), cred, nil)
	handleError(err)

	// ===== 1. Create a container =====
	containerName := "testcontainer"
	containerCreateResp, err := client.CreateContainer(context.TODO(), containerName, nil)
	handleError(err)
	fmt.Println(containerCreateResp)

	// ===== 2. Upload and Download a block blob =====
	blobData := "Hello world!"
	blobName := "HelloWorld.txt"
	uploadResp, err := client.UploadStream(context.TODO(),
		containerName,
		blobName,
		strings.NewReader(blobData),
		&azblob.UploadStreamOptions{
			Metadata: map[string]*string{"Foo": to.Ptr("Bar")},
			Tags:     map[string]string{"Year": "2022"},
		})
	handleError(err)
	fmt.Println(uploadResp)

	// Download the blob's contents and ensure that the download worked properly
	blobDownloadResponse, err := client.DownloadStream(context.TODO(), containerName, blobName, nil)
	handleError(err)

	// Use the bytes.Buffer object to read the downloaded data.
	// RetryReaderOptions has a lot of in-depth tuning abilities, but for the sake of simplicity, we'll omit those here.
	reader := blobDownloadResponse.Body
	downloadData, err := io.ReadAll(reader)
	handleError(err)
	if string(downloadData) != blobData {
		log.Fatal("Uploaded data should be same as downloaded data")
	}

	err = reader.Close()
	if err != nil {
		return
	}

	// ===== 3. List blobs =====
	// List methods returns a pager object which can be used to iterate over the results of a paging operation.
	// To iterate over a page use the NextPage(context.Context) to fetch the next page of results.
	// PageResponse() can be used to iterate over the results of the specific page.
	pager := client.NewListBlobsFlatPager(containerName, nil)
	for pager.More() {
		resp, err := pager.NextPage(context.TODO())
		handleError(err)
		for _, v := range resp.Segment.BlobItems {
			fmt.Println(*v.Name)
		}
	}

	// Delete the blob.
	_, err = client.DeleteBlob(context.TODO(), containerName, blobName, nil)
	handleError(err)

	// Delete the container.
	_, err = client.DeleteContainer(context.TODO(), containerName, nil)
	handleError(err)
}
Output:

Example (Blob_AccessConditions)

This example shows how to perform operations on blob conditionally.

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blockblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	accountName, accountKey := os.Getenv("AZURE_STORAGE_ACCOUNT_NAME"), os.Getenv("AZURE_STORAGE_ACCOUNT_KEY")

	credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
	handleError(err)
	blockBlob, err := blockblob.NewClientWithSharedKeyCredential(fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/Data.txt", accountName), credential, nil)
	handleError(err)

	// This function displays the results of an operation
	showResult := func(response *blob.DownloadStreamResponse, err error) {
		if err != nil {
			log.Fatalf("Failure: %s\n", err.Error())
		} else {
			err := response.Body.Close()
			if err != nil {
				log.Fatal(err)
			}
			// The client must close the response body when finished with it
			fmt.Printf("Success: %v\n", response)
		}

		// Close the response
		if err != nil {
			return
		}
		fmt.Printf("Success: %v\n", response)
	}

	showResultUpload := func(response blockblob.UploadResponse, err error) {
		if err != nil {
			log.Fatalf("Failure: %s\n", err.Error())
		}
		fmt.Printf("Success: %v\n", response)
	}

	// Create the blob
	upload, err := blockBlob.Upload(context.TODO(), streaming.NopCloser(strings.NewReader("Text-1")), nil)
	showResultUpload(upload, err)

	// Download blob content if the blob has been modified since we uploaded it (fails):
	downloadResp, err := blockBlob.DownloadStream(
		context.TODO(),
		&azblob.DownloadStreamOptions{
			AccessConditions: &blob.AccessConditions{
				ModifiedAccessConditions: &blob.ModifiedAccessConditions{
					IfModifiedSince: upload.LastModified,
				},
			},
		},
	)
	showResult(&downloadResp, err)

	// Download blob content if the blob hasn't been modified in the last 24 hours (fails):
	downloadResp, err = blockBlob.DownloadStream(
		context.TODO(),
		&azblob.DownloadStreamOptions{
			AccessConditions: &blob.AccessConditions{
				ModifiedAccessConditions: &blob.ModifiedAccessConditions{
					IfUnmodifiedSince: to.Ptr(time.Now().UTC().Add(time.Hour * -24))},
			},
		},
	)
	showResult(&downloadResp, err)

	// Upload new content if the blob hasn't changed since the version identified by ETag (succeeds):
	showResultUpload(blockBlob.Upload(
		context.TODO(),
		streaming.NopCloser(strings.NewReader("Text-2")),
		&blockblob.UploadOptions{
			AccessConditions: &blob.AccessConditions{
				ModifiedAccessConditions: &blob.ModifiedAccessConditions{IfMatch: upload.ETag},
			},
		},
	))

	// Download content if it has changed since the version identified by ETag (fails):
	downloadResp, err = blockBlob.DownloadStream(
		context.TODO(),
		&azblob.DownloadStreamOptions{
			AccessConditions: &blob.AccessConditions{
				ModifiedAccessConditions: &blob.ModifiedAccessConditions{IfNoneMatch: upload.ETag}},
		})
	showResult(&downloadResp, err)

	// Upload content if the blob doesn't already exist (fails):
	showResultUpload(blockBlob.Upload(
		context.TODO(),
		streaming.NopCloser(strings.NewReader("Text-3")),
		&blockblob.UploadOptions{
			AccessConditions: &blob.AccessConditions{
				ModifiedAccessConditions: &blob.ModifiedAccessConditions{IfNoneMatch: to.Ptr(azcore.ETagAny)},
			},
		}))
}
Output:

Example (Blob_Client_Download)

This example shows how to download a large stream with intelligent retries. Specifically, if the connection fails while reading, continuing to read from this stream initiates a new GetBlob call passing a range that starts from the last byte successfully read before the failure.

package main

import (
	"context"
	"fmt"
	"io"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// From the Azure portal, get your Storage account blob service URL endpoint.
	accountName, accountKey := os.Getenv("AZURE_STORAGE_ACCOUNT_NAME"), os.Getenv("AZURE_STORAGE_ACCOUNT_KEY")

	// Create a blobClient object to a blob in the container (we assume the container & blob already exist).
	blobURL := fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer/BigBlob.bin", accountName)
	credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
	handleError(err)
	blobClient, err := blob.NewClientWithSharedKeyCredential(blobURL, credential, nil)
	handleError(err)

	contentLength := int64(0) // Used for progress reporting to report the total number of bytes being downloaded.

	// Download returns an intelligent retryable stream around a blob; it returns an io.ReadCloser.
	dr, err := blobClient.DownloadStream(context.TODO(), nil)
	handleError(err)
	rs := dr.Body

	// NewResponseBodyProgress wraps the GetRetryStream with progress reporting; it returns an io.ReadCloser.
	stream := streaming.NewResponseProgress(
		rs,
		func(bytesTransferred int64) {
			fmt.Printf("Downloaded %d of %d bytes.\n", bytesTransferred, contentLength)
		},
	)
	defer func(stream io.ReadCloser) {
		err := stream.Close()
		if err != nil {
			log.Fatal(err)
		}
	}(stream) // The client must close the response body when finished with it

	file, err := os.Create("BigFile.bin") // Create the file to hold the downloaded blob contents.
	handleError(err)
	defer func(file *os.File) {
		err := file.Close()
		if err != nil {

		}
	}(file)

	written, err := io.Copy(file, stream) // Write to the file by reading from the blob (with intelligent retries).
	handleError(err)
	fmt.Printf("Wrote %d bytes.\n", written)
}
Output:

Example (Client_CreateContainer)
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	client, err := azblob.NewClient(serviceURL, cred, nil)
	handleError(err)

	resp, err := client.CreateContainer(context.TODO(), "testcontainer", &azblob.CreateContainerOptions{
		Metadata: map[string]*string{"hello": to.Ptr("world")},
	})
	handleError(err)
	fmt.Println(resp)
}
Output:

Example (Client_DeleteBlob)
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	client, err := azblob.NewClient(serviceURL, cred, nil)
	handleError(err)

	resp, err := client.DeleteBlob(context.TODO(), "testcontainer", "testblob", nil)
	handleError(err)
	fmt.Println(resp)
}
Output:

Example (Client_DeleteContainer)
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	client, err := azblob.NewClient(serviceURL, cred, nil)
	handleError(err)

	resp, err := client.DeleteContainer(context.TODO(), "testcontainer", nil)
	handleError(err)
	fmt.Println(resp)
}
Output:

Example (Client_DownloadFile)
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// Set up file to download the blob to
	destFileName := "test_download_file.txt"
	destFile, err := os.Create(destFileName)
	handleError(err)
	defer func(destFile *os.File) {
		err = destFile.Close()
		handleError(err)
	}(destFile)

	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	client, err := azblob.NewClient(serviceURL, cred, nil)
	handleError(err)

	// Perform download

	_, err = client.DownloadFile(context.TODO(), "testcontainer", "virtual/dir/path/"+destFileName, destFile,
		&azblob.DownloadFileOptions{
			// If Progress is non-nil, this function is called periodically as bytes are uploaded.
			Progress: func(bytesTransferred int64) {
				fmt.Println(bytesTransferred)
			},
		})

	// Assert download was successful
	handleError(err)
}
Output:

Example (Client_DownloadStream)
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
	panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

cred, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

client, err := azblob.NewClient(serviceURL, cred, nil)
handleError(err)

// Download the blob
downloadResponse, err := client.DownloadStream(ctx, "testcontainer", "test_download_stream.bin", nil)
handleError(err)

// Assert that the content is correct
actualBlobData, err := io.ReadAll(downloadResponse.Body)
handleError(err)
fmt.Println(len(actualBlobData))
Output:

Example (Client_NewClient)
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// this example uses Azure Active Directory (AAD) to authenticate with Azure Blob Storage
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	// https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#DefaultAzureCredential
	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	client, err := azblob.NewClient(serviceURL, cred, nil)
	handleError(err)

	fmt.Println(client.URL())
}
Output:

Example (Client_NewClientFromConnectionString)
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// this example uses a connection string to authenticate with Azure Blob Storage
	connectionString, ok := os.LookupEnv("AZURE_STORAGE_CONNECTION_STRING")
	if !ok {
		log.Fatal("the environment variable 'AZURE_STORAGE_CONNECTION_STRING' could not be found")
	}

	serviceClient, err := azblob.NewClientFromConnectionString(connectionString, nil)
	handleError(err)
	fmt.Println(serviceClient.URL())
}
Output:

Example (Client_NewClientWithSharedKeyCredential)
package main

import (
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// this example uses a shared key to authenticate with Azure Blob Storage
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	accountKey, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_KEY")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_KEY could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	// shared key authentication requires the storage account name and access key
	cred, err := azblob.NewSharedKeyCredential(accountName, accountKey)
	handleError(err)
	serviceClient, err := azblob.NewClientWithSharedKeyCredential(serviceURL, cred, nil)
	handleError(err)
	fmt.Println(serviceClient.URL())
}
Output:

Example (Client_NewListBlobsPager)
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
	panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

cred, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

client, err := azblob.NewClient(serviceURL, cred, nil)
handleError(err)

pager := client.NewListBlobsFlatPager("testcontainer", &azblob.ListBlobsFlatOptions{
	Include: container.ListBlobsInclude{Deleted: true, Versions: true},
})

for pager.More() {
	resp, err := pager.NextPage(ctx)
	handleError(err) // if err is not nil, break the loop.
	for _, _blob := range resp.Segment.BlobItems {
		fmt.Printf("%v", _blob.Name)
	}
}
Output:

Example (Client_NewListContainersPager)
accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
if !ok {
	panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
}
serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

cred, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

client, err := azblob.NewClient(serviceURL, cred, nil)
handleError(err)

pager := client.NewListContainersPager(&azblob.ListContainersOptions{
	Include: azblob.ListContainersInclude{Metadata: true, Deleted: true},
})

for pager.More() {
	resp, err := pager.NextPage(ctx)
	handleError(err) // if err is not nil, break the loop.
	for _, _container := range resp.ContainerItems {
		fmt.Printf("%v", _container)
	}
}
Output:

Example (Client_UploadFile)
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// Set up file to upload
	fileSize := 8 * 1024 * 1024
	fileName := "test_upload_file.txt"
	fileData := make([]byte, fileSize)
	err := os.WriteFile(fileName, fileData, 0666)
	handleError(err)

	// Open the file to upload
	fileHandler, err := os.Open(fileName)
	handleError(err)

	// close the file after it is no longer required.
	defer func(file *os.File) {
		err = file.Close()
		handleError(err)
	}(fileHandler)

	// delete the local file if required.
	defer func(name string) {
		err = os.Remove(name)
		handleError(err)
	}(fileName)

	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	client, err := azblob.NewClient(serviceURL, cred, nil)
	handleError(err)

	// Upload the file to a block blob
	_, err = client.UploadFile(context.TODO(), "testcontainer", "virtual/dir/path/"+fileName, fileHandler,
		&azblob.UploadFileOptions{
			BlockSize:   int64(1024),
			Concurrency: uint16(3),
			// If Progress is non-nil, this function is called periodically as bytes are uploaded.
			Progress: func(bytesTransferred int64) {
				fmt.Println(bytesTransferred)
			},
		})
	handleError(err)
}
Output:

Example (Client_UploadStream)
package main

import (
	"bytes"
	"context"
	"fmt"
	"log"
	"os"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	accountName, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_NAME")
	if !ok {
		panic("AZURE_STORAGE_ACCOUNT_NAME could not be found")
	}
	serviceURL := fmt.Sprintf("https://%s.blob.core.windows.net/", accountName)

	cred, err := azidentity.NewDefaultAzureCredential(nil)
	handleError(err)

	client, err := azblob.NewClient(serviceURL, cred, nil)
	handleError(err)

	// Set up test blob
	containerName := "testcontainer"
	bufferSize := 8 * 1024 * 1024
	blobName := "test_upload_stream.bin"
	blobData := make([]byte, bufferSize)
	blobContentReader := bytes.NewReader(blobData)

	// Perform UploadStream
	resp, err := client.UploadStream(context.TODO(), containerName, blobName, blobContentReader,
		&azblob.UploadStreamOptions{
			Metadata: map[string]*string{"hello": to.Ptr("world")},
		})
	// Assert that upload was successful
	handleError(err)
	fmt.Println(resp)
}
Output:

Example (Client_anonymous_NewClientWithNoCredential)
package main

import (
	"fmt"
	"log"

	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// this example uses anonymous access to access a public blob
	serviceClient, err := azblob.NewClientWithNoCredential("https://azurestoragesamples.blob.core.windows.net/samples/cloud.jpg", nil)
	handleError(err)
	fmt.Println(serviceClient.URL())
}
Output:

Example (ProgressUploadDownload)
package main

import (
	"bytes"
	"context"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blob"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/blockblob"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob/container"
)

func handleError(err error) {
	if err != nil {
		log.Fatal(err.Error())
	}
}

func main() {
	// Create a credentials object with your Azure Storage Account name and key.
	accountName, accountKey := os.Getenv("AZURE_STORAGE_ACCOUNT_NAME"), os.Getenv("AZURE_STORAGE_ACCOUNT_KEY")
	credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
	handleError(err)

	// From the Azure portal, get your Storage account blob service URL endpoint.
	containerURL := fmt.Sprintf("https://%s.blob.core.windows.net/mycontainer", accountName)

	// Create an serviceClient object that wraps the service URL and a request pipeline to making requests.
	containerClient, err := container.NewClientWithSharedKeyCredential(containerURL, credential, nil)
	handleError(err)

	// Here's how to create a blob with HTTP headers and metadata (I'm using the same metadata that was put on the container):
	blobClient := containerClient.NewBlockBlobClient("Data.bin")

	// requestBody is the stream of data to write
	requestBody := streaming.NopCloser(strings.NewReader("Some text to write"))

	// Wrap the request body in a RequestBodyProgress and pass a callback function for progress reporting.
	requestProgress := streaming.NewRequestProgress(streaming.NopCloser(requestBody), func(bytesTransferred int64) {
		fmt.Printf("Wrote %d of %d bytes.", bytesTransferred, requestBody)
	})
	_, err = blobClient.Upload(context.TODO(), requestProgress, &blockblob.UploadOptions{
		HTTPHeaders: &blob.HTTPHeaders{
			BlobContentType:        to.Ptr("text/html; charset=utf-8"),
			BlobContentDisposition: to.Ptr("attachment"),
		},
	})
	handleError(err)

	// Here's how to read the blob's data with progress reporting:
	get, err := blobClient.DownloadStream(context.TODO(), nil)
	handleError(err)

	// Wrap the response body in a ResponseBodyProgress and pass a callback function for progress reporting.
	responseBody := streaming.NewResponseProgress(
		get.Body,
		func(bytesTransferred int64) {
			fmt.Printf("Read %d of %d bytes.", bytesTransferred, *get.ContentLength)
		},
	)

	downloadedData := &bytes.Buffer{}
	_, err = downloadedData.ReadFrom(responseBody)
	if err != nil {
		return
	}
	err = responseBody.Close()
	if err != nil {
		return
	}
	fmt.Printf("Downloaded data: %s\n", downloadedData.String())
}
Output:

Index

Examples

Constants

View Source
const (
	// EventUpload is used for logging events related to upload operation.
	EventUpload = exported.EventUpload

	// EventSubmitBatch is used for logging events related to submit blob batch operation.
	EventSubmitBatch = exported.EventSubmitBatch
)

Variables

This section is empty.

Functions

This section is empty.

Types

type AccessConditions added in v0.5.0

type AccessConditions = exported.BlobAccessConditions

AccessConditions identifies blob-specific access conditions which you optionally set.

type CPKInfo added in v1.0.0

type CPKInfo = blob.CPKInfo

CPKInfo contains a group of parameters for client provided encryption key.

type CPKScopeInfo added in v1.0.0

type CPKScopeInfo = container.CPKScopeInfo

CPKScopeInfo contains a group of parameters for the ContainerClient.Create method.

type Client added in v0.5.0

type Client struct {
	// contains filtered or unexported fields
}

Client represents a URL to an Azure Storage blob; the blob may be a block blob, append blob, or page blob.

func NewClient added in v0.5.0

func NewClient(serviceURL string, cred azcore.TokenCredential, options *ClientOptions) (*Client, error)

NewClient creates an instance of Client with the specified values.

  • serviceURL - the URL of the storage account e.g. https://<account>.blob.core.windows.net/
  • cred - an Azure AD credential, typically obtained via the azidentity module
  • options - client options; pass nil to accept the default values

func NewClientFromConnectionString added in v0.5.0

func NewClientFromConnectionString(connectionString string, options *ClientOptions) (*Client, error)

NewClientFromConnectionString creates an instance of Client with the specified values.

  • connectionString - a connection string for the desired storage account
  • options - client options; pass nil to accept the default values

func NewClientWithNoCredential added in v0.5.0

func NewClientWithNoCredential(serviceURL string, options *ClientOptions) (*Client, error)

NewClientWithNoCredential creates an instance of Client with the specified values. This is used to anonymously access a storage account or with a shared access signature (SAS) token.

  • serviceURL - the URL of the storage account e.g. https://<account>.blob.core.windows.net/?<sas token>
  • options - client options; pass nil to accept the default values

func NewClientWithSharedKeyCredential added in v0.5.0

func NewClientWithSharedKeyCredential(serviceURL string, cred *SharedKeyCredential, options *ClientOptions) (*Client, error)

NewClientWithSharedKeyCredential creates an instance of Client with the specified values.

  • serviceURL - the URL of the storage account e.g. https://<account>.blob.core.windows.net/
  • cred - a SharedKeyCredential created with the matching storage account and access key
  • options - client options; pass nil to accept the default values

func (*Client) CreateContainer added in v0.5.0

func (c *Client) CreateContainer(ctx context.Context, containerName string, o *CreateContainerOptions) (CreateContainerResponse, error)

CreateContainer is a lifecycle method to creates a new container under the specified account. If the container with the same name already exists, a ResourceExistsError will be raised. This method returns a client with which to interact with the newly created container.

func (*Client) DeleteBlob added in v0.5.0

func (c *Client) DeleteBlob(ctx context.Context, containerName string, blobName string, o *DeleteBlobOptions) (DeleteBlobResponse, error)

DeleteBlob marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. Note that deleting a blob also deletes all its snapshots. For more information, see https://docs.microsoft.com/rest/api/storageservices/delete-blob.

func (*Client) DeleteContainer added in v0.5.0

func (c *Client) DeleteContainer(ctx context.Context, containerName string, o *DeleteContainerOptions) (DeleteContainerResponse, error)

DeleteContainer is a lifecycle method that marks the specified container for deletion. The container and any blobs contained within it are later deleted during garbage collection. If the container is not found, a ResourceNotFoundError will be raised.

func (*Client) DownloadBuffer added in v0.5.0

func (c *Client) DownloadBuffer(ctx context.Context, containerName string, blobName string, buffer []byte, o *DownloadBufferOptions) (int64, error)

DownloadBuffer downloads an Azure blob to a buffer with parallel.

func (*Client) DownloadFile added in v0.5.0

func (c *Client) DownloadFile(ctx context.Context, containerName string, blobName string, file *os.File, o *DownloadFileOptions) (int64, error)

DownloadFile downloads an Azure blob to a local file. The file would be truncated if the size doesn't match.

func (*Client) DownloadStream added in v0.5.0

func (c *Client) DownloadStream(ctx context.Context, containerName string, blobName string, o *DownloadStreamOptions) (DownloadStreamResponse, error)

DownloadStream reads a range of bytes from a blob. The response also includes the blob's properties and metadata. For more information, see https://docs.microsoft.com/rest/api/storageservices/get-blob.

func (*Client) NewListBlobsFlatPager added in v0.5.0

func (c *Client) NewListBlobsFlatPager(containerName string, o *ListBlobsFlatOptions) *runtime.Pager[ListBlobsFlatResponse]

NewListBlobsFlatPager returns a pager for blobs starting from the specified Marker. Use an empty Marker to start enumeration from the beginning. Blob names are returned in lexicographic order. For more information, see https://docs.microsoft.com/rest/api/storageservices/list-blobs.

func (*Client) NewListContainersPager added in v0.5.0

func (c *Client) NewListContainersPager(o *ListContainersOptions) *runtime.Pager[ListContainersResponse]

NewListContainersPager operation returns a pager of the containers under the specified account. Use an empty Marker to start enumeration from the beginning. Container names are returned in lexicographic order. For more information, see https://docs.microsoft.com/rest/api/storageservices/list-containers2.

func (*Client) ServiceClient added in v0.6.0

func (c *Client) ServiceClient() *service.Client

ServiceClient returns the embedded service client for this client.

func (*Client) URL added in v0.5.0

func (c *Client) URL() string

URL returns the URL endpoint used by the BlobClient object.

func (*Client) UploadBuffer added in v0.5.0

func (c *Client) UploadBuffer(ctx context.Context, containerName string, blobName string, buffer []byte, o *UploadBufferOptions) (UploadBufferResponse, error)

UploadBuffer uploads a buffer in blocks to a block blob.

func (*Client) UploadFile added in v0.5.0

func (c *Client) UploadFile(ctx context.Context, containerName string, blobName string, file *os.File, o *UploadFileOptions) (UploadFileResponse, error)

UploadFile uploads a file in blocks to a block blob.

func (*Client) UploadStream added in v0.5.0

func (c *Client) UploadStream(ctx context.Context, containerName string, blobName string, body io.Reader, o *UploadStreamOptions) (UploadStreamResponse, error)

UploadStream copies the file held in io.Reader to the Blob at blockBlobClient. A Context deadline or cancellation will cause this to error.

type ClientOptions

type ClientOptions base.ClientOptions

ClientOptions contains the optional parameters when creating a Client.

type CreateContainerOptions

type CreateContainerOptions = service.CreateContainerOptions

CreateContainerOptions contains the optional parameters for the ContainerClient.Create method.

type CreateContainerResponse added in v0.5.0

type CreateContainerResponse = service.CreateContainerResponse

CreateContainerResponse contains the response from method container.Client.Create.

type DeleteBlobOptions

type DeleteBlobOptions = blob.DeleteOptions

DeleteBlobOptions contains the optional parameters for the Client.Delete method.

type DeleteBlobResponse added in v0.5.0

type DeleteBlobResponse = blob.DeleteResponse

DeleteBlobResponse contains the response from method blob.Client.Delete.

type DeleteContainerOptions

type DeleteContainerOptions = service.DeleteContainerOptions

DeleteContainerOptions contains the optional parameters for the container.Client.Delete method.

type DeleteContainerResponse added in v0.5.0

type DeleteContainerResponse = service.DeleteContainerResponse

DeleteContainerResponse contains the response from method container.Client.Delete

type DeleteSnapshotsOptionType

type DeleteSnapshotsOptionType = generated.DeleteSnapshotsOptionType

DeleteSnapshotsOptionType defines values for DeleteSnapshotsOptionType.

func PossibleDeleteSnapshotsOptionTypeValues

func PossibleDeleteSnapshotsOptionTypeValues() []DeleteSnapshotsOptionType

PossibleDeleteSnapshotsOptionTypeValues returns the possible values for the DeleteSnapshotsOptionType const type.

type DownloadBufferOptions added in v0.5.0

type DownloadBufferOptions = blob.DownloadBufferOptions

DownloadBufferOptions identifies options used by the DownloadBuffer and DownloadFile functions.

type DownloadFileOptions added in v0.5.0

type DownloadFileOptions = blob.DownloadFileOptions

DownloadFileOptions identifies options used by the DownloadBuffer and DownloadFile functions.

type DownloadStreamOptions added in v0.5.0

type DownloadStreamOptions = blob.DownloadStreamOptions

DownloadStreamOptions contains the optional parameters for the Client.DownloadStream method.

type DownloadStreamResponse added in v0.5.0

type DownloadStreamResponse = blob.DownloadStreamResponse

DownloadStreamResponse wraps AutoRest generated BlobDownloadResponse and helps to provide info for retry.

type HTTPRange added in v0.5.0

type HTTPRange = exported.HTTPRange

HTTPRange defines a range of bytes within an HTTP resource, starting at offset and ending at offset+count. A zero-value HTTPRange indicates the entire resource. An HTTPRange which has an offset and zero value count indicates from the offset to the resource's end.

type ListBlobsFlatOptions added in v0.5.0

type ListBlobsFlatOptions = container.ListBlobsFlatOptions

ListBlobsFlatOptions contains the optional parameters for the container.Client.ListBlobFlatSegment method.

type ListBlobsFlatResponse added in v0.5.0

type ListBlobsFlatResponse = container.ListBlobsFlatResponse

ListBlobsFlatResponse contains the response from method container.Client.ListBlobFlatSegment.

type ListBlobsFlatSegmentResponse

type ListBlobsFlatSegmentResponse = generated.ListBlobsFlatSegmentResponse

ListBlobsFlatSegmentResponse - An enumeration of blobs

type ListBlobsInclude added in v0.5.0

type ListBlobsInclude = container.ListBlobsInclude

ListBlobsInclude indicates what additional information the service should return with each blob.

type ListContainersInclude added in v0.5.0

type ListContainersInclude = service.ListContainersInclude

ListContainersInclude indicates what additional information the service should return with each container.

type ListContainersOptions

type ListContainersOptions = service.ListContainersOptions

ListContainersOptions contains the optional parameters for the container.Client.ListContainers operation

type ListContainersResponse added in v0.5.0

type ListContainersResponse = service.ListContainersResponse

ListContainersResponse contains the response from method service.Client.ListContainersSegment.

type ListContainersSegmentResponse

type ListContainersSegmentResponse = generated.ListContainersSegmentResponse

ListContainersSegmentResponse - An enumeration of containers

type ObjectReplicationPolicy

type ObjectReplicationPolicy = blob.ObjectReplicationPolicy

ObjectReplicationPolicy are deserialized attributes

type PublicAccessType

type PublicAccessType = generated.PublicAccessType

PublicAccessType defines values for AccessType - private (default) or blob or container.

const (
	PublicAccessTypeBlob      PublicAccessType = generated.PublicAccessTypeBlob
	PublicAccessTypeContainer PublicAccessType = generated.PublicAccessTypeContainer
)

func PossiblePublicAccessTypeValues

func PossiblePublicAccessTypeValues() []PublicAccessType

PossiblePublicAccessTypeValues returns the possible values for the PublicAccessType const type.

type RetryReaderOptions

type RetryReaderOptions = blob.RetryReaderOptions

RetryReaderOptions contains properties which can help to decide when to do retry.

type SharedKeyCredential

type SharedKeyCredential = exported.SharedKeyCredential

SharedKeyCredential contains an account's name and its primary or secondary key.

func NewSharedKeyCredential

func NewSharedKeyCredential(accountName, accountKey string) (*SharedKeyCredential, error)

NewSharedKeyCredential creates an immutable SharedKeyCredential containing the storage account's name and either its primary or secondary key.

type URLParts added in v0.5.0

type URLParts = sas.URLParts

URLParts object represents the components that make up an Azure Storage Container/Blob URL. NOTE: Changing any SAS-related field requires computing a new SAS signature.

func ParseURL added in v0.5.0

func ParseURL(u string) (URLParts, error)

ParseURL parses a URL initializing URLParts' fields including any SAS-related & snapshot query parameters. Any other query parameters remain in the UnparsedParams field. This method overwrites all fields in the URLParts object.

type UploadBufferOptions added in v0.5.0

type UploadBufferOptions = blockblob.UploadBufferOptions

UploadBufferOptions provides set of configurations for UploadBuffer operation

type UploadBufferResponse added in v0.5.0

type UploadBufferResponse = blockblob.UploadBufferResponse

UploadBufferResponse contains the response from method Client.UploadBuffer/Client.UploadFile.

type UploadFileOptions added in v0.5.0

type UploadFileOptions = blockblob.UploadFileOptions

UploadFileOptions provides set of configurations for UploadFile operation

type UploadFileResponse added in v0.5.0

type UploadFileResponse = blockblob.UploadFileResponse

UploadFileResponse contains the response from method Client.UploadBuffer/Client.UploadFile.

type UploadResponse added in v0.5.0

type UploadResponse = blockblob.CommitBlockListResponse

UploadResponse contains the response from method blockblob.Client.CommitBlockList.

type UploadStreamOptions added in v0.4.0

type UploadStreamOptions = blockblob.UploadStreamOptions

UploadStreamOptions provides set of configurations for UploadStream operation

type UploadStreamResponse added in v0.5.0

type UploadStreamResponse = blockblob.CommitBlockListResponse

UploadStreamResponse contains the response from method Client.CommitBlockList.

Directories

Path Synopsis
internal
testcommon
Contains common helpers for TESTS ONLY
Contains common helpers for TESTS ONLY

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL