aws-solutions / serverless-image-handler

A solution to dynamically handle images on the fly, utilizing SharpJS
Apache License 2.0
1.31k stars 527 forks source link

Error when result s3 storage is enabled #75

Closed LowLevel96 closed 5 years ago

LowLevel96 commented 5 years ago

Hi, i am trying to setup thumbor.conf to save result images to S3 Bucket. When i do that i and test it, i get image from the API in the browser, but i get error in CloudWatch which believe is regarding saving the image in S3. Any help would be much appreciated.

This the thumbor.conf and error below that.


from os.path import expanduser, join
home = expanduser("~")

# thumbor imaging service
# https://github.com/thumbor/thumbor/wiki

# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license
# Copyright (c) 2011 globo.com thumbor@googlegroups.com

# the domains that can have their images resized
# use an empty list for allow all sources
#ALLOWED_SOURCES = ['mydomain.com']

# the max width of the resized image
# use 0 for no max width
# if the original image is larger than MAX_WIDTH x MAX_HEIGHT,
# it is proportionally resized to MAX_WIDTH x MAX_HEIGHT
# MAX_WIDTH = 800

# the max height of the resized image
# use 0 for no max height
# if the original image is larger than MAX_WIDTH x MAX_HEIGHT,
# it is proportionally resized to MAX_WIDTH x MAX_HEIGHT
# MAX_HEIGHT = 600

# the quality of the generated image
# this option can vary widely between
# imaging engines and works only on jpeg images
QUALITY = 85
WEBP_QUALITY = 80

# Automatically converts images to WebP if Accepts header present
AUTO_WEBP = False

# Specify the ratio between 1in and 1px for SVG images. This is only used when
# rasterizing SVG images having their size units in cm or inches.
# SVG_DPI = 150

# Preserves exif information in generated images. Increases image size in kbytes, use with caution.
PRESERVE_EXIF_INFO = False

# enable this options to specify client-side cache in seconds
MAX_AGE = 365 * 24 * 60 * 60

# client-side caching time for temporary images (using queued detectors or after detection errors)
MAX_AGE_TEMP_IMAGE = 0

# Sends If-Modified-Since & Last-Modified headers; requires support from result storage
SEND_IF_MODIFIED_LAST_MODIFIED_HEADERS = False

# the way images are to be loaded
#LOADER = 'thumbor.loaders.http_loader'
#LOADER = 'thumbor.loaders.file_loader'
LOADER = 'tc_aws.loaders.s3_loader'
#LOADER = 'tc_aws.loaders.presigning_loader'

# maximum size of the source image in Kbytes.
# use 0 for no limit.
# this is a very important measure to disencourage very
# large source images.
# THIS ONLY WORKS WITH http_loader.
MAX_SOURCE_SIZE = 0

# if you set UPLOAD_ENABLED to True,
# a route /upload will be enabled for your thumbor process
# You can then do a put to this URL to store the photo
# using the specified Storage
UPLOAD_ENABLED = False
UPLOAD_PHOTO_STORAGE = 'thumbor.storages.file_storage'
UPLOAD_PUT_ALLOWED = False
UPLOAD_DELETE_ALLOWED = False
UPLOAD_DEFAULT_FILENAME = 'image'

# how to store the loaded images so we don't have to load
# them again with the loader
#STORAGE = 'thumbor.storages.redis_storage'
STORAGE = 'thumbor.storages.no_storage'
#STORAGE = 'thumbor.storages.file_storage'
#STORAGE = 'thumbor.storages.mixed_storage'
#STORAGE = 'thumbor.storages.memcache_storage'
#STORAGE = 'tc_aws.storages.s3_storage'

# root path of the file storage
FILE_STORAGE_ROOT_PATH = join(home, 'thumbor', 'storage' )

# If you want to cache results, use this options to specify how to cache it
# Set Expiration seconds to ZERO if you want them not to expire.
#RESULT_STORAGE = 'thumbor.result_storages.no_storage'
#RESULT_STORAGE = 'thumbor.result_storages.file_storage'
**RESULT_STORAGE = 'tc_aws.result_storages.s3_storage'**
RESULT_STORAGE_EXPIRATION_SECONDS = 60 * 60 * 24  # one day
RESULT_STORAGE_FILE_STORAGE_ROOT_PATH = join(home, 'thumbor', 'result_storage')

RESULT_STORAGE_STORES_UNSAFE = True

# stores the crypto key in each image in the storage
# this is VERY useful to allow changing the security key
STORES_CRYPTO_KEY_FOR_EACH_IMAGE = True

#MEMCACHE_STORAGE_SERVERS = ['localhost:11211']

# imaging engine to use to process images

ENGINE = 'thumbor.engines.pil'

# if you need to use the OpenCV engine please refer
# to https://github.com/thumbor/opencv-engine
#ENGINE = 'opencv_engine'

# if you need to use the GraphicsMagick engine please refer
# to https://github.com/thumbor/graphicsmagick-engine
#ENGINE = 'graphicsmagick_engine'

# The graphics engine (and any optimizers) will block the IOLoop.  If you want
# to increase the number of concurrent requests Thumbor can handle, increase
# ENGINE_THREADPOOLSIZE to use a thread pool.  Benchmarks indicate 1xnumber of
# cpus - 2x number of cpus gives the best results, but do some benchmarks with
# your workload.
#ENGINE_THREADPOOL_SIZE = 0

# detectors to use to find Focal Points in the image
# more about detectors can be found in thumbor's docs
# at https://github.com/thumbor/thumbor/wiki

# SO-SIH-155 - 07/18/2018 - Rekognition integration
# Adding Rekognition support
DETECTORS = [
    #'thumbor.detectors.face_detector',
    'thumbor_rekognition',
    #'thumbor.detectors.profile_detector',
    #'thumbor.detectors.glasses_detector',
    'thumbor.detectors.feature_detector',
]

# Redis parameters for queued detectors
# REDIS_QUEUE_SERVER_HOST = 'localhost'
# REDIS_QUEUE_SERVER_PORT = 6379
# REDIS_QUEUE_SERVER_DB = 0
# REDIS_QUEUE_SERVER_PASSWORD = None

# AWS SQS parameters for queued detectors
# SQS_QUEUE_KEY_ID = ''
# SQS_QUEUE_KEY_SECRET = ''
# SQS_QUEUE_REGION = 'us-east-1'

# if you use face detection this is the file that
# OpenCV will use to find faces. The default should be
# fine, so change this at your own peril.
# if you set a relative path it will be relative to
# the thumbor/detectors/face_detector folder
#FACE_DETECTOR_CASCADE_FILE = 'haarcascade_frontalface_alt.xml'

# this is the security key used to encrypt/decrypt urls.
# make sure this is unique and not well-known
# This can be any string of up to 16 characters
SECURITY_KEY = ""

# if you enable this, the unencryted URL will be available
# to users.
# IT IS VERY ADVISED TO SET THIS TO False TO STOP OVERLOADING
# OF THE SERVER FROM MALICIOUS USERS
ALLOW_UNSAFE_URL = True

# Mixed storage classes. Change them to the fullname of the
# storage you desire for each operation.
#MIXED_STORAGE_FILE_STORAGE = 'thumbor.storages.file_storage'
#MIXED_STORAGE_CRYPTO_STORAGE = 'thumbor.storages.no_storage'
#MIXED_STORAGE_DETECTOR_STORAGE = 'thumbor.storages.no_storage'

#FILTERS = [
    #'thumbor.filters.brightness',
    #'thumbor.filters.colorize',
    #'thumbor.filters.contrast',
    #'thumbor.filters.rgb',
    #'thumbor.filters.round_corner',
    #'thumbor.filters.quality',
    #'thumbor.filters.noise',
    #'thumbor.filters.watermark',
    #'thumbor.filters.equalize',
    #'thumbor.filters.fill',
    #'thumbor.filters.saturation',
    #'thumbor.filters.sharpen',
    #'thumbor.filters.strip_icc',
    #'thumbor.filters.frame',
    #'thumbor.filters.grayscale',
    #'thumbor.filters.rotate',
    #'thumbor.filters.format',
    #'thumbor.filters.max_bytes',
    #'thumbor.filters.no_upscale',

    ## can only be applied if there are already points for the image being served
    ## this means that either you are using the local face detector or the image
    ## has already went through remote detection
    ## 'thumbor.filters.redeye',
#]

OPTIMIZERS = [
    'thumbor_plugins.optimizers.pngquant'
    #'thumbor_plugins.optimizers.pngcrush',
    #'thumbor_plugins.optimizers.auto'
    #'thumbor_plugins.optimizers.optipng'
    #'thumbor_plugins.optimizers.mozjpeg'
    #'thumbor.optimizers.gifv',
    #'thumbor.optimizers.jpegtran',
]

USE_GIFSICLE_ENGINE = False

PNGQUANT_PATH = '/var/task/pngquant'
PNGQUANT_QUALITY = 80
PNGQUANT_SPEED = 3

JPEGTRAN_PATH = '/var/task/jpegtran'
PNGCRUSH_PATH = '/var/task/pngcrush'
IMGMIN_PATH = '/var/task/imgmin'

OPTIPNG_PATH = '/var/task/optipng'
OPTIPNG_LEVEL = 5

MOZJPEG_PATH = '/var/task/cjpeg'
MOZJPEG_QUALITY = 75

# AWS Region the bucket is located in.
TC_AWS_REGION='us-east-1'
# A custom AWS endpoint.
TC_AWS_ENDPOINT='http://s3.amazonaws.com'

# AWS region for the Rekognition service
REKOGNITION_REGION='us-east-1'

# When using either tc_aws.loaders.s3_loader or tc_aws.loaders.presigning_loader.
TC_AWS_STORAGE_BUCKET='itest001' # S3 bucket for Storage
TC_AWS_STORAGE_ROOT_PATH='' # S3 path prefix for Storage bucket

