thumbor/config.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
# 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
import tempfile
from os.path import expanduser, join
from derpconf import config
from derpconf.config import Config
from thumbor import __version__
from thumbor.filters import BUILTIN_FILTERS
from thumbor.handler_lists import BUILTIN_HANDLERS
HOME = expanduser("~")
Config.define(
"THUMBOR_LOG_CONFIG", None, "Logging configuration as json", "Logging"
)
Config.define(
"THUMBOR_LOG_FORMAT",
"%(asctime)s %(name)s:%(levelname)s %(message)s",
"Log Format to be used by thumbor when writing log messages.",
"Logging",
)
Config.define(
"THUMBOR_LOG_DATE_FORMAT",
"%Y-%m-%d %H:%M:%S",
"Date Format to be used by thumbor when writing log messages.",
"Logging",
)
Config.define(
"MAX_WIDTH",
0,
"Max width in pixels for images read or generated by thumbor",
"Imaging",
)
Config.define(
"MAX_HEIGHT",
0,
"Max height in pixels for images read or generated by thumbor",
"Imaging",
)
Config.define(
"MAX_PIXELS", 75e6, "Max pixel count for images read by thumbor", "Imaging"
)
Config.define(
"MIN_WIDTH",
1,
"Min width in pixels for images read or generated by thumbor",
"Imaging",
)
Config.define(
"MIN_HEIGHT",
1,
"Min width in pixels for images read or generated by thumbor",
"Imaging",
)
Config.define(
"ALLOWED_SOURCES",
[],
"Allowed domains for the http loader to download. These are regular expressions.",
"Imaging",
)
Config.define(
"QUALITY", 80, "Quality index used for generated JPEG images", "Imaging"
)
Config.define(
"PROGRESSIVE_JPEG",
True,
"Exports JPEG images with the `progressive` flag set.",
"Imaging",
)
Config.define(
"PILLOW_JPEG_SUBSAMPLING",
None,
"Specify subsampling behavior for Pillow (see `subsampling` \
in http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html#jpeg)."
'Be careful to use int for 0,1,2 and string for "4:4:4" notation. '
"Will ignore `quality`. Using `keep` will copy the original file's subsampling.",
"Imaging",
)
Config.define(
"PILLOW_JPEG_QTABLES",
None,
"Specify quantization tables for Pillow (see `qtables` \
in http://pillow.readthedocs.org/en/latest/handbook/image-file-formats.html#jpeg). "
"Will ignore `quality`. Using `keep` will copy the original file's qtables.",
"Imaging",
)
Config.define(
"PILLOW_RESAMPLING_FILTER",
"LANCZOS",
"Specify resampling filter for Pillow resize method. "
"One of LANCZOS, NEAREST, BILINEAR, BICUBIC, HAMMING (Pillow>=3.4.0).",
"Imaging",
)
Config.define(
"WEBP_QUALITY",
None,
"Quality index used for generated WebP images. If not set (None) the same level of "
"JPEG quality will be used. If 100 the `lossless` flag will be used.",
"Imaging",
)
Config.define(
"AVIF_QUALITY",
None,
"Quality index used for generated AVIF images. If not set (None) the same "
"level of JPEG quality will be used. Controls the max quantizer setting, "
"with quality=0 corresponding to max quantizer 63, and quality=100 to "
"max quantizer=0",
"Imaging",
)
Config.define(
"AVIF_SPEED",
None,
"Quality/speed trade-off (0=slower-better, 10=fastest).",
"Imaging",
)
Config.define(
"AVIF_CODEC",
"auto",
"Codec to use for encoding AVIF images. Can be `auto`, `aom`, `rav1e`, "
"or `svt`, depending on what is compiled into libavif.",
"Imaging",
)
Config.define(
"AVIF_CODEC_FALLBACK",
"auto",
"Codec to use for encoding AVIF images if `AVIF_CODEC` cannot be used. "
"For instance, if AVIF_CODEC is `svt` but an image is too small or too "
"large to be encoded with that codec, the image will be encoded using "
"the codec from this setting instead.",
"Imaging",
)
Config.define(
"HEIF_QUALITY",
None,
"Quality index used for generated HEIF images. If not set (None) the same "
"level of JPEG quality will be used.",
"Imaging",
)
Config.define(
"SRGB_PROFILE",
None,
"Path to the file containing the sRGB ICC profile to use when images need "
"to be converted from other color spaces. If None, uses the default SRGB "
"profile from Pillow ImageCMS.",
"Imaging",
)
Config.define(
"PNG_COMPRESSION_LEVEL",
6,
"Compression level for generated PNG images.",
"Imaging",
)
Config.define(
"PILLOW_PRESERVE_INDEXED_MODE",
True,
"Indicates if final image should preserve indexed mode (P or 1) of original image",
"Imaging",
)
Config.define(
"AUTO_WEBP",
False,
"Specifies whether WebP format should be used automatically if the request accepts it "
"(via Accept header)",
"Imaging",
)
Config.define(
"AUTO_AVIF",
False,
"Specifies whether Avif format should be used automatically if the request accepts it "
"(via Accept header) and pillow-avif-plugin is enabled",
"Imaging",
)
Config.define(
"AUTO_JPG",
False,
"Specifies whether JPG format should be used automatically if the request accepts it "
"(via Accept header)",
"Imaging",
)
Config.define(
"AUTO_HEIF",
False,
"Specifies whether Heif format should be used automatically if the request accepts it "
"(via Accept header) and pillow-heif is enabled",
"Imaging",
)
Config.define(
"AUTO_PNG",
False,
"Specifies whether PNG format should be used automatically if the request accepts it "
"(via Accept header)",
"Imaging",
)
Config.define(
"AUTO_PNG_TO_JPG",
False,
"Specifies whether a PNG image should be used automatically if the png image has "
"no transparency (via alpha layer). "
"WARNING: Depending on case, this is not a good deal. "
"This transformation maybe causes distortions or the size of image can increase. "
"Images with texts, for example, the result image maybe will be distorted. "
"Dark images, for example, the size of result image maybe will be bigger. "
"You have to evaluate the majority of your use cases "
"to take a decision about the usage of this conf.",
"Imaging",
)
Config.define(
"SVG_DPI",
150,
"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.",
"Imaging",
)
Config.define(
"MAX_AGE",
24 * 60 * 60,
"Max AGE sent as a header for the image served by thumbor in seconds",
"Imaging",
)
Config.define(
"MAX_AGE_TEMP_IMAGE",
0,
"Indicates the Max AGE header in seconds for "
"temporary images (images with failed smart detection)",
"Imaging",
)
Config.define(
"RESPECT_ORIENTATION",
False,
"Indicates whether thumbor should rotate images that have an Orientation EXIF header",
"Imaging",
)
Config.define(
"IGNORE_SMART_ERRORS",
False,
"Ignore errors during smart detections and return image "
"as a temp image (not saved in result storage and with MAX_AGE_TEMP_IMAGE age)",
"Imaging",
)
Config.define(
"SEND_IF_MODIFIED_LAST_MODIFIED_HEADERS",
False,
"Sends If-Modified-Since & Last-Modified headers; requires support from result storage",
"Imaging",
)
Config.define(
"PRESERVE_EXIF_INFO",
False,
"Preserves exif information in generated images. "
"Increases image size in kbytes, use with caution.",
"Imaging",
)
Config.define(
"PRESERVE_EXIF_COPYRIGHT_INFO",
False,
"Preserves Exif copyright information in generated images.",
"Imaging",
)
Config.define(
"PRESERVE_IPTC_INFO",
False,
"Preserves Jpeg IPTC information in generated images.",
"Imaging",
)
Config.define(
"ALLOW_ANIMATED_GIFS",
True,
"Indicates whether thumbor should enable the EXPERIMENTAL support for animated gifs.",
"Imaging",
)
Config.define(
"USE_GIFSICLE_ENGINE",
False,
"Indicates whether thumbor should use gifsicle engine. "
"Please note that smart cropping and filters are not "
"supported for gifs using gifsicle (but won't give an error).",
"Imaging",
)
Config.define(
"USE_BLACKLIST",
False,
"Indicates whether thumbor should enable blacklist "
"functionality to prevent processing certain images.",
"Imaging",
)
Config.define(
"ENGINE_THREADPOOL_SIZE",
0,
"Size of the thread pool used for image transformations."
" The default value is 0 (don't use a threadpoool). "
"Increase this if you are seeing your IOLoop getting "
"blocked (often indicated by your upstream HTTP "
"requests timing out)",
"Imaging",
)
Config.define(
"METRICS",
"thumbor.metrics.logger_metrics",
"The metrics backend thumbor should use to measure internal actions."
" This must be the full name of a python module "
"(python must be able to import it)",
"Extensibility",
)
Config.define(
"LOADER",
"thumbor.loaders.http_loader",
"The loader thumbor should use to load the original image. "
"This must be the full name of a python module "
"(python must be able to import it)",
"Extensibility",
)
Config.define(
"STORAGE",
"thumbor.storages.file_storage",
"The file storage thumbor should use to store original images."
" This must be the full name of a python module "
"(python must be able to import it)",
"Extensibility",
)
Config.define(
"RESULT_STORAGE",
None,
"The result storage thumbor should use to store generated "
"images. This must be the full name of a python "
"module (python must be able to import it)",
"Extensibility",
)
Config.define(
"ENGINE",
"thumbor.engines.pil",
"The imaging engine thumbor should use to perform image "
"operations. This must be the full name of a "
"python module (python must be able to import it)",
"Extensibility",
)
Config.define(
"GIF_ENGINE",
"thumbor.engines.gif",
"The gif engine thumbor should use to perform image operations."
" This must be the full name of a "
"python module (python must be able to import it)",
"Extensibility",
)
Config.define(
"SECURITY_KEY",
"MY_SECURE_KEY",
"The security key thumbor uses to sign image URLs",
"Security",
)
Config.define(
"ALLOW_UNSAFE_URL",
True,
"Indicates if the /unsafe URL should be available",
"Security",
)
Config.define(
"ENABLE_ETAGS", True, "Enables automatically generated etags", "HTTP"
)
Config.define(
"MAX_ID_LENGTH",
32,
"Set maximum id length for images when stored",
"Storage",
)
Config.define(
"GC_INTERVAL",
None,
"Set garbage collection interval in seconds",
"Performance",
)
Config.define(
"HEALTHCHECK_ROUTE", r"/healthcheck/?", "Healthcheck route.", "Healthcheck"
)
# METRICS OPTIONS
Config.define(
"STATSD_HOST", None, "Host to send statsd instrumentation to", "Metrics"
)
Config.define(
"STATSD_PORT", 8125, "Port to send statsd instrumentation to", "Metrics"
)
Config.define("STATSD_PREFIX", None, "Prefix for statsd", "Metrics")
# FILE LOADER OPTIONS
Config.define(
"FILE_LOADER_ROOT_PATH",
HOME,
"The root path where the File Loader will try to find images",
"File Loader",
)
# HTTP LOADER OPTIONS
Config.define(
"HTTP_LOADER_CONNECT_TIMEOUT",
5,
"The maximum number of seconds libcurl can take to connect to an image being loaded",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_REQUEST_TIMEOUT",
20,
"The maximum number of seconds libcurl can take to download an image",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_FOLLOW_REDIRECTS",
True,
"Indicates whether libcurl should follow redirects when downloading an image",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_MAX_REDIRECTS",
5,
"Indicates the number of redirects libcurl should follow when downloading an image",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_MAX_CLIENTS",
10,
"The maximum number of simultaneous HTTP connections the loader can make before queuing",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_FORWARD_USER_AGENT",
False,
"Indicates whether thumbor should forward the user agent of the requesting user",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_FORWARD_ALL_HEADERS",
False,
"Indicates whether thumbor should forward the headers of the request",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_FORWARD_HEADERS_WHITELIST",
[],
"Indicates which headers should be forwarded among all the headers of the request",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_DEFAULT_USER_AGENT",
f"Thumbor/{__version__}",
"Default user agent for thumbor http loader requests",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_PROXY_HOST",
None,
"The proxy host needed to load images through",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_PROXY_PORT",
None,
"The proxy port for the proxy host",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_PROXY_USERNAME",
None,
"The proxy username for the proxy host",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_PROXY_PASSWORD",
None,
"The proxy password for the proxy host",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_CA_CERTS",
None,
"The filename of CA certificates in PEM format",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_VALIDATE_CERTS",
None,
"Validate the server’s certificate for HTTPS requests",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_CLIENT_KEY",
None,
"The filename for client SSL key",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_CLIENT_CERT",
None,
"The filename for client SSL certificate",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT",
False,
"If the CurlAsyncHTTPClient should be used",
"HTTP Loader",
)
Config.define(
"HTTP_LOADER_CURL_LOW_SPEED_TIME",
0,
"If HTTP_LOADER_CURL_LOW_SPEED_LIMIT and HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT "
+ "are set, then this is the time in seconds as integer after a download should "
+ "timeout if the speed is below HTTP_LOADER_CURL_LOW_SPEED_LIMIT for that long",
)
Config.define(
"HTTP_LOADER_CURL_LOW_SPEED_LIMIT",
0,
"If HTTP_LOADER_CURL_LOW_SPEED_TIME and HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT "
+ "are set, then this is the limit in bytes per second as integer which should "
+ "timeout if the speed is below that limit for HTTP_LOADER_CURL_LOW_SPEED_TIME seconds",
)
# FILE STORAGE GENERIC OPTIONS
Config.define(
"STORAGE_EXPIRATION_SECONDS",
60 * 60 * 24 * 30,
"Expiration in seconds for the images in the File Storage. Defaults to one month",
"File Storage",
)
Config.define(
"STORES_CRYPTO_KEY_FOR_EACH_IMAGE",
False,
"Indicates whether thumbor should store the signing key for each image in the file storage. "
+ "This allows the key to be changed and old images to still be properly found",
"File Storage",
)
# FILE STORAGE OPTIONS
Config.define(
"FILE_STORAGE_ROOT_PATH",
join(tempfile.gettempdir(), "thumbor", "storage"),
"The root path where the File Storage will try to find images",
"File Storage",
)
# PHOTO UPLOAD OPTIONS
Config.define(
"UPLOAD_MAX_SIZE",
0,
"Max size in bytes for images uploaded to thumbor",
"Upload",
)
Config.define(
"UPLOAD_ENABLED",
False,
"Indicates whether thumbor should enable File uploads",
"Upload",
)
Config.define(
"UPLOAD_PHOTO_STORAGE",
"thumbor.storages.file_storage",
"The type of storage to store uploaded images with",
"Upload",
)
Config.define(
"UPLOAD_DELETE_ALLOWED",
False,
"Indicates whether image deletion should be allowed",
"Upload",
)
Config.define(
"UPLOAD_PUT_ALLOWED",
False,
"Indicates whether image overwrite should be allowed",
"Upload",
)
Config.define(
"UPLOAD_DEFAULT_FILENAME",
"image",
"Default filename for image uploaded",
"Upload",
)
# ALIASES FOR OLD PHOTO UPLOAD OPTIONS
Config.alias("MAX_SIZE", "UPLOAD_MAX_SIZE")
Config.alias("ENABLE_ORIGINAL_PHOTO_UPLOAD", "UPLOAD_ENABLED")
Config.alias("ORIGINAL_PHOTO_STORAGE", "UPLOAD_PHOTO_STORAGE")
Config.alias("ALLOW_ORIGINAL_PHOTO_DELETION", "UPLOAD_DELETE_ALLOWED")
Config.alias("ALLOW_ORIGINAL_PHOTO_PUTTING", "UPLOAD_PUT_ALLOWED")
# MIXED STORAGE OPTIONS
Config.define(
"MIXED_STORAGE_FILE_STORAGE",
"thumbor.storages.no_storage",
"Mixed Storage file storage. This must be the full name "
"of a python module (python must be able to import it)",
"Mixed Storage",
)
Config.define(
"MIXED_STORAGE_CRYPTO_STORAGE",
"thumbor.storages.no_storage",
"Mixed Storage signing key storage. This must be the full "
"name of a python module (python must be able to import it)",
"Mixed Storage",
)
Config.define(
"MIXED_STORAGE_DETECTOR_STORAGE",
"thumbor.storages.no_storage",
"Mixed Storage detector information storage. This must be the full "
"name of a python module (python must be able to import it)",
"Mixed Storage",
)
# JSON META ENGINE OPTIONS
Config.define(
"META_CALLBACK_NAME",
None,
"The callback function name that should be used by the META route for JSONP access",
"Meta",
)
# DETECTORS OPTIONS
Config.define(
"DETECTORS",
[],
"List of detectors that thumbor should use to find faces and/or features. All of them must be "
+ "full names of python modules (python must be able to import it)",
"Detection",
)
# FACE DETECTOR CASCADE FILE
Config.define(
"FACE_DETECTOR_CASCADE_FILE",
"haarcascade_frontalface_alt.xml",
"The cascade file that opencv will use to detect faces.",
"Detection",
)
Config.define(
"GLASSES_DETECTOR_CASCADE_FILE",
"haarcascade_eye_tree_eyeglasses.xml",
"The cascade file that opencv will use to detect glasses.",
"Detection",
)
Config.define(
"PROFILE_DETECTOR_CASCADE_FILE",
"haarcascade_profileface.xml",
"The cascade file that opencv will use to detect profile faces.",
"Detection",
)
Config.define(
"OPTIMIZERS",
[
# 'thumbor.optimizers.jpegtran',
# 'thumbor_plugins.optimizers.gifv',
],
"List of optimizers that thumbor will use to optimize images",
"Optimizers",
)
# OPTIMIZER CONFIGURATIONS
Config.define(
"JPEGTRAN_PATH",
"/usr/bin/jpegtran",
"Path for the jpegtran binary",
"Optimizers",
)
Config.define(
"JPEGTRAN_SCANS_FILE",
"",
"Path for the progressive scans file to use with "
"jpegtran optimizer. Implies progressive jpeg output",
"Optimizers",
)
Config.define(
"FFMPEG_PATH",
"/usr/local/bin/ffmpeg",
"Path for the ffmpeg binary used to generate gifv(h.264)",
"Optimizers",
)
# AVAILABLE FILTERS
Config.define(
"FILTERS",
BUILTIN_FILTERS,
"List of filters that thumbor will allow to be used in generated images. All of them must be "
+ "full names of python modules (python must be able to import it)",
"Filters",
)
# RESULT STORAGE
Config.define(
"RESULT_STORAGE_EXPIRATION_SECONDS",
0,
"Expiration in seconds of generated images in the result storage",
"Result Storage",
) # Never expires
Config.define(
"RESULT_STORAGE_FILE_STORAGE_ROOT_PATH",
join(tempfile.gettempdir(), "thumbor", "result_storage"),
"Path where the Result storage will store generated images",
"Result Storage",
)
Config.define(
"RESULT_STORAGE_STORES_UNSAFE",
False,
"Indicates whether unsafe requests should also be stored in the Result Storage",
"Result Storage",
)
# QUEUED DETECTOR REDIS OPTIONS
Config.define(
"REDIS_QUEUE_SERVER_HOST",
"localhost",
"Server host for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SERVER_PORT",
6379,
"Server port for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SERVER_DB",
0,
"Server database index for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SERVER_PASSWORD",
None,
"Server password for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_MODE",
"single_node",
"Redis operation mode 'single_node' or 'sentinel'",
"Queued Redis Detector",
)
# QUEUED DETECTOR REDIS SENTINEL OPTIONS
Config.define(
"REDIS_QUEUE_SENTINEL_INSTANCES",
"localhost:26379",
"Sentinel server instances for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SENTINEL_PASSWORD",
None,
"Sentinel server password for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SENTINEL_MASTER_INSTANCE",
"master",
"Sentinel server master instance for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SENTINEL_MASTER_PASSWORD",
None,
"Sentinel server master password for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SENTINEL_MASTER_DB",
0,
"Sentinel server master database index for the queued redis detector",
"Queued Redis Detector",
)
Config.define(
"REDIS_QUEUE_SENTINEL_SOCKET_TIMEOUT",
10.0,
"Sentinel server socket timeout for the queued redis detector",
"Queued Redis Detector",
)
# QUEUED DETECTOR SQS OPTIONS
Config.define("SQS_QUEUE_KEY_ID", None, "AWS key id", "Queued SQS Detector")
Config.define(
"SQS_QUEUE_KEY_SECRET", None, "AWS key secret", "Queued SQS Detector"
)
Config.define(
"SQS_QUEUE_REGION", "us-east-1", "AWS SQS region", "Queued SQS Detector"
)
# ERROR HANDLING
Config.define(
"USE_CUSTOM_ERROR_HANDLING",
False,
"This configuration indicates whether thumbor should use a custom error handler.",
"Errors",
)
Config.define(
"ERROR_HANDLER_MODULE",
"thumbor.error_handlers.sentry",
"Error reporting module. Needs to contain a class called ErrorHandler with a "
+ "handle_error(context, handler, exception) method.",
"Errors",
)
# SENTRY REPORTING MODULE
Config.define(
"SENTRY_DSN_URL",
"",
"Sentry thumbor project dsn. i.e.: "
+ "http://5a63d58ae7b94f1dab3dee740b301d6a:73eea45d3e8649239a973087e8f21f98@localhost:9000/2",
"Errors - Sentry",
)
# SENTRY REPORTING MODULE
Config.define(
"SENTRY_ENVIRONMENT",
None,
"Sentry environment i.e.: staging ",
"Errors - Sentry",
)
# FILE REPORTING MODULE
Config.define("ERROR_FILE_LOGGER", None, "File of error log as json", "Errors")
Config.define(
"ERROR_FILE_NAME_USE_CONTEXT",
False,
"File of error log name is parametrized with context attribute",
"Errors",
)
# SIGNER MODULE
Config.define(
"URL_SIGNER",
"libthumbor.url_signers.base64_hmac_sha1",
"The url signer thumbor should use to verify url signatures."
+ "This must be the full name of a python module "
+ "(python must be able to import it)",
"Extensibility",
)
# SERVER
Config.define(
"MAX_WAIT_SECONDS_BEFORE_SERVER_SHUTDOWN",
0,
"The amount of time to wait before shutting down the server, i.e. stop accepting requests.",
"Server",
)
Config.define(
"MAX_WAIT_SECONDS_BEFORE_IO_SHUTDOWN",
0,
"The amount of time to wait before shutting down all io, after the server has been stopped",
"Server",
)
Config.define(
"NON_BLOCKING_SOCKETS",
False,
"If True, thumbor will ensure that the socket from the file descriptor number passed using"
" the --fd flag is non-blocking. This setting has no effect if the --fd flag is a path,"
" sockets created that way are always non-blocking.",
)
# HANDLER LISTS
Config.define(
"HANDLER_LISTS",
BUILTIN_HANDLERS,
"Handler Lists are responsible for adding new handlers to thumbor app.",
"HandlerLists",
)
Config.define(
"APP_CLASS",
"thumbor.app.ThumborServiceApp",
"Custom app class to override ThumborServiceApp. "
"This config value is overridden by the -a command-line parameter.",
)
Config.define(
"ACCESS_CONTROL_ALLOW_ORIGIN_HEADER",
False,
"Sends Access-Control-Allow-Origin header",
)
# COMPATIBILITY
Config.define(
"COMPATIBILITY_LEGACY_LOADER",
None,
"Loader that will be used with the compatibility layer, instead of the "
"compatibility loader. Please only use this if you can't use up-to-date loaders.",
"Compatibility",
)
Config.define(
"COMPATIBILITY_LEGACY_STORAGE",
None,
"Storage that will be used with the compatibility layer, instead of the "
"compatibility storage. Please only use this if you can't use up-to-date storages.",
"Compatibility",
)
Config.define(
"COMPATIBILITY_LEGACY_RESULT_STORAGE",
None,
"Result Storage that will be used with the compatibility layer, instead of the "
"compatibility result storage. Please only use this if you can't use "
"up-to-date result storages.",
"Compatibility",
)
def generate_config():
config.generate_config()
def format_value(value):
if isinstance(value, str):
return f"'{value}'"
if isinstance(value, (tuple, list, set)):
return "[\n" + "".join(f"# {item}" for item in value) + "#]"
return value
if __name__ == "__main__":
generate_config()