{"id":16520361,"url":"https://github.com/benbusby/b2","last_synced_at":"2025-10-28T07:31:42.963Z","repository":{"id":187073978,"uuid":"663115024","full_name":"benbusby/b2","owner":"benbusby","description":"Go library for the Backblaze B2 Cloud Storage API","archived":false,"fork":false,"pushed_at":"2024-09-25T19:07:40.000Z","size":156,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-01T12:45:31.802Z","etag":null,"topics":["backblaze","backblaze-api","backblaze-b2","go","golang","s3"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benbusby.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-07-06T15:25:56.000Z","updated_at":"2025-01-26T03:18:26.000Z","dependencies_parsed_at":"2024-01-19T21:38:06.053Z","dependency_job_id":"41c6e336-e39b-4735-ac98-8c2a73930ede","html_url":"https://github.com/benbusby/b2","commit_stats":null,"previous_names":["benbusby/b2"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbusby%2Fb2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbusby%2Fb2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbusby%2Fb2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benbusby%2Fb2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benbusby","download_url":"https://codeload.github.com/benbusby/b2/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238614580,"owners_count":19501484,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backblaze","backblaze-api","backblaze-b2","go","golang","s3"],"created_at":"2024-10-11T16:50:35.816Z","updated_at":"2025-10-28T07:31:37.576Z","avatar_url":"https://github.com/benbusby.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# b2\n[![Tests](https://github.com/benbusby/b2/actions/workflows/tests.yml/badge.svg)](https://github.com/benbusby/b2/actions/workflows/tests.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/benbusby/b2)](https://goreportcard.com/report/github.com/benbusby/b2)\n\nA Go library for the [Backblaze B2 Cloud Storage\n](https://www.backblaze.com/b2/cloud-storage.html) API.\n\n## Contents\n\n1. [API Support](#api-support)\n2. [Install](#install)\n3. [Setup](#setup)\n4. [Usage](#usage)\n   1. [Authentication](#authentication)\n   2. [Upload File](#upload-file)\n   3. [Upload Large File](#upload-large-file)\n   4. [Download File](#download-file)\n   5. [Delete a File](#delete-a-file)\n   6. [List Files](#list-files)\n\n## API Support\n\nThe following API endpoints and functionality are currently supported:\n\n- Authentication\n  - `b2_authorize_account`\n- Uploading a file\n  - `b2_get_upload_url`\n  - `b2_upload_file`\n- Uploading a large file (multi-part upload)\n  - `b2_start_large_file`\n  - `b2_get_upload_part_url`\n  - `b2_upload_part`\n  - `b2_finish_large_file`\n  - `b2_cancel_large_file`\n- Downloading a file\n  - `b2_download_file_by_id`\n- Deleting a file\n  - `b2_delete_file_version`\n \nThe project is being actively developed, and more functionality will likely\nbe added in the near future. Existing functionality is unlikely to change\nand should be considered stable.\n\n## Install\n\n`go get github.com/benbusby/b2`\n\n## Setup\n\nTo use this library with B2, create an account on backblaze.com, create \na new bucket (or use an existing one) and follow the following steps to \ncreate an Application Key:\n\n1. Select `Account \u003e Application Keys \u003e Add New Application Key`\n2. Name the key and select which bucket the key should have access to\n3. Save the `keyID` and `applicationKey` values\n\n### Local Storage Only\n\nIf you just want to use the library functions to write files to your machine\nfor testing, you can skip creating a Backblaze account and just use one of\nthe \"dummy\" authentication methods outlined below in [Authentication](#authentication).\n\n## Usage\n\n### Authentication\n\nYou can authenticate with Backblaze B2 using `b2.AuthorizeAccount(keyID, key)`,\nwhere `keyID` is either an application or master key ID, and `key` is the\nactual key contents. `b2.AuthorizeAccount` returns a `b2.Auth` struct:\n\n```go\ntype Auth struct {\n\tAbsoluteMinimumPartSize int    `json:\"absoluteMinimumPartSize\"`\n\tAccountID               string `json:\"accountId\"`\n\tAllowed                 struct {\n\t\tBucketID     string   `json:\"bucketId\"`\n\t\tBucketName   string   `json:\"bucketName\"`\n\t\tCapabilities []string `json:\"capabilities\"`\n\t\tNamePrefix   any      `json:\"namePrefix\"`\n\t} `json:\"allowed\"`\n\tAPIURL              string `json:\"apiUrl\"`\n\tAuthorizationToken  string `json:\"authorizationToken\"`\n\tDownloadURL         string `json:\"downloadUrl\"`\n\tRecommendedPartSize int    `json:\"recommendedPartSize\"`\n\tS3APIURL            string `json:\"s3ApiUrl\"`\n}\n```\n\nMost B2 functions have a receiver type of `Auth` and will use the\n`AuthorizationToken` field to authenticate requests.\n\n___\n\n#### Functions\n\n```go\nfunc AuthorizeAccount(\n\tb2BucketKeyId string,\n\tb2BucketKey string,\n) (Service, AuthV2, error)\n\nfunc AuthorizeAccountV2(\n    b2BucketKeyId string,\n    b2BucketKey string,\n) (Service, AuthV3, error)\n\nfunc AuthorizeDummyAccount(\n\tpath string,\n) (Service, error)\n\nfunc AuthorizeLimitedDummyAccount(\n\tpath string,\n\tstorageLimit int,\n) (Service, error)\n```\n\n___\n\n#### Example\n\n```go\n# Authenticate with B2\nb2, err := b2.AuthorizeAccount(\n\tos.Getenv(\"B2_BUCKET_KEY_ID\"),\n\tos.Getenv(\"B2_BUCKET_KEY\"))\n\n# Create dummy authentication\nb2, err := b2.AuthorizeDummyAccount(\"/tmp\")\n\n# Create dummy authentication w/ 1GB storage limit\nb2, err := b2.AuthorizeLimitedDummyAccount(\"local-bucket\", 1024*1024*1024)\n```\n\n### Upload File\n\nUploading a regular (non-chunked) file involves fetching the upload\nparameters first (unique upload URL, token, etc), and then sending\nyour file data, a SHA-1 checksum for the data, and the file name.\n\nNote that although the endpoint for retrieving upload data is named\n`b2_get_upload_url`, the returned struct contains more than just a\nURL. Most importantly, it contains the required auth token for actually\nuploading the file.\n\nAfter uploading, you'll receive a struct with fields such as `FileID` that\nyou can use to access or delete the file later.\n\n___\n\n#### Functions\n\nGet upload URL:\n```go\nfunc (b2Service *Service) GetUploadURL() (FileInfo, error)\n```\n\nUpload file:\n```go\nfunc (b2Info FileInfo) UploadFile(\n\tfilename string,\n\tchecksum string,\n\tcontents []byte,\n) (File, error)\n```\n\n___\n\n#### Example\n\n```go\nb2, _ := b2.AuthorizeAccount(\n\tos.Getenv(\"B2_BUCKET_KEY_ID\"),\n\tos.Getenv(\"B2_BUCKET_KEY\"))\n\nb2Uploader, _ := b2.GetUploadURL()\n\ndata := []byte(\"test\")\n\nh := sha1.New()\nh.Write(data)\nchecksum := fmt.Sprintf(\"%x\", h.Sum(nil))\n\nfile, err := b2Uploader.UploadFile(\n\t\"myfile.txt\",\n\tchecksum,\n\tdata)\n\n// save/store `file.FileID` somewhere in order to access it later\n```\n\n### Upload Large File\n\nUploading a large file requires extra steps to \"start\" and \"stop\" uploading,\nwhich will depend on how many chunks of data you're sending. Each chunk of\nfile data needs to be at least 5mb, except for the final chunk. You cannot use\nthe large file upload process to upload files \u003c5mb.\n\nThe basic flow of uploading a large file is:\n\n1. Start the file\n2. Get the upload info for a chunk\n3. Upload the chunks of data until finished\n4. Stop the file\n\nYou'll also need to track each checksum as you upload data, since finishing a\nlarge file requires an array of past checksums to finalize the upload.\n\nThe finalized large file struct, like the normal B2 file struct, contains metadata\nthat you may want in order to access the file later.\n\n___\n\n#### Function(s)\n\nStart large file:\n```go\nfunc (b2Service *Service) StartLargeFile(filename string) (StartFile, error)\n```\n\nGet upload part URL:\n```go\nfunc (b2Service *Service) GetUploadPartURL(b2File StartFile) (FilePartInfo, error)\n```\n\nUpload file part:\n```go\nfunc (b2PartInfo FilePartInfo) UploadFilePart(\n\tchunkNum int,\n\tchecksum string,\n\tcontents []byte,\n) error\n```\n\nFinish large file:\n```go\nfunc (b2Service *Service) FinishLargeFile(\n\tfileID string,\n\tchecksums []string,\n) (LargeFile, error)\n```\n\nCancel large file:\n```go\nfunc (b2Service *Service) CancelLargeFile(fileID string) (bool, error)\n```\n\n___\n\n#### Example\n\n```go\ndataSize := 10485760\nchunkSize := 5242880\n\ndata := make([]byte, dataSize) // empty, only for example\nvar checksums []string\n\nb2, _ := b2.AuthorizeAccount(\n\tos.Getenv(\"B2_BUCKET_KEY_ID\"),\n\tos.Getenv(\"B2_BUCKET_KEY\"))\n\nb2InitFile, _ := b2.StartLargeFile(\"mybigfile.mp4\")\nb2PartUploader, _ := b2.GetUploadPartURL(b2InitFile)\n\nfor i := 0; i \u003c dataSize; i++ {\n\tstart := i * chunkSize\n\tstop := i * chunkSize + chunkSize\n\tchunk := data[start:stop]\n\n\th := sha1.New()\n\th.Write(data)\n\tchecksum := fmt.Sprintf(\"%x\", h.Sum(nil))\n\tchecksums = append(checksums, checksum)\n\n\t// B2 chunk numbering starts at 1, not 0\n\terr := info.UploadFilePart(i+1, checksum, chunk)\n\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\nerr = b2.FinishLargeFile(b2PartUploader.FileID, checksums)\nif err != nil {\n\tpanic(err)\n}\n```\n\n### Download File\n\nDownloading a file can either be done in one request (likely only\nfeasible for smaller files) or chunked, similar to how large files\nare uploaded but in reverse.\n\n___\n\n#### Functions\n\nMulti-part download:\n```go\nfunc (b2Service *Service) PartialDownloadById(\n\tid string,\n\tbegin int,\n\tend int,\n) ([]byte, error)\n```\n\nFull download:\n\n```go\nfunc (b2Service *Service) DownloadById(id string) ([]byte, error)\n```\n\n___\n\n#### Example (single request)\n\n```go\nb2, _ := b2.AuthorizeAccount(\n\tos.Getenv(\"B2_BUCKET_KEY_ID\"),\n\tos.Getenv(\"B2_BUCKET_KEY\"))\n\nid := getB2FileID() // value from UploadFile or FinishLargeFile\n\ndata, err := b2.DownloadById(id)\n\n// do something with the file data\n```\n\n#### Example (multi request)\n\n```go\nb2, _ := b2.AuthorizeAccount(\n\tos.Getenv(\"B2_BUCKET_KEY_ID\"),\n\tos.Getenv(\"B2_BUCKET_KEY\"))\n\nid := getB2FileID() // value from UploadFile or FinishLargeFile\nfileSize := getB2FileSize() // same note as above\n\nchunkSize := 5242880\ni := 0\nvar output []byte\n\nfor i \u003c fileSize {\n\tstart := i * chunkSize\n\tstop := i * chunkSize + chunkSize\n\tdata, _ := auth.PartialDownloadById(id, start, stop)\n\toutput = append(output, data...)\n}\n\n// do something with output (full file data)\n```\n\n### Delete a File\n\nDeleting a file requires both the file's ID, and the file's name. Both\nof these are returned in the final struct when uploading a file and\nshould be stored somewhere if you want to delete the file later on.\n\n___\n\n#### Function\n\n```go\nfunc (b2Service *Service) DeleteFile(b2ID string, name string) bool\n```\n___\n\n#### Example\n\n```go\nb2, _ := b2.AuthorizeAccount(\n\tos.Getenv(\"B2_BUCKET_KEY_ID\"),\n\tos.Getenv(\"B2_BUCKET_KEY\"))\n\nid, name := getB2FileInfo()\n\nif b2.DeleteFile(id, name) {\n\tfmt.Println(\"File successfully deleted\")\n} else {\n\treturn errors.New(\"failed to delete file\")\n}\n```\n\n### List Files\n\nListing files requires the bucket ID that you're wanting to query, and\ncan accept a few optional parameters for filtering.\n\n___\n\n#### Functions\n\n```go\nfunc (b2Service *Service) ListAllFiles(bucketID string) (FileList, error)\n\nfunc (b2Service *Service) ListNFiles(bucketID string, count int) (FileList, error)\n\nfunc (b2Service *Service) ListFiles(\n\tbucketID string,\n\tcount int,\n\tstartName string,\n\tstartID string,\n) (FileList, error)\n```\n\n___\n\n#### Example\n\n```go\nfiles, _ := b2.ListAllFiles(bucketID)\n\nfor _, file := range files.Files {\n    // do something with `file`\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenbusby%2Fb2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenbusby%2Fb2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenbusby%2Fb2/lists"}