Backblaze B2 Python SDK

repository·master·Indexed 42 days ago

https://github.com/backblaze/b2-sdk-python

A client library providing programmatic access to Backblaze B2 Cloud Storage capabilities. The SDK (b2sdk) allows developers to build applications such as FUSE filesystems and storage backend drivers, featuring advanced object creation methods like b2sdk.v3.Bucket.create_file and b2sdk.v3.Bucket.concatenate for synthesizing files from local and remote sources.

Tokens
18.1K
Snippets
49
Records
98
Agent score
53%

What's inside Backblaze B2 Python SDK

  1. Overview of b2sdk

    master

    b2sdk is a client library designed for easy access to the full capabilities of Backblaze B2 Cloud Storage. It is a mature and stable library used for various applications, including building command-line tools, FUSE filesystems, and storage backend drivers for backup applications.

    Key features include:

    • Synchronizer: A high-performance, parallel rsync-like utility for data synchronization.
    • raw_simulator: Allows you to mock the B2 cloud for unit testing purposes.
    • Resilience: Automatically continues interrupted transfers.
    • Progress Reporting: Supports reporting the progress of operations to custom objects.
    • Error Handling: Provides a structured exception hierarchy for informative user messaging.
    • Stability: Follows a semantic versioning policy to prevent incompatible changes from breaking your application.
  2. Understand b2sdk interface versions and imports

    master

    The SDK uses versioned import paths (e.g., from b2sdk.v3 import ...) to allow the interface to evolve without breaking existing applications. When new versions are released, b2sdk provides wrapper functions that match old signatures, allowing legacy code to continue working.

    Note that while the interface is fluid, some legacy functions may be removed between major versions (e.g., moving from .v0 to .v1), requiring developers to update their imports to the equivalent new wrappers.

  3. Understand B2 storage concepts: Buckets and Parts

    master

    When working with B2 Cloud Storage, keep the following structural concepts in mind:

    • bucket: A top-level container that holds files. You can have up to 100 buckets per account.
    • absoluteMinimumPartSize: The smallest allowable size for a part of a large file. This value is determined dynamically by the server during the authorization process (historically 5MB, but it can vary).
  4. Compare B2 object creation methods

    master

    The B2 server API allows creating new objects from existing ones (local or remote) to avoid unnecessary data transfers. The b2sdk provides several methods to achieve this, with varying support for range overlaps, streaming, and continuation. Use the following capability matrix to choose the right method for your use case:

    MethodSourceRangeOverlapStreamingContinuation
    b2sdk.v3.Bucket.uploadlocalnonoautomatic
    b2sdk.v3.Bucket.copyremotenonoautomatic
    b2sdk.v3.Bucket.concatenateanynonoautomatic
    b2sdk.v3.Bucket.concatenate_streamanynoyesmanual
    b2sdk.v3.Bucket.create_fileanyyesnoautomatic
    b2sdk.v3.Bucket.create_file_streamanyyesyesmanual
  5. Continue large file uploads and creations

    master

    The b2sdk supports continuing interrupted upload or creation sessions for large files. Continuation can be handled in two ways:

    1. Automatic Continuation

    For local-only input sources, b2sdk.v3.Bucket.create_file automatically attempts to find and resume an unfinished large file with the same file_name, file_info, and media type. It verifies checksums of uploaded parts against local sources to select the most complete valid candidate.

    For other input types (e.g., remote sources), the SDK uses 'plan information' stored in the file_info. It looks for an unfinished large file with matching plan info and verifies checksums. If checksum verification fails for all candidates, an error is raised; in this case, you should manually cancel the corrupted unfinished files and retry, or disable auto-continuation.

    2. Manual Continuation

    If automatic continuation is not available or you want to avoid ambiguity when multiple matching sessions exist, you can use the large_file_id. You can extract this ID via the large_file_callback during the initial operation and pass it into the subsequent call.

    Support Matrix:

    • b2sdk.v3.Bucket.create_file: Supports both automatic and manual continuation.
    • b2sdk.v3.Bucket.create_file_stream: Supports only manual continuation for local-only inputs.
    • b2sdk.v3.Bucket.concatenate and b2sdk.v3.Bucket.concatenate_stream: concatenate_stream supports only manual continuation of local sources.
    • b2sdk.v3.Bucket.upload and b2sdk.v3.Bucket.copy: Support both automatic and manual continuation.
    # Manual continuation example
    def large_file_callback(large_file):
        # Store the ID (e.g., in a database) to use later
        storage.store({'name': remote_name, 'large_file_id': large_file.id})
    
    # Initial attempt
    bucket.create_file(input_sources, remote_name, file_info, large_file_callback=large_file_callback)
    
    # ... later, to resume ...
    large_file_id = storage.query({'name': remote_name})[0]['large_file_id']
    bucket.create_file(input_sources, remote_name, file_info, large_file_id=large_file_id)
  6. Use EncryptionSettingsProvider with Sync operations

    master

    While standard read/write methods accept a single EncryptionSetting object, the Sync functionality requires an EncryptionSettingsProvider object.

    An EncryptionSettingsProvider acts as a factory that yields the appropriate EncryptionSetting for a file based on its metadata. To use encryption with Sync, you must implement an instance of b2sdk.v3.AbstractSyncEncryptionSettingsProvider that can map file metadata to the required encryption settings.

  7. Understand b2sdk versioning and interfaces

    master

    The SDK uses two types of versioning to manage compatibility:

    • b2sdk version: The semantic version of the library (e.g., v1.0.0 or 1.0.0).
    • b2sdk interface version: A version identifier (e.g., v3 or b2sdk.v3) used to maintain backward compatibility for the SDK's public interfaces.
  8. How synchronization works in b2sdk

    master

    Synchronization is the preferred method for moving data into and out of B2 because it parallelizes scanning and data transfer for high performance.

    To perform a sync, you use the Synchronizer class along with:

    • parse_folder(): To convert local paths or B2 URLs (e.g., b2://bucket-name) into folder objects.
    • ScanPoliciesManager: To define how files are scanned (e.g., exclude_all_symlinks=True).
    • SyncReport: To handle progress reporting and output.
    • EncryptionSettingsProvider: To map file metadata (like bucket_name) to specific EncryptionSettings.

    If you need to provide unique encryption keys on a per-file basis rather than per-bucket, you must implement your own AbstractSyncEncryptionSettingsProvider.

    from b2sdk.v3 import ScanPoliciesManager, parse_folder, Synchronizer, SyncReport, BasicSyncEncryptionSettingsProvider, EncryptionSettings, EncryptionMode, EncryptionKey
    import time
    import sys
    
    # Setup source and destination
    source = parse_folder('/home/user1/b2_example', b2_api)
    destination = parse_folder('b2://example-mybucket-b2', b2_api)
    
    # Configure scanning and synchronization
    policies_manager = ScanPoliciesManager(exclude_all_symlinks=True)
    synchronizer = Synchronizer(
        max_workers=10,
        policies_manager=policies_manager,
        dry_run=False,
        allow_empty_source=True,
    )
    
    # Define encryption mapping
    encryption_settings_provider = BasicSyncEncryptionSettingsProvider({
        'bucket1': EncryptionSettings(mode=EncryptionMode.SSE_B2),
        'bucket2': EncryptionSettings(
            mode=EncryptionMode.SSE_C,
            key=EncryptionKey(secret=b'VkYp3s6v9y$B&E)H@McQfTjWmZq4t7w!', id='user-generated-key-id')
        ),
        'bucket3': None,
    })
    
    # Execute sync
    with SyncReport(sys.stdout, no_progress=False) as reporter:
        synchronizer.sync_folders(
            source_folder=source,
            dest_folder=destination,
            now_millis=int(round(time.time() * 1000)),
            reporter=reporter,
            encryption_settings_provider=encryption_settings_provider,
        )
  9. Manage file locks and retention settings

    master

    The b2sdk.v3 module provides classes to manage file locks, legal holds, and retention settings for B2 buckets and files. These classes allow you to configure how long files are retained and whether they are subject to legal holds to prevent deletion.

    Key components include:

    • LegalHold: Represents the status of a legal hold on a file. It supports states like ON, OFF, UNSET, and UNKNOWN.
    • FileRetentionSetting and BucketRetentionSetting: Define the retention configuration for specific files or entire buckets.
    • RetentionMode: Defines the mode of retention.
    • RetentionPeriod: Defines the duration of the retention.
    • FileLockConfiguration: Encapsulates the full configuration for file locks.
  10. Expected changes in a numbered interface version

    master

    A specific numbered interface (like v3) is not guaranteed to be identical throughout its lifespan. Developers should design their code to tolerate the following changes:

    • Exceptions: The exception hierarchy may change in a backwards-compatible way. Best Practice: Use isinstance() and super() properly. Avoid calling parent class constructors by directly naming them, as this might skip intermediate classes in a changing hierarchy.
    • Extensions: Classes, enums, and objects may gain new fields (visible in as_dict() or __repr__). Methods may start accepting new optional arguments, and new methods may be added to existing classes.
    • Performance: While effort is made to maintain performance, some old interfaces may experience slight degradation in newer releases. If performance is critical, pin your dependency to a specific minor version (e.g., b2sdk>=X.Y.0,<X.Y+1.0).
  11. How b2sdk handles bucket name to ID mapping via caching

    master
    The b2sdk library automatically caches the mapping between bucket names and bucket IDs. This abstraction allows users to interact with buckets using their human-readable names without having to manually manage or look up the corresponding unique bucket IDs required by the underlying API.
  12. How high-level file objects work in B2

    master

    While low-level API methods require basic information like file IDs and names, the SDK provides high-level Python objects for manipulating file state: b2sdk.v3.FileVersion and b2sdk.v3.DownloadVersion.

    Key Behavior: Methods called on these objects typically do not modify the object itself in place; instead, they return a new object representing the updated state. This allows for a functional approach to managing file properties like legal holds and retention settings.