追加アップロードを使用すると、既存の追加可能オブジェクトの末尾にデータを追加できます。このトピックでは、OSS SDK for Python V2 を使用して追加アップロードを実行する方法について説明します。
注意事項
このトピックのサンプルコードでは、リージョン ID が
cn-hangzhouの中国 (杭州) リージョンを例として使用しています。デフォルトでは、パブリックエンドポイントが使用されます。OSS と同じリージョンにある他の Alibaba Cloud サービスから OSS にアクセスする場合は、内部エンドポイントを使用する必要があります。OSS リージョンとエンドポイント間のマッピングの詳細については、「OSS リージョンとエンドポイント」をご参照ください。オブジェクトが存在しない場合、追加アップロードメソッドを呼び出すと、追加可能オブジェクトが作成されます。
オブジェクトが存在する場合:
オブジェクトが追加可能オブジェクトであり、指定された追加位置がオブジェクトの現在の長さと同じである場合、コンテンツはオブジェクトの末尾に追加されます。
オブジェクトが追加可能オブジェクトであるが、指定された追加位置がオブジェクトの現在の長さと同じでない場合、PositionNotEqualToLength 例外がスローされます。
オブジェクトが追加可能オブジェクトでない場合 (簡易アップロードを使用してアップロードされた通常のオブジェクトなど)、ObjectNotAppendable 例外がスローされます。
権限
デフォルトでは、Alibaba Cloud アカウントは完全な権限を持っています。Alibaba Cloud アカウント下の RAM ユーザーまたは RAM ロールは、デフォルトでは何の権限も持っていません。Alibaba Cloud アカウントまたはアカウント管理者は、RAM ポリシーまたはバケットポリシーを介して操作権限を付与する必要があります。
API | アクション | 定義 |
AppendObject |
| この操作を呼び出して、既存のオブジェクトにオブジェクトを追加することでオブジェクトをアップロードできます。 |
| 既存のオブジェクトにオブジェクトを追加してオブジェクトをアップロードするときに、x-oss-tagging を介してオブジェクトタグを指定する場合は、この権限が必要です。 |
メソッドの定義
追加アップロードのシナリオでは、Python SDK V2 は AppendFile メソッドを追加して、バケット内のオブジェクトに対するファイルの読み取りおよび書き込み操作をシミュレートします。次の表に、AppendFile メソッドと AppendObject メソッドを示します。
メソッド | 説明 |
AppendFile | AppendObject メソッドと同じ機能を提供します。 障害後の再送に対するフォールトトレランスを最適化します。 |
AppendObject | 追加アップロードを実行します。最終的なオブジェクトのサイズは最大 5 GiB です。 CRC-64 データ検証をサポートします (デフォルトで有効)。 進捗横棒グラフをサポートします。 |
AppendFile: Premium Edition の追加アップロード API
AppendFile メソッドを呼び出して、追加モードでデータをアップロードできます。オブジェクトが存在しない場合は、追加可能オブジェクトが作成されます。オブジェクトは存在するが追加可能オブジェクトではない場合、エラーが返されます。
次のコードは、AppendFile メソッドの定義を示しています。
append_file(bucket: str, key: str, request_payer: str | None = None, create_parameter: AppendObjectRequest | None = None, **kwargs) → AppendOnlyFileリクエストパラメーター
パラメーター | タイプ | 説明 |
bucket | str | バケットの名前。 |
key | str | オブジェクトの名前。 |
RequestPayer | str | リクエスト元支払いモードが有効になっている場合は、このパラメーターを 'requester' に設定します。 |
CreateParameter | AppendObjectRequest | 最初のアップロードで設定されるオブジェクトのメタデータ (ContentType、Metadata、権限、ストレージタイプなど)。詳細については、「AppendObjectRequest」をご参照ください。 |
戻り値
タイプ | 説明 |
AppendOnlyFile | 追加可能ファイルのインスタンス。詳細については、「AppendOnlyFile」をご参照ください。 |
次の表に、AppendOnlyFile クラスに含まれるメソッドを示します。
メソッド | 説明 |
Close() | ファイルハンドルを閉じてリソースを解放します。 |
write(b) | バイトデータをファイルに書き込み、書き込まれたバイト数を返します。 |
write_from(b: str | bytes | Iterable[bytes] | IO[str] | IO[bytes]) | 任意のデータをファイルに書き込み、書き込まれたバイト数を返します。 |
AppendFile メソッドの完全な定義については、「append_file」をご参照ください。
AppendObject: Basic Edition の追加アップロード API
append_object(request: AppendObjectRequest, **kwargs) → AppendObjectResultリクエストパラメーター
パラメーター | タイプ | 説明 |
request | AppendObjectRequest | リクエストパラメーター。詳細については、「AppendObjectRequest」をご参照ください。 |
戻り値
タイプ | 説明 |
AppendObjectResult | 戻り値。詳細については、「AppendObjectResult」をご参照ください。 |
AppendObject メソッドの完全な定義については、「append_object」をご参照ください。
例
(推奨) AppendFile を使用して追加アップロードを実行する
import argparse
import alibabacloud_oss_v2 as oss
# コマンドライン引数パーサーを作成し、スクリプトの目的を記述します: この例では、OSS オブジェクトにデータを追加する方法を示します。
parser = argparse.ArgumentParser(description="append file sample")
# --region コマンドライン引数を追加します。これはバケットが配置されているリージョンを指定します。この引数は必須です。
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# --bucket コマンドライン引数を追加します。これは操作対象のバケットの名前を指定します。この引数は必須です。
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# --endpoint コマンドライン引数を追加します。これは他のサービスが OSS にアクセスするために使用できるドメイン名を指定します。この引数はオプションです。
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# --key コマンドライン引数を追加します。これは OSS 内のオブジェクト (ファイル) のキーを指定します。この引数は必須です。
parser.add_argument('--key', help='The name of the object.', required=True)
def main():
# コマンドライン引数を解析して、ユーザーが指定した値を取得します。
args = parser.parse_args()
# ID 検証のために、環境変数から OSS へのアクセスに必要な認証情報を読み込みます。
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# SDK のデフォルト構成を使用して構成オブジェクトを作成し、認証情報プロバイダーを設定します。
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
cfg.region = args.region
# カスタムエンドポイントが指定されている場合は、構成オブジェクトのエンドポイントプロパティを更新します。
if args.endpoint is not None:
cfg.endpoint = args.endpoint
# OSS との対話の準備として、前述の構成で OSS クライアントを初期化します。
client = oss.Client(cfg)
# 追加するデータを定義します。
data1 = b'hello'
data2 = b' world. '
# データを初めて追加します。
with client.append_file(bucket=args.bucket, key=args.key) as f:
append_f = f
f.write(data1)
# 最初の追加操作後のファイルステータスを出力します。
print(f'closed: {append_f.closed},'
f' name: {append_f.name}'
)
# データを 2 回目に追加します。
with client.append_file(bucket=args.bucket, key=args.key) as f:
append_f = f
f.write(data2)
# 2 回目の追加操作後のファイルステータスを出力します。
print(f'closed: {append_f.closed},'
f' name: {append_f.name}'
)
# データを追加した後のオブジェクトのコンテンツを取得します。
result = client.get_object(oss.GetObjectRequest(
bucket=args.bucket,
key=args.key,
))
# オブジェクト取得の結果を出力します。
print(f'status code: {result.status_code},'
f' request id: {result.request_id},'
f' content: {result.body.content.decode("utf-8")}'
)
# このスクリプトが直接実行されるときに、main 関数を呼び出して処理ロジックを開始します。
if __name__ == "__main__":
main() # スクリプトのエントリポイント。ここからプログラムのフローが開始されます。AppendObject を使用して追加アップロードを実行する
import argparse
import alibabacloud_oss_v2 as oss
# コマンドライン引数パーサーを作成します。
parser = argparse.ArgumentParser(description="append object sample")
# コマンドライン引数を追加します。
# --region: OSS バケットが配置されているリージョンを指定します。
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# --bucket: 操作対象のバケットの名前を指定します。
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# --endpoint: OSS サービスへのアクセスに使用されるドメイン名を指定するオプションのパラメーター。
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# --key: OSS 内のオブジェクト (ファイル) のキーを指定します。
parser.add_argument('--key', help='The name of the object.', required=True)
def main():
# コマンドライン引数を解析します。
args = parser.parse_args()
# 環境変数から OSS に必要な認証情報を読み込みます。
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# SDK が提供するデフォルト構成を使用して構成オブジェクトを作成します。
cfg = oss.config.load_default()
# 認証情報プロバイダーを、以前に作成したオブジェクトに設定します。
cfg.credentials_provider = credentials_provider
# ユーザーの入力に基づいて OSS クライアントのリージョンを設定します。
cfg.region = args.region
# ユーザーがカスタムエンドポイントを指定した場合は、構成を更新します。
if args.endpoint is not None:
cfg.endpoint = args.endpoint
# 前述の構成を使用して OSS クライアントインスタンスを作成します。
client = oss.Client(cfg)
# 追加するデータを定義します。
data1 = b'hello'
data2 = b' world'
# データを初めて追加します。
result = client.append_object(oss.AppendObjectRequest(
bucket=args.bucket, # 宛先バケットを指定します。
key=args.key, # オブジェクトのキーを指定します。
position=0, # 追加の開始位置。最初は 0 です。
body=data1, # 追加するデータ。
))
# 最初の追加操作の結果を出力します。
print(f'status code: {result.status_code},'
f' request id: {result.request_id},'
f' version id: {result.version_id},'
f' hash crc64: {result.hash_crc64},'
f' next position: {result.next_position},'
)
# データを 2 回目に追加します。
result = client.append_object(oss.AppendObjectRequest(
bucket=args.bucket, # 宛先バケットを指定します。
key=args.key, # オブジェクトのキーを指定します。
position=result.next_position, # 前回の追加操作の次の位置から開始します。
body=data2, # 追加するデータ。
))
# 2 回目の追加操作の結果を出力します。
print(f'status code: {result.status_code},'
f' request id: {result.request_id},'
f' version id: {result.version_id},'
f' hash crc64: {result.hash_crc64},'
f' next position: {result.next_position},'
)
# このスクリプトが直接実行されるときに、main 関数を呼び出します。
if __name__ == "__main__":
main()シナリオ
追加アップロードの進捗バーを表示する
import argparse
import alibabacloud_oss_v2 as oss
# コマンドライン引数パーサーを作成します。
parser = argparse.ArgumentParser(description="append object sample")
# コマンドライン引数を追加します。
# --region: OSS バケットが配置されているリージョンを指定します。
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# --bucket: 操作対象のバケットの名前を指定します。
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# --endpoint: OSS サービスへのアクセスに使用されるドメイン名を指定するオプションのパラメーター。
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# --key: OSS 内のオブジェクト (ファイル) のキーを指定します。
parser.add_argument('--key', help='The name of the object.', required=True)
def main():
# コマンドライン引数を解析します。
args = parser.parse_args()
# 環境変数から OSS に必要な認証情報を読み込みます。
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# SDK が提供するデフォルト構成を使用して構成オブジェクトを作成します。
cfg = oss.config.load_default()
# 認証情報プロバイダーを、以前に作成したオブジェクトに設定します。
cfg.credentials_provider = credentials_provider
# ユーザーの入力に基づいて OSS クライアントのリージョンを設定します。
cfg.region = args.region
# ユーザーがカスタムエンドポイントを指定した場合は、構成を更新します。
if args.endpoint is not None:
cfg.endpoint = args.endpoint
# 前述の構成を使用して OSS クライアントインスタンスを作成します。
client = oss.Client(cfg)
# progress_state という名前の辞書変数を定義して、アップロードの進捗状況を保存します。初期値は 0 です。
progress_state = {'saved': 0}
def _progress_fn(n, written, total):
# グローバル変数を使用しないように、書き込まれたバイトの累積数を保存するために辞書を使用します。
progress_state['saved'] += n
# 現在のアップロード率を計算します。値は、書き込まれたバイト数を合計バイト数で除算し、結果を切り捨てることによって取得されます。
rate = int(100 * (float(written) / float(total)))
# 現在のアップロードの進捗状況を出力します。\r は行の先頭に戻ることを示し、コマンドラインでリアルタイムの更新を実装します。
# end='' は改行がないことを示し、次の出力が現在の行を上書きするようにします。
print(f'\rUpload progress: {rate}% ', end='')
# 追加するデータを定義します。
data1 = b'hello'
data2 = b' world'
# データを初めて追加します。
result = client.append_object(oss.AppendObjectRequest(
bucket=args.bucket, # 宛先バケットを指定します。
key=args.key, # オブジェクトのキーを指定します。
position=0, # 追加の開始位置。最初は 0 です。
body=data1, # 追加するデータ。
progress_fn=_progress_fn, # 進捗コールバック関数を設定します。
))
# 最初の追加操作の結果を出力します。
print(f'status code: {result.status_code},'
f' request id: {result.request_id},'
f' version id: {result.version_id},'
f' hash crc64: {result.hash_crc64},'
f' next position: {result.next_position},'
)
# データを 2 回目に追加します。
result = client.append_object(oss.AppendObjectRequest(
bucket=args.bucket, # 宛先バケットを指定します。
key=args.key, # オブジェクトのキーを指定します。
position=result.next_position, # 前回の追加操作の次の位置から開始します。
body=data2, # 追加するデータ。
progress_fn=_progress_fn, # 進捗コールバック関数を設定します。
))
# 2 回目の追加操作の結果を出力します。
print(f'status code: {result.status_code},'
f' request id: {result.request_id},'
f' version id: {result.version_id},'
f' hash crc64: {result.hash_crc64},'
f' next position: {result.next_position},'
)
# このスクリプトが直接実行されるときに、main 関数を呼び出します。
if __name__ == "__main__":
main()リファレンス
追加アップロードの完全なサンプルコードについては、「append_file.py」および「append_object.py」をご参照ください。