Flask utility for signing Amazon S3 POST requests and validating Amazon S3 files. Both Python 2.7 and 3.4 are supported.
Upgrade note: Pontus 1.x branch uses Boto3. If you are still using boto, use 0.x.x versions. Check Git branch `version-0`.
Install with pip:
pip install Pontus
Pontus has the following dependencies:
- Flask >= 0.10.1
 - boto3 >= 1.4.7
 - python-magic >= 0.4.6 (https://github.com/ahupp/python-magic)
 
Moreover python-magic depends on the libmagic file type identification library.
Creating form fields for a signed Amazon S3 POST request
import boto3
from flask import current_app
from pontus import AmazonS3SignedRequest
session = boto3.session.Session(
    aws_access_key_id=current_app.config.get('AWS_ACCESS_KEY_ID'),
    aws_secret_access_key=current_app.config.get('AWS_SECRET_ACCESS_KEY'),
    region_name=current_app.config.get('AWS_REGION_NAME')
)
bucket = session.resource('s3').Bucket('testbucket')
signed_request = AmazonS3SignedRequest(
    key_name=u'my/file.jpg',
    mime_type=u'image/jpeg',
    bucket=bucket,
    session=session
)
signed_request.form_fields
# {
#     'x-amz-algorithm': 'AWS4-HMAC-SHA256',
#     'x-amz-credential': 'your-aws-access-key-id/date/region-name/s3/aws4_request',
#     'x-amz-date': 'date',
#     'x-amz-signature': 'generated-signature',
#     'success_action_status': '201',
#     'acl': 'public-read',
#     'Content-Type': 'image/png',
#     'key': u'f6c157e1-1a1a-4418-99fe-3362dcf7b1ea/images/my-image.jpg',
#     'policy': 'generated-policy-document'
# }These form fields can be used to POST files to Amazon S3 as described in Amazon's documentation.
Validating that an image file is less than 2MB and is of image/jpeg
MIME type.
import boto3
from flask import current_app
from pontus import AmazonS3FileValidator
from pontus.validators import FileSize, MimeType
session = boto3.session.Session(
    aws_access_key_id=current_app.config.get('AWS_ACCESS_KEY_ID'),
    aws_secret_access_key=current_app.config.get('AWS_SECRET_ACCESS_KEY')
)
bucket = session.resource('s3').Bucket('testbucket')
validator = AmazonS3FileValidator(
    key_name='images/my-image.jpg',
    bucket=bucket,
    validators=[FileSize(max=2097152), MimeType('image/jpeg')],
    session=session
)
if validator.validate():
    # File is <2MB image/jpeg
    pass
else:
    # File was invalid, printing errors
    print validator.errorsValidators can either be instances of a class inheriting
pontus.validators.BaseValidator or callable functions that take one
parameter obj, which is a boto.S3.Object instance.
from pontus.exceptions import ValidationError
from pontus.validators import BaseValidator
def name_starts_with_images(obj):
    if not obj.key.startswith('images/'):
        raise ValidationError()
# OR
class NameStartsWith(BaseValidator):
    def __init__(self, starts_with_str):
        self.starts_with_str = starts_with_str
    def __call__(self, obj):
        if not obj.key.startswith(starts_with_str):
            raise ValidationError()
name_starts_with_images = NameStartsWith('images/')