kopia lustrzana https://github.com/simonw/s3-credentials
put-object and get-object commands, closes #38
rodzic
0cce643994
commit
46b6531e45
22
README.md
22
README.md
|
@ -352,6 +352,28 @@ User: s3.read-write.simonw-test-bucket-10
|
|||
```
|
||||
You can pass it multiple usernames to delete multiple users at a time.
|
||||
|
||||
### put-object
|
||||
|
||||
You can upload a file to a key in an S3 bucket using `s3-credentials put-object`:
|
||||
|
||||
s3-credentials put-object my-bucket my-key.txt /path/to/file.txt
|
||||
|
||||
Use `-` as the file name to upload from standard input:
|
||||
|
||||
echo "Hello" | s3-credentials put-object my-bucket hello.txt -
|
||||
|
||||
This command shows a progress bar by default. Use `-s` or `--silent` to hide the progress bar.
|
||||
|
||||
### get-object
|
||||
|
||||
To download a file from a bucket use `s3-credentials get-object`:
|
||||
|
||||
s3-credentials get-object my-bucket hello.txt
|
||||
|
||||
This defaults to outputting the downloaded file to the terminal. You can instead direct it to save to a file on disk using the `-o` or `--output` option:
|
||||
|
||||
s3-credentials get-object my-bucket hello.txt -o /path/to/hello.txt
|
||||
|
||||
## Common options
|
||||
|
||||
All of the `s3-credentials` commands also accept the following options for authenticating against AWS:
|
||||
|
|
|
@ -3,8 +3,11 @@ import boto3
|
|||
import botocore
|
||||
import click
|
||||
import configparser
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from . import policies
|
||||
|
||||
|
||||
|
@ -639,3 +642,56 @@ def list_bucket(bucket, **boto_options):
|
|||
for page in paginator.paginate(Bucket=bucket):
|
||||
for row in page["Contents"]:
|
||||
click.echo(json.dumps(row, indent=4, default=str))
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.argument("bucket")
|
||||
@click.argument("key")
|
||||
@click.argument(
|
||||
"content",
|
||||
type=click.Path(
|
||||
exists=True, file_okay=True, dir_okay=False, readable=True, allow_dash=True
|
||||
),
|
||||
)
|
||||
@click.option("silent", "-s", "--silent", is_flag=True, help="Don't show progress bar")
|
||||
@common_boto3_options
|
||||
def put_object(bucket, key, content, silent, **boto_options):
|
||||
"Upload an object to an S3 bucket"
|
||||
s3 = make_client("s3", **boto_options)
|
||||
size = None
|
||||
if content == "-":
|
||||
# boto needs to be able to seek
|
||||
fp = io.BytesIO(sys.stdin.buffer.read())
|
||||
if not silent:
|
||||
size = fp.getbuffer().nbytes
|
||||
else:
|
||||
fp = click.open_file(content, "rb")
|
||||
if not silent:
|
||||
size = os.path.getsize(content)
|
||||
if not silent:
|
||||
# Show progress bar
|
||||
with click.progressbar(length=size, label="Uploading") as bar:
|
||||
s3.upload_fileobj(fp, bucket, key, Callback=bar.update)
|
||||
else:
|
||||
s3.upload_fileobj(fp, bucket, key)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.argument("bucket")
|
||||
@click.argument("key")
|
||||
@click.option(
|
||||
"output",
|
||||
"-o",
|
||||
"--output",
|
||||
type=click.Path(file_okay=True, dir_okay=False, writable=True, allow_dash=False),
|
||||
help="Write to this file instead of stdout",
|
||||
)
|
||||
@common_boto3_options
|
||||
def get_object(bucket, key, output, **boto_options):
|
||||
"Download an object from an S3 bucket"
|
||||
s3 = make_client("s3", **boto_options)
|
||||
if not output:
|
||||
fp = sys.stdout.buffer
|
||||
else:
|
||||
fp = click.open_file(output, "wb")
|
||||
s3.download_fileobj(bucket, key, fp)
|
||||
|
|
|
@ -22,7 +22,7 @@ def cleanup():
|
|||
cleanup_any_resources()
|
||||
|
||||
|
||||
def test_create_bucket_with_read_write():
|
||||
def test_create_bucket_with_read_write(tmpdir):
|
||||
bucket_name = "s3-credentials-tests.read-write.{}".format(secrets.token_hex(4))
|
||||
# Bucket should not exist
|
||||
s3 = boto3.client("s3")
|
||||
|
@ -37,17 +37,18 @@ def test_create_bucket_with_read_write():
|
|||
time.sleep(10)
|
||||
assert bucket_exists(s3, bucket_name)
|
||||
# Use the credentials to write a file to that bucket
|
||||
test_write = tmpdir / "test-write.txt"
|
||||
test_write.write_text("hello", "utf-8")
|
||||
get_output("put-object", bucket_name, "test-write.txt", str(test_write))
|
||||
credentials_s3.put_object(
|
||||
Body="hello".encode("utf-8"), Bucket=bucket_name, Key="hello.txt"
|
||||
Body="hello".encode("utf-8"), Bucket=bucket_name, Key="test-write.txt"
|
||||
)
|
||||
# Use default s3 client to check that the write succeeded
|
||||
get_object_response = s3.get_object(Bucket=bucket_name, Key="hello.txt")
|
||||
get_object_response = s3.get_object(Bucket=bucket_name, Key="test-write.txt")
|
||||
assert get_object_response["Body"].read() == b"hello"
|
||||
# Check we can read the file using the credentials too
|
||||
credentials_response = credentials_s3.get_object(
|
||||
Bucket=bucket_name, Key="hello.txt"
|
||||
)
|
||||
assert credentials_response["Body"].read() == b"hello"
|
||||
output = get_output("get-object", bucket_name, "test-write.txt")
|
||||
assert output == "hello"
|
||||
|
||||
|
||||
def test_create_bucket_read_only_duration_15():
|
||||
|
|
Ładowanie…
Reference in New Issue