# S3 bucket for Loader. If given, source urls are interpreted as keys
# within this bucket. If not given, source urls are expected to contain
# the bucket name, such as 's3-bucket/keypath'.
TC_AWS_LOADER_BUCKET='serverlessimagehandler-demowebsitebucket-82ea245dyrd9'

# S3 path prefix for Loader bucket. If given, this is prefixed to
# all S3 keys.
TC_AWS_LOADER_ROOT_PATH=''

# Enable HTTP Loader as well?
# This would allow you to load watermarks in over your images dynamically through a URI
# E.g.
# http://your-thumbor.com/unsafe/filters:watermark(http://example.com/watermark.png,0,0,50)/s3_bucket/photo.jpg
# SO-SIH-165 - 08/08/2018 - Enable watermarking
TC_AWS_ENABLE_HTTP_LOADER = True

TC_AWS_ALLOWED_BUCKETS=False # List of allowed bucket to be requested

TC_AWS_STORAGE_BUCKET='' # S3 bucket for Storage
TC_AWS_STORAGE_ROOT_PATH='' # S3 path prefix for Storage bucket

# When tc_aws.storages.s3_storage is enabled.
# put data into S3 using the Server Side Encryption functionality to
# encrypt data at rest in S3
# https://aws.amazon.com/about-aws/whats-new/2011/10/04/amazon-s3-announces-server-side-encryption-support/
TC_AWS_STORAGE_SSE=False

# put data into S3 with Reduced Redundancy
# https://aws.amazon.com/about-aws/whats-new/2010/05/19/announcing-amazon-s3-reduced-redundancy-storage/
TC_AWS_STORAGE_RRS=False

# When tc_aws.result_storages.s3_storage is enabled.
**TC_AWS_RESULT_STORAGE_BUCKET='serverlessimagehandler-demowebsitebucket-82ea245dyrd9' # S3 bucket for result Storage**
**TC_AWS_RESULT_STORAGE_ROOT_PATH='optimized' # S3 path prefix for Result storage bucket**
TC_AWS_MAX_RETRY=1 # Max retries for get image from S3 Bucket. Default is 0

TC_AWS_STORE_METADATA=False # Store result with metadata (for instance content-type)

Error in Cloud Watch

[ERROR] 2018-11-28T20:51:27.534Z    6015afe0-f34f-11e8-9bad-975ca559ce4e    Exception in callback <functools.partial object at 0x7f86965d4db8>
Traceback (most recent call last):
File "/var/task/tornado/ioloop.py", line 760, in _run_callback
ret = callback()
File "/var/task/tornado/stack_context.py", line 276, in null_wrapper
return fn(*args, **kwargs)
File "/var/task/tornado/ioloop.py", line 781, in _discard_future_result
future.result()
File "/var/task/tornado/concurrent.py", line 260, in result
raise_exc_info(self._exc_info)
File "/var/task/tornado/gen.py", line 315, in wrapper
yielded = next(result)
File "/var/task/thumbor/handlers/__init__.py", line 478, in _store_results
yield gen.maybe_future(result_storage.put(results))
File "/var/task/tornado/concurrent.py", line 521, in wrapper
future.result()
File "/var/task/tornado/concurrent.py", line 260, in result
raise_exc_info(self._exc_info)
File "/var/task/tornado/concurrent.py", line 509, in wrapper
result = f(*args, **kwargs)
File "/var/task/tc_aws/result_storages/s3_storage.py", line 42, in put
super(Storage, self).set(bytes, path, callback=callback)
File "/var/task/tornado/concurrent.py", line 521, in wrapper
future.result()
File "/var/task/tornado/concurrent.py", line 260, in result
raise_exc_info(self._exc_info)
File "/var/task/tornado/concurrent.py", line 509, in wrapper
result = f(*args, **kwargs)
File "/var/task/tc_aws/aws/storage.py", line 81, in set
callback=callback,
File "/var/task/tornado/concurrent.py", line 521, in wrapper
future.result()
File "/var/task/tornado/concurrent.py", line 260, in result
raise_exc_info(self._exc_info)
File "/var/task/tornado/concurrent.py", line 509, in wrapper
result = f(*args, **kwargs)
File "/var/task/tc_aws/aws/bucket.py", line 124, in put
self._put_client.call(**args)
File "/var/task/tornado_botocore/base.py", line 154, in call
callback=callback
File "/var/task/tornado_botocore/base.py", line 110, in _make_api_call
callback=callback
File "/var/task/tornado_botocore/base.py", line 101, in _make_request
callback=callback
File "/var/task/tornado_botocore/base.py", line 74, in _send_request
proxy_port=self.proxy_port
File "/var/task/tornado/httpclient.py", line 446, in __init__
self.body = body
File "/var/task/tornado/httpclient.py", line 491, in body
self._body = utf8(value)
File "/var/task/tornado/escape.py", line 197, in utf8
"Expected bytes, unicode, or None; got %r" % type(value)
TypeError: Expected bytes, unicode, or None; got <type 'instance'>
LowLevel96 commented 5 years ago

Issue resolved. I changed the tornado version to 5.1.1 and tornado_botocore to 1.5.0