Skip to content

Instantly share code, notes, and snippets.

@fdobrovolny
Created March 25, 2021 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fdobrovolny/b3b3abb54a794b39d9fdc6b5236980b9 to your computer and use it in GitHub Desktop.
Save fdobrovolny/b3b3abb54a794b39d9fdc6b5236980b9 to your computer and use it in GitHub Desktop.
Command line utility to generate curl commands with presigned AWS S3 upload POST URLs
#!/usr/bin/env python
"""
This command line utility enables you to easily create presigned
urls for uploading files. This can be usdeful for running on
remote machines without risking to copy over your credentials.
Filip Dobrovolny <dobrovolny.filip@gmail.com> 2020
"""
import argparse
import logging
from argparse import RawTextHelpFormatter
import boto3
from botocore.exceptions import ClientError
def create_presigned_post(bucket_name, object_name,
fields=None, conditions=None, expiration=3600):
"""Generate a presigned URL S3 POST request to upload a file
:param bucket_name: string
:param object_name: string
:param fields: Dictionary of prefilled form fields
:param conditions: List of conditions to include in the policy
:param expiration: Time in seconds for the presigned URL to remain valid
:return: Dictionary with the following keys:
url: URL to post to
fields: Dictionary of form fields and values to submit with the POST
:return: None if error.
"""
# Generate a presigned S3 POST URL
s3_client = boto3.client('s3')
try:
response = s3_client.generate_presigned_post(bucket_name,
object_name,
Fields=fields,
Conditions=conditions,
ExpiresIn=expiration)
except ClientError as e:
logging.error(e)
return None
# The response contains the presigned URL and required fields
return response
parser = argparse.ArgumentParser(
description="""Create presigned upload url to s3
This command line utility enables you to easily create presigned
urls for uploading files. This can be usdeful for running on
remote machines without risking to copy over your credentials.
Filip Dobrovolny <dobrovolny.filip@gmail.com> 2020
""", formatter_class=RawTextHelpFormatter
)
parser.add_argument('bucket', help='The name of the bucket to upload to')
parser.add_argument('key', help='Key to which the file will be uploaded')
parser.add_argument(
'-f', '--file',
help='Path to the local file. If not specified you have'
'to specify this in the resulting curl command',
default="<FIX ME>")
parser.add_argument('-e', '--expires',
help="When the link expires", type=int, default=3600)
args = parser.parse_args()
data = create_presigned_post(args.bucket, args.key, expires=args.expires)
fields = ' '.join(['-F \'%s=%s\'' % (key, value)
for key, value in data['fields'].items()])
print(f"curl -v -L -X POST {data['url']} {fields} -F 'file=@{args.file}'")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment