thumbor is an open-source photo thumbnail service by globo.com

Overview

Survey

If you use thumbor, please take 1 minute and answer this survey? It's only 2 questions and one is multiple choice!!!

build CircleCI Status Coverage Status Code Climate Codacy Badge Shields Shields PyPI PyPI Bountysource

thumbor is a smart imaging service. It enables on-demand crop, resizing and flipping of images.

It also features a VERY smart detection of important points in the image for better cropping and resizing, using state-of-the-art face and feature detection algorithms (more on that in Detection Algorithms).

Using thumbor is very easy (after it is running). All you have to do is access it using an URL for an image, like this:

http://<thumbor-server>/300x200/smart/thumbor.readthedocs.io/en/latest/_images/logo-thumbor.png

That URL would show an image of the big brother brasil participants in 300x200 using smart crop.

There are several other options to the image URL configuration. You can check them in the Usage page.

For more information check thumbor's documentation.

Demo

You can see thumbor in action at http://thumborize.me/

Join the chat at https://gitter.im/thumbor/thumbor

Comments
  • Upgrading from 6.4.1 to 6.5.X impacts response time and cpu usage

    Upgrading from 6.4.1 to 6.5.X impacts response time and cpu usage

    We have upgraded our docker image from thumbor 6.4.1 to 6.5.1 yesterday. Both CPU and response time are increasing considerably ever since, that's the only change that happened.

    Expected behaviour

    Nothing should dramatically change...

    Actual behaviour

    Both CPU usage and response-time went up considerably.

    screen shot 2018-07-31 at 11 00 11
    • Orange - time to fetch
    • Blue - p95 of response time
    • Yellow dashed - Max response time
    • Red - deployment (first ones to upgrade, second one to downgrade)

    Once I've downgraded back to 6.4.1 the response time went down again...

    screen shot 2018-07-31 at 10 19 44
    • CPU Usage per pod after the deployments...

    The spike matches the deployment time, the CPU usage went down over night because of the less intensive traffic but the response time was still higher (1.5x) the one before.

    Operating system

    Ubuntu 16.04 on K8s

    Your thumbor.conf

        import re
    
        ALLOWED_SOURCES=[
          # https://regexper.com/https://regexper.com/#^https:\/\/*(.+)?hey[.]car\/*(.+)
          re.compile(r'^https://*(.+)?hey[.]car/*(.+)'),
        ]
    
        MAX_SOURCE_SIZE = 500
        SECURITY_KEY = "REDACTED"
        MAX_WIDTH = 2000
        MAX_HEIGHT = 2000
    
        # Cache
        MAX_AGE = 365 * 24 * 60 * 60
        MAX_AGE_TEMP_IMAGE = 240
    
        # Defaults
        QUALITY = 100
    
        # Engines
        HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT = True
    
        # Metrics
        METRICS = "thumbor.metrics.statsd_metrics"
        STATSD_PORT = 8125
        STATSD_HOST = "datadog-statsd.kube-system"
        STATSD_PREFIX = "image_proxy_service"
    
        # GC Options
        GC_INTERVAL = 1800
    
        # AutoWebp
        AUTO_WEBP = True
    
        # Sentry
        ERROR_HANDLER_MODULE = "thumbor.error_handlers.sentry"
        SENTRY_DSN = "REDACTED"
    

    Any thoughts on what could've caused this? Is there any new config that I need to take into account when upgrading? I've been reading the changelog and haven't found anything clearly related to that.

    opened by marceloboeira 51
  • Memory Usage Explosion

    Memory Usage Explosion

    We are experiencing memory usage explosion on Ubuntu 14.04.1 LTS with Thumbor v6.0.1 and Pillow 3.2.0. Our memory usage can hit ~97%. Then it will return to ~60% memory usage and after some time it will hit again ~97% memory usage.

    After some investigation, there is possility that resize method in thumbor/engines/pil.py is the root cause. If we run gc.collect() in resize method, our memory usage is never hit 97% again.

    Thumbor request URL

    Sample url http://localhost:7001/unsafe/1920x1080/filename.jpg

    Script to reproduce

    #! /usr/bin/env ruby
    
    require 'open-uri'
    
    @total = 0
    count = 100000
    
    (5000..(5000+count)).each do |i|
      size = 2000 + rand(2000)
      wxh = [size, size].join('x')
      url = "http://localhost:7001/unsafe/#{wxh}/filename.jpg"
      start_time = Time.now
      open url
      end_time = Time.now
      duration = end_time - start_time
      @total += duration
      puts "got: #{url} in #{duration.round(2)}"
    end
    
    puts "That took: #{@total.round(2)} seconds"
    puts "Average #{(@total / count).round(2)} per image"
    
    

    Expected behaviour

    Memory usage should below 90%

    Actual behaviour

    Memory usage hit ~97%

    Operating system

    14.04.1 LTS Thumbor v6.0.1 Pillow 3.2.0

    thumbor.conf

    MAX_AGE = 31536000
    ALLOW_ANIMATED_GIFS = False
    LOADER = 'thumbor.loaders.file_loader'
    
    STORAGE = 'thumbor.storages.mixed_storage'
    SECURITY_KEY = 'example'
    
    ALLOW_UNSAFE_URL = True
    FILE_LOADER_ROOT_PATH = '/vagrant/images'
    
    REDIS_STORAGE_SERVER_HOST = 'example.com'
    REDIS_STORAGE_SERVER_PORT = 6379
    REDIS_STORAGE_SERVER_DB = 0
    REDIS_STORAGE_SERVER_PASSWORD = None
    
    MIXED_STORAGE_CRYPTO_STORAGE = 'tc_redis.storages.redis_storage'
    MIXED_STORAGE_DETECTOR_STORAGE = 'tc_redis.storages.redis_storage'
    
    DETECTORS = [
       'thumbor.detectors.face_detector',
       'thumbor.detectors.profile_detector',
       'thumbor.detectors.glasses_detector',
       'thumbor.detectors.feature_detector'
    ]
    
    opened by kuntoaji 45
  • Support WebP

    Support WebP

    I was reading this article http://www.igvita.com/2012/12/18/deploying-new-image-formats-on-the-web/ and found myself thinking that it should be fairly easy for us to support webp format (supported currently by chrome and opera).

    Do you guys think we should provide some flag that would make thumbor return the smallest possible image? The only downside is that browsers (as is said on the article) do NOT send proper Accept headers.

    We could allow the users to specify what formats they want to support. Thumbor would generate the image in all the formats, then pick the smallest one.

    What do you guys think?

    opened by heynemann 43
  • Watermark : Enable watermark centering, refs issue #545

    Watermark : Enable watermark centering, refs issue #545

    Allow the value 'center' to be passed to the filter's parameters x or/and y in order to automatically center the filigrane. ex : watermark(watermark.png,center,center,10) watermark(watermark.png,10,center,10) watermark(watermark.png,center,-10,10)

    I don't know what I did wrong but the diff are not showing properly :

    •    regex = r'(?:watermark((?P<url>._?),(?P<x>-?[\d]_?),(?P<y>-?[\d]_?),(?P<alpha>[\d]_?)))'
      
    •    regex = r'(?:watermark\((?P<url>.*?),(?P<x>(?:-?\d+)|center),(?P<y>(?:-?\d+)|center),(?P<alpha>[\d]*?)\))'
      
    •    inv_x = self.x[0] == '-'       
      
    •    inv_y = self.y[0] == '-'  
      
    •    x, y = int(self.x), int(self.y)  
      
    •    center_x = self.x == 'center'
      
    •    center_y = self.y == 'center'
      
    •    if not center_x :
      
    •        inv_x = self.x[0] == '-'
      
    •        x = int(self.x)
      
    •    if not center_y :
      
    •        inv_y = self.y[0] == '-'
      
    •        y = int(self.y)
      
    •    if inv_x:
      
    •        x = (sz[0] - watermark_sz[0]) + x
      
    •    if inv_y:
      
    •        y = (sz[1] - watermark_sz[1]) + y
      
    •    if center_x :
      
    •        x = (sz[0] - watermark_sz[0]) /2
      
    •    elif inv_x:
      
    •        x = (sz[0] - watermark_sz[0]) + x  
      
    •    if center_y :
      
    •        y = (sz[1] - watermark_sz[1]) /2
      
    •    elif inv_y:
      
    •        y = (sz[1] - watermark_sz[1]) + y
      
    • @filter_method(BaseFilter.String, r'-?[\d]+', r'-?[\d]+', BaseFilter.PositiveNumber, async=True)
    • @filter_method(BaseFilter.String, r'(?:-?\d+)|center', r'(?:-?\d+)|center', BaseFilter.PositiveNumber, async=True)
    opened by adeboisanger 38
  • using trim with certain transparent png's results in not-transparent images

    using trim with certain transparent png's results in not-transparent images

    Original: pallas_m_fix_moondust original

    With trim (wrong / no transparency): pallas_m_fix_moondust 1

    Without trim (transparency = good): pallas_m_fix_moondust

    I had the idea maybe this could be the problem: https://github.com/thumbor/thumbor/blob/master/thumbor/transformer.py#L96

    opened by LeonB 35
  • Ubuntu + Thumbor using 100% CPU

    Ubuntu + Thumbor using 100% CPU

    Setup: DigitalOcean Machine 1: Ubuntu 14.11 Thumbor 5.05

    Machine 2 Ubuntu 15.04 Thumbor 4.12.2

    Both machines were with the default config. Only thing changed was the Security key.

    supervisord is starting 2 instances of thumber. And nginx is load balancing them. There is nothing else on the machine running.

    Every couple of hours. For some reason one of our cores on a 2core machine goes up to 100% and stays that way.

    If we dont notice the problem after a while the second core will go up to 100%

    And then the images will load slowly.

    Looking at logs (debug is enabled) it all looked good. Except in the syslog there there are thousands of these:

    Jul 24 18:15:23 packer-ubuntu-15-04-amd64 kernel: [41464.159540] thumbor[25784]: segfault at 1ff1b58 ip 00007f4906cf9783 sp 00007fffe096d3c0 error 6 in libc-2.21.so[7f4906c77000+1c0000]

    Any ideas why this is happening.

    https://www.dropbox.com/s/ugfvd01vjii8q18/Screenshot%202015-07-25%2021.12.45.png?dl=0

    opened by igormatkovic 29
  • Hbase thrift storage

    Hbase thrift storage

    Hello,

    Here is a contrib to make thumbor able to store images in Hbase storage (1 row per path) (like at Yfrog for example http://www.slideshare.net/jacque74/hug-hbase-presentation )

    Very inspire by the redis storage module.

    Hbase is part of the Apache Hadoop project http://hbase.apache.org/ a k/v store column oriented based on HDFS.

    it depends on hbase-thrift and thrift (available via pip).

    Cheers,

    Damien

    FEATURE COMMUNITY SUGGESTION 
    opened by dhardy92 29
  • Guidelines for CPU and memory optimizations

    Guidelines for CPU and memory optimizations

    Hi,

    First, let me start by thanking you for this beautiful and elegant solution. We are using Thumbor for last 6 months in production, serving on average 10,000,000 images/hour with zero issues. Now that we know the product is very stable, we would like to optimize the EC2 instances to further enhance Thumbor on processing more images/minute.

    We are using a Thumbor stack deployed with AWS CloudFormation and an autoscaling group of c5.2xlarge CentOS7 EC2 instances, fully optimized to take advantage of the 10Gbit network infrastructure AWS offers. All images are cached with Akamai and whatever missed, is cached locally for an hour into a Redis cache.

    Current infrastructure (image served with Thumbor🥇): Thumbor Infrastructure The thumbor-6.4.2 RPM is available into AXIVO repository. We use python-pillow-simd-4.3.0, as is 2.5 times faster compared to python-pillow-4.3.0 and proxy all calls through nginx-1.13.10. This allowed us to reduce the CPU usage by approximately 20%.

    While CPU is currently floating around 75% values on each instance, I noticed the memory is partially used. This is the Thumbor configuration we use, on 8 processors and 16GB of RAM:

    $ cat /etc/thumbor/thumbor.conf
    ALLOW_OLD_URLS = False
    ALLOW_UNSAFE_URL = False
    AUTO_WEBP = True
    DETECTORS = [
    	'thumbor.detectors.face_detector',
    	'thumbor.detectors.feature_detector',
    	'thumbor.detectors.glasses_detector',
    	'thumbor.detectors.profile_detector'
    ]
    OPTIMIZERS = [
    	'thumbor.optimizers.jpegtran'
    ]
    ENGINE_THREADPOOL_SIZE = 16
    JPEGTRAN_PATH = '/bin/jpegtran'
    HTTP_LOADER_MAX_CLIENTS = 16384
    MAX_AGE = 2592000
    MAX_AGE_TEMP_IMAGE = 60
    STORAGE = 'tc_redis.storages.redis_storage'
    STORAGE_EXPIRATION_SECONDS = 3600
    REDIS_STORAGE_IGNORE_ERRORS = True
    REDIS_STORAGE_SERVER_HOST = '0001.usw2.cache.amazonaws.com'
    REDIS_STORAGE_SERVER_PORT = 6379
    REDIS_STORAGE_SERVER_DB = 0
    REDIS_STORAGE_SERVER_PASSWORD = None
    RESULT_STORAGE = 'tc_redis.result_storages.redis_result_storage'
    RESULT_STORAGE_EXPIRATION_SECONDS = 3600
    REDIS_RESULT_STORAGE_IGNORE_ERRORS = True
    REDIS_RESULT_STORAGE_SERVER_HOST = '0001.usw2.cache.amazonaws.com'
    REDIS_RESULT_STORAGE_SERVER_PORT = 6379
    REDIS_RESULT_STORAGE_SERVER_DB = 1
    REDIS_RESULT_STORAGE_SERVER_PASSWORD = None
    
    $ free -m
                  total        used        free      shared  buff/cache   available
    Mem:          15309        7604        5871         284        1834        7024
    Swap:             0           0           0
    
    $ systemctl --type=service --state=running list-units | grep thumbor
    [email protected]             loaded active running Thumbor ([email protected])
    [email protected]             loaded active running Thumbor ([email protected])
    [email protected]             loaded active running Thumbor ([email protected])
    [email protected]             loaded active running Thumbor ([email protected])
    [email protected]             loaded active running Thumbor ([email protected])
    [email protected]             loaded active running Thumbor ([email protected])
    [email protected]             loaded active running Thumbor ([email protected])
    [email protected]             loaded active running Thumbor ([email protected])
    

    The ENGINE_THREADPOOL_SIZE value is 2 x nproc.

    Are there any other settings I should take advantage of, to optimize the CPU usage and also increase the memory usage? @heynemann, @guilhermef, @cezarsa, your input is greatly appreciated on this matter.

    Regards,

    Floren Munteanu

    Stale 
    opened by fmunteanu 27
  • Add support Client Hints (DPR, Width, Resource-Width)

    Add support Client Hints (DPR, Width, Resource-Width)

    Chrome 46 is shipping with support for Client Hints. Specifically, we'll send them on an opt-in basis and can advertise device DPR, viewport width, and resource display width (when it's known) to the server to enable automated delivery and optimization of responsive images.

    For additional context on motivation and developer use cases, see: https://developers.google.com/web/updates/2015/09/automating-resource-selection-with-client-hints

    It would be great to have CH support in thumbor! :)

    opened by igrigorik 27
  • GIF image is completely distorted after resize

    GIF image is completely distorted after resize

    After a straightforward 200x200 resize, this black and white GIF image turns into a pixelated mess.

    Operation I am attempting: /unsafe/200x200/https://square-production.s3.amazonaws.com/files/547b05546a7fc457dfc17b0c55132119133460c5/original.gif

    The result image looks like: car-bad

    opened by robolson 25
  • BaseStorage interface is missing callback parameter to optimize for Tornado Runloop

    BaseStorage interface is missing callback parameter to optimize for Tornado Runloop

    I noticed a huge bottleneck when using the thumbor storages and result storages:

    The BaseStorage interface in https://github.com/thumbor/thumbor/blob/master/thumbor/result_storages/init.py#L22

    class BaseStorage(object):
        ...
        def put(self, bytes):
            ...
    
        def get(self):
            ...
    

    supplies only synchronous methods with return values instead of callbacks like the loader interface in https://github.com/thumbor/thumbor/blob/master/thumbor/loaders/file_loader.py

    def load(context, path, callback):
    

    (perfectly fine)

    https://github.com/thumbor/thumbor/blob/master/thumbor/result_storages/init.py Should look more like

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    ...
    import os
    from os.path import exists
    
    class BaseStorage(object):
        def __init__(self, context):
            self.context = context
    
        def put(self, bytes, callback):
            raise NotImplementedError()
    
        def get(self, callback):
            raise NotImplementedError()
    
        def last_updated(self, callback):
            raise NotImplementedError()
    
        def ensure_dir(self, path, callback):
            raise NotImplementedError()
    
    opened by RobertBiehl 23
  • Thumbor should process gifs in a faster way.

    Thumbor should process gifs in a faster way.

    Expected behaviour

    Thumbor should process gifs in a faster way.

    Actual behaviour

    Thumbor is taking too long to process some gifs. So we run some tests using gifsicle (our actual process gifs lib) and pil to compare time processing on both. image

    Conclusion

    We thought, although Gifsicle indeed had a better performance in flips, pil had better processing times in all the others. We don't think the flip filter is heavily used, so the trade off pays itself.

    opened by maiagripp 7
  • Installing thumbor on windows server

    Installing thumbor on windows server

    Expected behaviour

    Installing thumbor on windows server.

    Actual behaviour

    UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 148: character maps to

    Operating system

    Windows server 2016 Standard

    Your thumbor.conf

    C:\Users\Administrator>pip install thumbor Collecting thumbor Using cached thumbor-7.3.1.tar.gz (29.7 MB) Installing build dependencies ... done Getting requirements to build wheel ... error error: subprocess-exited-with-error

    × Getting requirements to build wheel did not run successfully. │ exit code: 1 ╰─> [27 lines of output] Traceback (most recent call last): File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\pip_vendor\pep517\in_process_in_process.py", line 351, in main() File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\pip_vendor\pep517\in_process_in_process.py", line 333, in main json_out['return_val'] = hook(**hook_input['kwargs']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\site-packages\pip_vendor\pep517\in_process_in_process.py", line 118, in get_requires_for_build_wheel return hook(config_settings) ^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Temp\2\pip-build-env-_5qg5a97\overlay\Lib\site-packages\setuptools\build_meta.py", line 338, in get_requires_for_build_wheel return self._get_build_requires(config_settings, requirements=['wheel']) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Temp\2\pip-build-env-_5qg5a97\overlay\Lib\site-packages\setuptools\build_meta.py", line 320, in _get_build_requires self.run_setup() File "C:\Users\Administrator\AppData\Local\Temp\2\pip-build-env-_5qg5a97\overlay\Lib\site-packages\setuptools\build_meta.py", line 485, in run_setup self).run_setup(setup_script=setup_script) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Temp\2\pip-build-env-_5qg5a97\overlay\Lib\site-packages\setuptools\build_meta.py", line 335, in run_setup exec(code, locals()) File "", line 20, in File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\pathlib.py", line 1059, in read_text return f.read() ^^^^^^^^ File "C:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\encodings\cp1252.py", line 23, in decode return codecs.charmap_decode(input,self.errors,decoding_table)[0] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 148: character maps to [end of output]

    note: This error originates from a subprocess, and is likely not a problem with pip. error: subprocess-exited-with-error

    × Getting requirements to build wheel did not run successfully. │ exit code: 1 ╰─> See above for output.

    note: This error originates from a subprocess, and is likely not a problem with pip.

    How can I install thumbor on windows server? Please help me...

    opened by graphicseoul 0
  • Face detector working on some pics but not others. (Debug mode shows pixels)

    Face detector working on some pics but not others. (Debug mode shows pixels)

    Thumbor request URL

    The request url for the issue you are having, you can swap the host name with a fake This image below shows fine. mydomain<<:unsafe/debug/620x620/smart/https://images.healthshots.com/healthshots/en/uploads/2021/09/01154247/ice-on-face-1-770x433.jpg This image doesn't work. mydomain<<:/unsafe/debug/1920x620/smart/https://cdn.filestackcontent.com/pRGFW9N5RsCAJtoEqC9m Also got the Jpeg hosted and passed so it can't be the CDN. Try downloading the image. (Screenshot 2022-12-13 at 16 47 21 from https://newsroom.notified.com/gul-pr/media/68282/vilda-rosenblad-foto-anna-lena-ahlstromjpg)

    Expected behaviour

    Tell us what should happen I'd expect smart cropping.

    Actual behaviour

    Tell us what happens instead When cropped it cuts off the head and doesn't smart crop.

    Operating system

    This is run from the Docker container provided. https://github.com/thumbor/thumbor/blob/master/docker/Dockerfile with additions. Can provide if like.

    Your thumbor.conf

    Your config file (WARNING: replace your SECURITY_KEY key with a dummy key or your key will become public)

    Thumber.conf `from os.path import expanduser, join home = expanduser("~") PRESERVE_EXIF_INFO = False SEND_IF_MODIFIED_LAST_MODIFIED_HEADERS = False LOADER = "thumbor.loaders.http_loader" MAX_SOURCE_SIZE = 0 UPLOAD_ENABLED = False ENGINE = "thumbor.engines.pil" DETECTORS = [ 'thumbor.detectors.face_detector', 'thumbor.detectors.feature_detector', ]

    SECURITY_KEY = "*********" ALLOW_UNSAFE_URL = True HTTP_LOADER_CURL_ASYNC_HTTP_CLIENT = False MAX_AGE = 360000 MAX_AGE_TEMP_IMAGE = 60 MAX_WIDTH = 1920 QUALITY = 70 AUTO_WEBP = True `

    ------------- Below environment Variables ---------------------

    ENV VARS. AWS_STORAGE_ROOT_PATH=storage AUTO_WEBP=True AWS_RESULT_STORAGE_BUCKET_NAME=s3-j****** STORAGE=thumbor_aws.storage AWS_RESULT_STORAGE_S3_SECRET_ACCESS_KEY=************************** RESULT_STORAGE=thumbor_aws.result_storage AWS_STORAGE_BUCKET_NAME=s3-j*********** AWS_RESULT_STORAGE_S3_ACCESS_KEY_ID=**************** ALLOW_UNSAFE_URL=True AWS_STORAGE_S3_ACCESS_KEY_ID=******************** AWS_STORAGE_REGION_NAME=******** LOADER=thumbor.loaders.http_loader AWS_DEFAULT_LOCATION=https://s3-***************** HTTP_LOADER_VALIDATE_CERTS=False AWS_STORAGE_S3_SECRET_ACCESS_KEY=*********************** SECURITY_KEY=**************** AWS_STORAGE_S3_ENDPOINT_URL=https://s3-j**************** AWS_RESULT_STORAGE_ROOT_PATH=storage AWS_RESULT_STORAGE_S3_ENDPOINT_URL=https://s3-************** ALLOW_OLD_URLS=True AWS_RESULT_STORAGE_REGION_NAME=********

    opened by WebLeash 0
  • thumbor not being installed properly

    thumbor not being installed properly

    Thumbor v7.3.0 (of 01-Nov-2022)

    Thumbor doctor will analyze your install and verify if everything is working as expected.

    Verifying libraries support...

    ❎ pycurl is not installed. Thumbor works much better with PyCurl. For more information visit http://pycurl.io/.

    ❎ cairosvg is not installed. Thumbor uses CairoSVG for reading SVG files. For more information check https://cairosvg.org/.

    ❎ pyexiv2 is not installed. If you do not need EXIF metadata, you can safely ignore this. For more information visit https://python3-exiv2.readthedocs.io/en/latest/.

    Verifying thumbor compiled extensions...

    ✅ _alpha ✅ _bounding_box ✅ _brightness ✅ _colorize ✅ _composite ✅ _contrast ✅ _convolution ✅ _curve ✅ _equalize ✅ _fill ✅ _nine_patch ✅ _noise ✅ _rgb ✅ _round_corner ✅ _saturation ✅ _sharpen

    Verifying extension programs...

    ✅ jpegtran is installed correctly. ❎ ffmpeg is not installed. Thumbor uses ffmpeg for rendering animated images as GIFV. For more information visit https://www.ffmpeg.org/.

    ❎ gifsicle is not installed. Thumbor uses gifsicle for better processing of GIF images. For more information visit https://www.lcdf.org/gifsicle/.

    Verifying security...

    😞 Oh no! We found some things that could improve... 😞

    ⚠️Warnings⚠️

    • pyexiv2 Error Message: No module named 'pyexiv2'

      Error Description: If you do not need EXIF metadata, you can safely ignore this. For more information visit https://python3-exiv2.readthedocs.io/en/latest/.

    ⛔Errors⛔

    • pycurl Error Message: pycurl: libcurl link-time ssl backends (secure-transport, openssl) do not include compile-time ssl backend (none/other)

      Error Description: Thumbor works much better with PyCurl. For more information visit http://pycurl.io/.

    • cairosvg Error Message: No module named 'cairosvg'

      Error Description: Thumbor uses CairoSVG for reading SVG files. For more information check https://cairosvg.org/.

    • ffmpeg Error Message: Could not find ffmpeg.

      Error Description: Thumbor uses ffmpeg for rendering animated images as GIFV. For more information visit https://www.ffmpeg.org/.

    • gifsicle Error Message: Could not find gifsicle.

      Error Description:

    Stale 
    opened by TarangVarshney 1
  • Remove documentation on Ubuntu/Debian PPA

    Remove documentation on Ubuntu/Debian PPA

    opened by MattBlissett 1
  • "Forbidden" Issue with S3 bucket.

    Thumbor request URL

    example.com

    Expected behaviour

    File uploaded to S3 bucket.

    Actual behaviour

    _RROR ERROR: Traceback (most recent call last): File "/home/thumbor/venv/lib/python3.9/site-packages/tornado/web.py", line 1713, in _execute result = await result File "/home/thumbor/venv/lib/python3.9/site-packages/thumbor/handlers/imaging.py", line 119, in get return await self.check_image(kw) File "/home/thumbor/venv/lib/python3.9/site-packages/thumbor/handlers/imaging.py", line 28, in check_image exists = await self.context.modules.storage.exists( File "/home/thumbor/venv/lib/python3.9/site-packages/tc_aws/storages/s3_storage.py", line 116, in exists file_key = self.storage.get_key(file_abspath) File "/home/thumbor/venv/lib/python3.9/site-packages/boto/s3/bucket.py", line 193, in get_key key, resp = self._get_key_internal(key_name, headers, query_args_l) File "/home/thumbor/venv/lib/python3.9/site-packages/boto/s3/bucket.py", line 231, in get_key_internal raise self.connection.provider.storage_response_error( boto.exception.S3ResponseError: S3ResponseError: 403 Forbidden

    Operating system

    Base Image. python:3.9.15-slim-bullseye

    Your thumbor.conf

    HTTP_LOADER_VALIDATE_CERTS = "False" ALLOW_OLD_URLS = "True" ALLOW_UNSAFE_URL = "True" FORWARDED_ALLOWED_IPS = "0.0.0.0" SECURITY_KEY = "******" HTTP_ADDRESS = "0.0.0.0" AUTO_WEBP = "True" QUALITY = "70" MAX_AGE_TEMP_IMAGE = "60" AWS_ACCESS_KEY_ID = "*********" AWS_SECRET_ACCESS_KEY = "************" TC_AWS_REGION = "******" TC_AWS_STORAGE_BUCKET = "s3-bucket-name" TC_AWS_STORAGE_ROOT_PATH = "storage" TC_AWS_RESULT_STORAGE_BUCKET = "s3-bucket-name" TC_AWS_RESULT_STORAGE_ROOT_PATH = "result_storage" STORAGE = "tc_aws.storages.s3_storage" UPLOAD_PHOTO_STORAGE = "tc_aws.storages.s3_storage" COMPATIBILITY_LEGACY_LOADER = "tc_aws.loaders.s3_loader" LOADER = "thumbor.compatibility.loader" RESULT_STORAGE = "tc_aws.result_storages.s3_storage"

    opened by WebLeash 7
Releases(7.4.4)
  • 7.4.4(Jan 6, 2023)

    What's Changed

    • Fixed piexif load when exif tag is broken by @RaphaelVRossi in https://github.com/thumbor/thumbor/pull/1542

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.4.3...7.4.4

    Source code(tar.gz)
    Source code(zip)
  • 7.4.3(Jan 4, 2023)

    What's Changed

    • docs(thumbor): Link directly to 7.0.0 release notes for migration guide by @neilsh in https://github.com/thumbor/thumbor/pull/1538
    • fix: auto convert image with transparency by @devppjr in https://github.com/thumbor/thumbor/pull/1541

    New Contributors

    • @neilsh made their first contribution in https://github.com/thumbor/thumbor/pull/1538

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.4.2...7.4.3

    Source code(tar.gz)
    Source code(zip)
  • 7.4.2(Dec 21, 2022)

    What's Changed

    • Define image format by accept header by @devppjr in https://github.com/thumbor/thumbor/pull/1518
    • Update CODE_OF_CONDUCT.md by @Arkaroy147 in https://github.com/thumbor/thumbor/pull/1509
    • Hyperlinked the thumbor logo in readme.md by @Abubakrce19 in https://github.com/thumbor/thumbor/pull/1499
    • Fix Docs by @xuanyanwow in https://github.com/thumbor/thumbor/pull/1531

    New Contributors

    • @Arkaroy147 made their first contribution in https://github.com/thumbor/thumbor/pull/1509
    • @Abubakrce19 made their first contribution in https://github.com/thumbor/thumbor/pull/1499
    • @xuanyanwow made their first contribution in https://github.com/thumbor/thumbor/pull/1531

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.4.1...7.4.2

    Source code(tar.gz)
    Source code(zip)
  • 7.4.1(Dec 22, 2022)

    What's Changed

    • Release Thumbor wheels and add support to Python 3.11 by @guilhermef in https://github.com/thumbor/thumbor/pull/1498

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.3.2...7.4.1

    Source code(tar.gz)
    Source code(zip)
  • 7.3.2(Dec 20, 2022)

    What's Changed

    • chore(thumbor): Update metadata docs by @guilhermef in https://github.com/thumbor/thumbor/pull/1523
    • fix(doctor): Remove Pyexiv check by @guilhermef in https://github.com/thumbor/thumbor/pull/1522
    • Fix: Numpy 1.24.0 release is incompatible with Thumbor by @guilhermef in https://github.com/thumbor/thumbor/pull/1537

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.3.1...7.3.2

    Source code(tar.gz)
    Source code(zip)
  • 7.3.1(Dec 19, 2022)

    What's Changed

    • Documention spell check by @TiagoDanin in https://github.com/thumbor/thumbor/pull/1501
    • feat(thumbor): Replace pyexiv2 with piexif by @guilhermef in https://github.com/thumbor/thumbor/pull/1519
    • fix(engines): Try to import piexif and use it when available by @scorphus in https://github.com/thumbor/thumbor/pull/1524
    • keep exif copyright information by @devppjr in https://github.com/thumbor/thumbor/pull/1507
    • Revert "fix(engines): Try to import piexif and use it when available … by @maiagripp in https://github.com/thumbor/thumbor/pull/1530

    New Contributors

    • @TiagoDanin made their first contribution in https://github.com/thumbor/thumbor/pull/1501

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.3.0...7.3.1

    Source code(tar.gz)
    Source code(zip)
  • 7.3.0(Nov 1, 2022)

    What's Changed

    • Support for reading & writing HEIF files format using pillow_heif by @bigcat88 in https://github.com/thumbor/thumbor/pull/1510
    • Add missing runtime dependencies to Docker image by @Tenzer in https://github.com/thumbor/thumbor/pull/1508
    • test(pil): Mark a test as expected to fail by @scorphus in https://github.com/thumbor/thumbor/pull/1516
    • cleanup: Remove a dead line from README by @scorphus in https://github.com/thumbor/thumbor/pull/1515
    • Set default format when required format is not available by @RaphaelVRossi in https://github.com/thumbor/thumbor/pull/1512

    New Contributors

    • @bigcat88 made their first contribution in https://github.com/thumbor/thumbor/pull/1510
    • @Tenzer made their first contribution in https://github.com/thumbor/thumbor/pull/1508

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.2.1...7.3.0

    Source code(tar.gz)
    Source code(zip)
  • 7.2.1(Oct 21, 2022)

    What's Changed

    • GitHub Workflows security hardening by @sashashura in https://github.com/thumbor/thumbor/pull/1484
    • Add Thumbor official Docker image by @guilhermef in https://github.com/thumbor/thumbor/pull/1496

    New Contributors

    • @sashashura made their first contribution in https://github.com/thumbor/thumbor/pull/1484

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.2.0...7.2.1

    Source code(tar.gz)
    Source code(zip)
  • 7.2.0(Oct 20, 2022)

    What's Changed

    • feat: Support AVIF format encoding by @fdintino in https://github.com/thumbor/thumbor/pull/1476
    • Updated the correct link on Readme.mkd by @shendrekbharath in https://github.com/thumbor/thumbor/pull/1497
    • Update README.mkd by @JensColman in https://github.com/thumbor/thumbor/pull/1495
    • Fix library test example in docs and use python3 by @tchollingsworth in https://github.com/thumbor/thumbor/pull/1450

    New Contributors

    • @shendrekbharath made their first contribution in https://github.com/thumbor/thumbor/pull/1497
    • @JensColman made their first contribution in https://github.com/thumbor/thumbor/pull/1495
    • @tchollingsworth made their first contribution in https://github.com/thumbor/thumbor/pull/1450

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.1.2...7.2.0

    Source code(tar.gz)
    Source code(zip)
  • 7.1.2(Oct 19, 2022)

    What's Changed

    • Fix/background color auto by @siqueira-ec in https://github.com/thumbor/thumbor/pull/1489
    • Fixed load PSD files by @RaphaelVRossi in https://github.com/thumbor/thumbor/pull/1487
    • improve workflows adding isort by @devppjr in https://github.com/thumbor/thumbor/pull/1440
    • Adding docs for cover filter by @maiagripp in https://github.com/thumbor/thumbor/pull/1493

    New Contributors

    • @siqueira-ec made their first contribution in https://github.com/thumbor/thumbor/pull/1489

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.1.1...7.1.2

    Source code(tar.gz)
    Source code(zip)
  • 7.1.1(Sep 21, 2022)

    What's Changed

    • fix spurious write errors when STORES_CRYPTO_KEY_FOR_EACH_IMAGE is set to True by @fraenki in https://github.com/thumbor/thumbor/pull/1470
    • docs: Fix a few typos by @timgates42 in https://github.com/thumbor/thumbor/pull/1465
    • readme: Update Wikipedia logo by @Krinkle in https://github.com/thumbor/thumbor/pull/1460
    • Update libraries.rst by @beeyev in https://github.com/thumbor/thumbor/pull/1459
    • Remove unnecessary pass statement by @scorphus in https://github.com/thumbor/thumbor/pull/1481
    • Only call get_sampling on images with layers by @scorphus in https://github.com/thumbor/thumbor/pull/1480

    New Contributors

    • @fraenki made their first contribution in https://github.com/thumbor/thumbor/pull/1470
    • @Krinkle made their first contribution in https://github.com/thumbor/thumbor/pull/1460
    • @beeyev made their first contribution in https://github.com/thumbor/thumbor/pull/1459

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.1.0...7.1.1

    Source code(tar.gz)
    Source code(zip)
  • 7.1.0(Jul 27, 2022)

    What's Changed

    • Fix some typos and add missing whitespace by @jaap3 in https://github.com/thumbor/thumbor/pull/1447
    • Ensure socket from file descriptor is non-blocking by @jaap3 in https://github.com/thumbor/thumbor/pull/1449

    New Contributors

    • @jaap3 made their first contribution in https://github.com/thumbor/thumbor/pull/1447

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.12...7.1.0

    Source code(tar.gz)
    Source code(zip)
  • 7.0.12(Jul 8, 2022)

    What's Changed

    • added new validation in watermark filter to respect allowed sources configuration by @maiagripp in https://github.com/thumbor/thumbor/pull/1457

    New Contributors

    • @maiagripp made their first contribution in https://github.com/thumbor/thumbor/pull/1457

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.11...7.0.12

    Source code(tar.gz)
    Source code(zip)
  • 7.0.11(Jul 6, 2022)

    What's Changed

    • Fixed pylint execution error by @RaphaelVRossi in https://github.com/thumbor/thumbor/pull/1464
    • Added Redis Sentinel support by @RaphaelVRossi in https://github.com/thumbor/thumbor/pull/1439

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.10...7.0.11

    Source code(tar.gz)
    Source code(zip)
  • 7.0.10(May 20, 2022)

    What's Changed

    • Remove snapshottest to reduce number of dependencies by @scorphus in https://github.com/thumbor/thumbor/pull/1433
    • Apply filters in the same order as in the URI by @scorphus in https://github.com/thumbor/thumbor/pull/1435
    • py3exiv2 0.11.0 breaks python3.10 unit test by @RaphaelVRossi in https://github.com/thumbor/thumbor/pull/1436
    • Skip test from #1435 for python3.7 version by @RaphaelVRossi in https://github.com/thumbor/thumbor/pull/1438

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.9...7.0.10

    Source code(tar.gz)
    Source code(zip)
  • 7.0.9(May 1, 2022)

    ATTENTION

    In case your deployment/delivery pipelines do not rely on setup.py to install the set of dependencies, be aware that colorful has been replaced by colorama.

    What's Changed

    • ext/filters/_convolution: Apply convolution to alpha channel too by @scorphus in https://github.com/thumbor/thumbor/pull/1411
    • Include WebP files in MANIFEST.in by @marcelometal in https://github.com/thumbor/thumbor/pull/1426
    • Remove socketfromfd dependency to be able to launch thumbor with the --fd option by @ebilheude in https://github.com/thumbor/thumbor/pull/1422
    • Replace 'colorful' with 'colorama' by @marcelometal in https://github.com/thumbor/thumbor/pull/1427
    • Added pre-commit by @marcelometal in https://github.com/thumbor/thumbor/pull/1394
    • Improving URL composer by @marcelometal in https://github.com/thumbor/thumbor/pull/1430

    New Contributors

    • @ebilheude made their first contribution in https://github.com/thumbor/thumbor/pull/1422

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.8...7.0.9 PyPi release: https://pypi.org/project/thumbor/7.0.9/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.8(Apr 3, 2022)

    WARNING

    If you are using thumbor's gifv optimizer, please switch to use thumbor-plugins gifv optimizer instead. We will discontinue this plugin from thumbor's main codebase soon!

    Using it is pretty simple. Make sure you have installed it with pip install thumbor-plugins-gifv and then in your thumbor.conf:

    OPTIMIZERS = [
        'thumbor_plugins.optimizers.gifv',
    ]
    

    What's Changed

    • Add black formatter by @guilhermef in https://github.com/thumbor/thumbor/pull/1428
    • Fixed thumbor-url by @marcelometal in https://github.com/thumbor/thumbor/pull/1409
    • Moving gifv to thumbor-plugins by @guilhermef in https://github.com/thumbor/thumbor/pull/1423
    • Fixed issue #1417 with invalid usage of the same metric naming for two different metrics @heynemann

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.7...7.0.8 PyPi release: https://pypi.org/project/thumbor/7.0.8/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.7(Mar 16, 2022)

    What's Changed

    • README Improvements by @heynemann
    • CONTRIBUTING Improvements by @nicolasgabrielt and @marcelometal in #1402
    • Fix convolution filter by @RaphaelVRossi in #1419
    • Fix saturation filter by @devppjr in #1421
    • DOCS Improvements by @Chavao in #1415 and #1416
    • Fix TypeError in sentry error handler by @OndrejIT in #1420
    • Build test image on Github action by @guilhermef in #1414

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.6...7.0.7 PyPi release: https://pypi.org/project/thumbor/7.0.7/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.6(Jan 27, 2022)

    Potential Breaking Change

    This should've been a major, but it should not cause major issues. If your thumbor install depends on OpenCV, instead of installing thumbor with pip install thumbor use pip install thumbor[all] and opencv-python-headless will be installed with it. Otherwise, if you already have OpenCV installed, no issues.

    To make sure everything is smooth, just run thumbor-doctor -c <your thumbor.conf file> and thumbor will verify it can import OpenCV (if you are using it in some way).

    What's Changed

    • Feature/optional opencv by @heynemann in https://github.com/thumbor/thumbor/pull/1400
    • README Improvements by @heynemann in https://github.com/thumbor/thumbor/pull/1401

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.5...7.0.6 PyPi release: https://pypi.org/project/thumbor/7.0.6/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.5(Jan 26, 2022)

    What's Changed

    • Remove mock library dependency by @jairhenrique in https://github.com/thumbor/thumbor/pull/1396
    • Allowed sources work in file_loader_http_fallback by @heynemann in https://github.com/thumbor/thumbor/pull/1399
    • Fixed mock import by @marcelometal in https://github.com/thumbor/thumbor/pull/1398
    • doctor: fix errors when there is no config by @marcelometal in https://github.com/thumbor/thumbor/pull/1397

    New Contributors

    • @jairhenrique made their first contribution in https://github.com/thumbor/thumbor/pull/1396

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.3...7.0.5 PyPi Release: https://pypi.org/project/thumbor/7.0.5/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.4(Jan 26, 2022)

    This release should not be used, it was made in error

    Please refrain from using 7.0.4. We're removing it from pypi, but leaving this note here, just in case.

    Source code(tar.gz)
    Source code(zip)
  • 7.0.3(Jan 24, 2022)

    What's Changed

    • Updating cairosvg by @heynemann in https://github.com/thumbor/thumbor/pull/1389
    • fancy readme by @mvhirsch in https://github.com/thumbor/thumbor/pull/1392
    • Updated pillow version due to security issues by @heynemann in https://github.com/thumbor/thumbor/pull/1390
    • Smarter thumbor doctor by @heynemann in https://github.com/thumbor/thumbor/pull/1393

    New Contributors

    • @mvhirsch made their first contribution in https://github.com/thumbor/thumbor/pull/1392

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.2...7.0.3 PyPI Release: https://pypi.org/project/thumbor/7.0.3/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.2(Jan 22, 2022)

    What's Changed

    • fix(filter/proportion): Fix crash with impossible proportion constraint by @amccloud in https://github.com/thumbor/thumbor/pull/1327
    • thumbor.conf, black it! by @marcelometal in https://github.com/thumbor/thumbor/pull/1386
    • Allow sending a Access-Control-Allow-Origin header by @relthyg in https://github.com/thumbor/thumbor/pull/1375

    New Contributors

    • @amccloud made their first contribution in https://github.com/thumbor/thumbor/pull/1327

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.1...7.0.2 PyPi Release: https://pypi.org/project/thumbor/7.0.2/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.1(Jan 22, 2022)

    This release fixes a bug with the 7.0.0 refactor of the codebase when images were generated with MAX_WIDTH or MAX_HEIGHT configurations. For more information check #1384.

    What's Changed

    • Update whos_using_it.rst by @gabriel-kaam in https://github.com/thumbor/thumbor/pull/1383
    • Update doc for Custom Error Handlers by @gabriel-kaam in https://github.com/thumbor/thumbor/pull/1382
    • Bug with normalize during refactor in thumbor 7 by @heynemann in https://github.com/thumbor/thumbor/pull/1391

    New Contributors

    • @gabriel-kaam made their first contribution in https://github.com/thumbor/thumbor/pull/1383

    Full Changelog: https://github.com/thumbor/thumbor/compare/7.0.0...7.0.1 PyPI Release: https://pypi.org/project/thumbor/7.0.1/

    Source code(tar.gz)
    Source code(zip)
  • 6.7.6(Jan 22, 2022)

    This is a release for Python 2 and you are strongly advised to move to the 7.x line of releases in python 3 as the support for python 2 will be removed in the future.

    What's Changed

    • [FIX] Ability to listen to a socket passed as file descriptor by @gael-ian in https://github.com/thumbor/thumbor/pull/1281
    • Allow sending a Access-Control-Allow-Origin header (6.7.x branch) by @relthyg in https://github.com/thumbor/thumbor/pull/1374

    New Contributors

    • @gael-ian made their first contribution in https://github.com/thumbor/thumbor/pull/1281

    Full Changelog: https://github.com/thumbor/thumbor/compare/6.7.5...6.7.6 PyPi Release: https://pypi.org/project/thumbor/6.7.6/

    Source code(tar.gz)
    Source code(zip)
  • 7.0.0(Feb 27, 2020)

    Installing

    $ pip install "thumbor>=7.0.0"
    $ thumbor-doctor
    

    Keep on reading for the changes you need to be aware of. If you experience any problems, please run thumbor-doctor --nocolor and create an issue with your problem and the results of running thumbor-doctor.

    Introduction

    This release notes will be slightly different from others as we need to have more of a conversation on what happened. We'll detail the changes below, but first let's explain them.

    We set out to update thumbor to work with python3. During the work required to do that, it became clear that we were going to break most extensions with this release.

    At this point we made a decision to not only update thumbor to python3, but completely modernize it.

    Some of the 7.0.0 features:

    • Python 3.6+ support. Python 2 is not supported anymore (does not even work).
    • Updated tornado to release 6.0.3. This should fix many bugs/vulnerabilities we still had due to old tornado.
    • Updated pillow version to >= 7.0.0, <9 (meaning you should get latest pillow as it is in 8.4.0).
    • All tests now run using py.test.
    • Updated every dependency we could update.

    While updating the codebase to support new tornado and python 3 we also decided to get rid of the callback hell that tormented the committers for the last 10 years or so. The new codebase uses proper async/await idioms for all the asynchronous code.

    As a bonus for this update, we added a new concept to customizing thumbor: handler lists. It has been a request for a long time to allow thumbor extensions to add new handlers to thumbor. Well, now you can!

    Now that you understand why we broke compatibility with many constructs previously in place, be assured that the committers worked hard to make the transition as easy as possible. We added a compatibility layer to ease the transition to the new way of writing Loaders, Result Storages and Storages. This means you get to use your current extensions as long as they are python 3 compatible. We even monkey-patched tornado (very safely) to ensure these extensions can keep using return_future as it has been removed from tornado entirely.

    Last, but not least, we decided not to support python 2 anymore. We'll keep updating the 6.7.x branch with bug fixes, but new features are going to be focused on python3 and thumbor7.

    Lets get to the details!

    Breaking Changes

    First let's see what breaks (apart from not supporting python 2, that is).

    Storages

    Previously storages were implemented like this (this is NoStorage):

    class Storage(BaseStorage):
    
        def put(self, path, bytes):
            return path
    
        def put_crypto(self, path):
            return path
    
        def put_detector_data(self, path, data):
            return path
    
        @return_future
        def get_crypto(self, path, callback):
            callback(None)
    
        @return_future
        def get_detector_data(self, path, callback):
            callback(None)
    
        @return_future
        def get(self, path, callback):
            callback(None)
    
        @return_future
        def exists(self, path, callback):
            callback(False)
    
        def remove(self, path):
            pass
    

    With release 7.0.0 we modernize these functions to be async. The same storage in the new release:

    class Storage(BaseStorage):
        async def put(self, path, file_bytes):
            return path
    
        async def put_crypto(self, path):
            return path
    
        async def put_detector_data(self, path, data):
            return path
    
        async def get_crypto(self, path):
            return None
    
        async def get_detector_data(self, path):
            return None
    
        async def get(self, path):
            return None
    
        async def exists(self, path):
            return False
    
        async def remove(self, path):
            pass
    

    Much simpler, right? No funky callback business. The downside is that all storages out there need to be updated. It should be simply a matter of "asyncifying" them.

    That said, if you can't (or don't know how) to update them, you can use the compatibility layer provided by thumbor to aid you:

    thumbor.conf

    # how to store the loaded images so we don't have to load
    # them again with the loader
    STORAGE = 'thumbor.compatibility.storage'
    
    ## 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.
    ## Defaults to: None
    COMPATIBILITY_LEGACY_STORAGE = 'tc_aws.storages.s3_storage'
    

    With this configuration, thumbor will understand how to call the methods with callbacks from previous releases.

    Loaders

    The same applies to loaders. Let's see what a loader looked like in 6.7.2:

    @return_future
    def load(context, path, callback):
        # does a lot of stuff and :(
        callback(loaded_image)
    

    Now in 7.0.0 it is a simple async function:

    async def load(context, path):
        # does a lot of stuff with no callbacks whatsoever
        return loader_result
    

    It's much simpler to understand the new loaders (and to create new ones), but the same issue as above: previous loaders won't work with thumbor 7.0.0+ (until asyncified). Important note: going forward, loaders should return LoaderResult object. While returning plain image bytes still works, it's encouraged to update loaders to return object.

    Once again, if you can't (or don't know how) to update them, you can use the compatibility layer provided by thumbor to aid you:

    thumbor.conf

    LOADER = 'thumbor.compatibility.loader'
    
    ## 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.
    ## Defaults to: None
    # COMPATIBILITY_LEGACY_LOADER = 'tc_aws.loaders.s3_loader'
    

    With this configuration, thumbor will understand how to call the methods with callbacks from previous releases.

    Result Storages

    You get the gist, right? NoStorage Result Storage in 6.7.2:

    class Storage(BaseStorage):
        # THIS METHOD IS NOT EVEN ASYNC :(
        def put(self, bytes):
            return ''
    
        @return_future
        def get(self, callback):
            callback(None)
    

    Now in 7.0.0+:

    class Storage(BaseStorage):
        async def put(self, image_bytes):
            return ""
    
        async def get(self):
            return None
    

    Previous result storages won't work with thumbor 7.0.0+ (until asyncified).

    Getting repetitive here, but if you can't (or don't know how) to update them, you can use the compatibility layer provided by thumbor to aid you:

    thumbor.conf

    RESULT_STORAGE = 'thumbor.compatibility.result_storage'
    
    ## 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.
    ## Defaults to: None
    COMPATIBILITY_LEGACY_RESULT_STORAGE = 'tc_aws.result_storages.s3_storage'
    

    With this configuration, thumbor will understand how to call the methods with callbacks from previous releases.

    Tornado Compatibility

    If any of the compatibility extensions are used (storage, loader, result storage), then thumbor verifies whether tornado has a tornado.concurrent.return_future decorator. If it does, then thumbor won't change it. If it's not there, we add a decorator that won't do anything.

    The intention here is to ensure that previous extensions keep working with the compatibility layer.

    Please understand that the compatibility layer will NOT:

    • Update your extension to be python 3 compliant;
    • Make your extension non-blocking. If you have blocking methods, they'll keep blocking thumbor anyway.

    Filters

    Same ol', same ol'. Let's check format filter in 6.7.2.

    class Filter(BaseFilter):
    
        @filter_method(BaseFilter.String)
        def format(self, format):
            if format.lower() not in ALLOWED_FORMATS:
                logger.debug('Format not allowed: %s' % format.lower())
                self.context.request.format = None
            else:
                logger.debug('Format specified: %s' % format.lower())
                self.context.request.format = format.lower()
    

    Now the same filter in 7.0.0:

    class Filter(BaseFilter):
        @filter_method(BaseFilter.String)
        async def format(self, file_format):
            if file_format.lower() not in ALLOWED_FORMATS:
                logger.debug("Format not allowed: %s", file_format.lower())
                self.context.request.format = None
            else:
                logger.debug("Format specified: %s", file_format.lower())
                self.context.request.format = file_format.lower()
    

    Hardly noticeable, right? Except now you get to run async code in your filters without arcane magic or callbacks. As with all the others, previous filters won't work with thumbor 7.0.0+ (until asyncified).

    For this and detectors (below) we do not provide compatibility layer as we understand them to be easier to update. If you have a scenario that requires these, let us know.

    Detectors

    These were also modernized. Let's take a look at our face detector in 6.7.2:

    class Detector(CascadeLoaderDetector):
        # details removed for clarity
    
        def detect(self, callback):
            features = self.get_features()
            if features:
                for (left, top, width, height), neighbors in features:
                    top = self.__add_hair_offset(top, height)
                    self.context.request.focal_points.append(
                        FocalPoint.from_square(left, top, width, height, origin="Face Detection")
                    )
                callback()
            else:
                self.next(callback)
    

    Now the same detector in 7.0.0+:

    class Detector(CascadeLoaderDetector):
        # details removed for clarity
    
        async def detect(self):
            features = self.get_features()
            if features:
                for (left, top, width, height), _ in features:
                    top = self.__add_hair_offset(top, height)
                    self.context.request.focal_points.append(
                        FocalPoint.from_square(
                            left, top, width, height, origin="Face Detection"
                        )
                    )
                return
    
            await self.next()
    

    No more callbacks and now detector pipeline works by awaiting the next detector or just a plain early return to stop the pipe. As with the other updates, previous detectors will not work with thumbor 7.0.0 (until asyncified).

    For detectors we do not provide compatibility layer as we understand them to be easier to update. If you have a scenario that requires these, let us know.

    Improvements

    Thumbor Testing Tools

    This one is for you, an extension author! Thumbor now includes a thumbor.testing module that ships with it and allows extensions to create tests that get thumbor up and running easier. An example test from our code:

    from preggy import expect
    from tornado.testing import gen_test
    
    from thumbor.testing import TestCase
    from thumbor.storages.no_storage import Storage as NoStorage
    
    class NoStorageTestCase(TestCase):
        def get_image_url(self, image):
            return "s.glbimg.com/some/{0}".format(image)
    
        @gen_test
        async def test_store_image_should_be_null(self):
            iurl = self.get_image_url("source.jpg")
            storage = NoStorage(None)
            stored = await storage.get(iurl)
            expect(stored).to_be_null()
    
       # many more tests!
    

    Notice how the test can now test only what it needs to. We're using py.test now and that allows async test methods.

    WARNING: If you use thumbor.testing you need to also add "mock==3.,>=3.0.5" and "pyssim==0.,>=0.4.0" as dev dependencies of your package, as these are used in thumbor.testing. We didn't add these as dependencies for thumbor as it would require every thumbor user to also install them alongside thumbor and they are only useful for testing.

    Revised Docs

    The many fundamental changes in thumbor prompted a major review of the docs and improvement of many areas in it. Please help us improve the docs if you feel like contributing.

    Handler Lists

    Not all is breaking changes, though. Now you get to extend thumbor with new handlers! And it is as simple as creating a module with:

       from typing import Any, cast
    
       from thumbor.handler_lists import HandlerList
    
       from my.handlers.index import IndexHandler  # This is your code <--
    
       def get_handlers(context: Any) -> HandlerList:
           something_enabled = cast(bool, self.context.config.SOMETHING_ENABLED)
           if not something_enabled:
               return []
           return [
               (r"/my-url/?", IndexHandler, {"context": self.context}),
           ]
    

    Then including it in thumbor.conf:

       from thumbor.handler_lists import BUILTIN_HANDLERS
    
       # Two things worth noticing here:
       # 1) The handler list order indicates precedence, so whatever matches first will be executed;
       # 2) Please do not forget thumbor's built-ins or you'll kill thumbor functionality.
       HANDLER_LISTS = BUILTIN_HANDLERS + [
           "my.handler_list',
       ]
    

    Acknowledgements

    This release would not be possible without the work of thumbor's commiters. I'd like to call out the work of @kkopachev that has enabled me (@heynemann) to move forward with this release.

    Again thanks @kkopachev for all the code reviews and thanks the whole of thumbor community for catching errors when I hadn't even written the release notes! That's nothing short of amazing.

    Now onto the not comprehensive list of changes in this release!

    Fixes/Features

    • Fix typo (thanks @timgates42);
    • Python 3 support (thanks @kkopachev);
    • Removed callbacks in favor of async-await;
    • Simplified pillow feature checks (thanks @kkopachev);
    • Extensive work to improve codebase quality (lint errors should be few now);
    • Using stdlib which instead of a custom one (thanks @kkopachev);
    • Major documentation review;
    • Added handler lists to allow further extension;
    • Update classifiers and add python_requires to help pip (thanks @hugovk);
    • Ability to run thumbor in multiprocess mode (thanks @kkopachev);
    • Python 3.6 support (thanks @amanagr);
    • New thumbor-doctor command to help diagnose issues with installs;
    • New compatibility layer for using legacy storages, loaders and result storages.

    Contribution List

    • Asyncawait2 by @heynemann in https://github.com/thumbor/thumbor/pull/1257
    • [IMPR] Use stdlib's shutil.which instead of custom one by @kkopachev in https://github.com/thumbor/thumbor/pull/1262
    • [IMPR] Revising docs for 7.0.0 release by @heynemann in https://github.com/thumbor/thumbor/pull/1267
    • [FEAT] URL Routers support by @heynemann in https://github.com/thumbor/thumbor/pull/1261
    • [FIX] Ability to listen on unix sockets by @kkopachev in https://github.com/thumbor/thumbor/pull/1272
    • [IMPR] Performance tests by @heynemann in https://github.com/thumbor/thumbor/pull/1273
    • Update classifiers and add python_requires to help pip by @hugovk in https://github.com/thumbor/thumbor/pull/1283
    • [FEAT] Ability to run thumbor in multiprocess mode by @kkopachev in https://github.com/thumbor/thumbor/pull/1276
    • Add Python 3.6 Support to thumbor library. by @amanagr in https://github.com/thumbor/thumbor/pull/1282
    • [FEAT] thumbor-doctor by @heynemann in https://github.com/thumbor/thumbor/pull/1284
    • cherry-picked [FIX] Ability to listen to a socket passed as file descriptor by @kkopachev in https://github.com/thumbor/thumbor/pull/1287
    • [IMPR] Add docs describing how to run thumbor multiprocess by @kkopachev in https://github.com/thumbor/thumbor/pull/1288
    • Update libraries.rst by @marlonnardi in https://github.com/thumbor/thumbor/pull/1295
    • Minor documentation typo by @sunny in https://github.com/thumbor/thumbor/pull/1303
    • Pin py3exiv2 to a version < 0.8.0 by @znerol in https://github.com/thumbor/thumbor/pull/1318
    • [DOCS] Update instructions on installing OSX deps by @scorphus in https://github.com/thumbor/thumbor/pull/1320
    • Make python binary configurable in Makefile by @gi11es in https://github.com/thumbor/thumbor/pull/1328
    • [FIX] Make fill with blur engine-agnostic by @scorphus in https://github.com/thumbor/thumbor/pull/1323
    • [FEAT] Improvement of our build and CircleCI by @heynemann in https://github.com/thumbor/thumbor/pull/1341
    • [FIX] Exclude py3exiv2 version 0.9.3 by @scorphus in https://github.com/thumbor/thumbor/pull/1340
    • Allow remotecv 3.x by @gi11es in https://github.com/thumbor/thumbor/pull/1331
    • Fix HTTP 500 when request path points to directory by @f90d83a8 in https://github.com/thumbor/thumbor/pull/1329
    • Upgrade pillow and pytz requirements by @andersk in https://github.com/thumbor/thumbor/pull/1321
    • UPLOAD_MAX_SIZE is calculated in bytes by @istovatis in https://github.com/thumbor/thumbor/pull/1315
    • add timings and counters for Smart and None Smart option by @mohammedelhakim in https://github.com/thumbor/thumbor/pull/1251
    • Configure GitHub Actions by @scorphus in https://github.com/thumbor/thumbor/pull/1324
    • [fix] Lint fixes by @heynemann in https://github.com/thumbor/thumbor/pull/1343
    • [FIX] Add pylint to GitHub Actions workflow too by @scorphus in https://github.com/thumbor/thumbor/pull/1344
    • correct typo in usage.rst by @dessert1 in https://github.com/thumbor/thumbor/pull/1355
    • [Fix] Docs: code formatting error and link error by @ThesllaDev in https://github.com/thumbor/thumbor/pull/1369
    • DOCS readme correction by @christopherdarling in https://github.com/thumbor/thumbor/pull/1368
    • [IMPR] Compatibility loader,storage,res storage by @heynemann in https://github.com/thumbor/thumbor/pull/1342
    • fix(gifv): Adding webm required bitrate parameter by @guilhermef in https://github.com/thumbor/thumbor/pull/1377
    • Fix/lint by @heynemann in https://github.com/thumbor/thumbor/pull/1378
    • Updated min pillow version by @heynemann in https://github.com/thumbor/thumbor/pull/1376

    New Contributors

    • @hugovk made their first contribution in https://github.com/thumbor/thumbor/pull/1283
    • @amanagr made their first contribution in https://github.com/thumbor/thumbor/pull/1282
    • @marlonnardi made their first contribution in https://github.com/thumbor/thumbor/pull/1295
    • @sunny made their first contribution in https://github.com/thumbor/thumbor/pull/1303
    • @f90d83a8 made their first contribution in https://github.com/thumbor/thumbor/pull/1329
    • @istovatis made their first contribution in https://github.com/thumbor/thumbor/pull/1315
    • @mohammedelhakim made their first contribution in https://github.com/thumbor/thumbor/pull/1251
    • @dessert1 made their first contribution in https://github.com/thumbor/thumbor/pull/1355
    • @ThesllaDev made their first contribution in https://github.com/thumbor/thumbor/pull/1369
    • @christopherdarling made their first contribution in https://github.com/thumbor/thumbor/pull/1368

    Full Changelog: https://github.com/thumbor/thumbor/compare/6.7.1...7.0.0 Pypi release: https://pypi.org/project/thumbor/7.0.0/

    Source code(tar.gz)
    Source code(zip)
  • 6.7.5(Mar 9, 2020)

  • 6.7.3(Feb 29, 2020)

  • 6.7.2(Feb 26, 2020)

  • 6.7.1(Feb 3, 2020)

    Changelog

    Fixes

    • Fix for a bug that blocked tornado thread (#1151 thanks @Tideorz);
    • Fix numpy not writable ndarray (#1171 thanks @cristiandean);
    • Fix FocalPoint from_dict now returns integer (#1172 thanks @cristiandean);
    • Replace dots in original image's source with underscore to prevent stats hierarchy levels being created (#1241 thanks @dfrieling).

    Improvements

    • Improved fill filter to suport blur (#1159 thanks @andrejguran);
    • Added transparent support to rounded corner filter (#1163 thanks @AlterTable);
    • Add SENTRY_ENVIRONMENT configuration (#1170 thanks @cristiandean);
    • Replace piexif with custom orientation-only exif reader/writer (#1210 thanks @kkopachev);
    • Lossless webp when quality is 100 (#1230 thanks @ehlertij);
    • Prevent healthcheck from being cached (#1205 thanks @guilhermearaujo).

    Modernizing

    • Replace 'pycryptodome' with 'pycryptodomex' (#1173 thanks @marcelometal);
    • MANIFEST.in: Add LICENSE and tests (#1179 thanks @jayvdb);
    • Allow Pillow 6.x (#1232 thanks both @andersk and @bagipriyank);
    • Replace Raven with new Sentry SDK (#1167 thanks @tjb346);
    • Travis updated to Ubuntu Xenial: drop trusty-media repo, add libgnutls (#1207 thanks @kkopachev);
    • Removing old Crypto module (#1198 thanks @kkopachev).

    Docs

    • Added thumbor_spaces plugin (#1158 thanks @siddhartham);
    • Updated contributing.md (thanks @marcelometal);
    • Fix readme.mkd badges (#1177 thanks @cristiandean);
    • Update MAX/MIN_WIDTH and MAX/MIN_HEIGHT configuration docs (#1183 thanks @HectorNM);
    • Update how_to_upload_images.rst (thanks @codechelon);
    • Update thumbor logo in docs (#1225 thanks @matgomes);
    • Fix link to blog post of Squareup in docs (#1250 thanks @ad-m);
    • Add 'thumbor-video-engine' to plugin documentation (#1247 thanks @fdintino);
    • Fix simple typo: transparant -> transparent (#1244 thanks @timgates42).

    Diff to previous release Pypi release

    Source code(tar.gz)
    Source code(zip)
Owner
Thumbor (by @globocom)
Thumbor organization is meant to hold all projects related to thumbor maintained by globo.com.
Thumbor (by @globocom)
API to help generating QR-code for ZATCA's e-invoice known as Fatoora with any programming language

You can try it @ api-fatoora api-fatoora API to help generating QR-code for ZATCA's e-invoice known as Fatoora with any programming language Disclaime

نافع الهلالي 12 Oct 05, 2022
Nudity detection with Python

nude.py About Nudity detection with Python. Port of nude.js to Python. Installation from pip: $ pip install --upgrade nudepy from easy_install: $ eas

Hideo Hattori 881 Jan 06, 2023
MaryJane is a simple MJPEG server written in Python.

MaryJane is a simple MJPEG server written in Python.

bootrino 152 Dec 13, 2022
A tool for hiding data inside of images

Stegenography-tool a tool for hiding data inside of images Quick test: do python steg-encode.py test/message.txt test/covid19.png to generate the test

luke 2 Nov 02, 2021
reversable image censoring tool

StupidCensor a REVERSABLE image censoring tool to reversably mosiac censor jpeg files to temporarily remove image details not allowed on most websites

2 Jan 28, 2022
Napari simpleitk image processing

napari-simpleitk-image-processing (n-SimpleITK) Process images using SimpleITK in napari Usage Filters of this napari plugin can be found in the Tools

Robert Haase 11 Dec 19, 2022
Generative Art Synthesizer - a python program that generates python programs that generates generative art

GAS - Generative Art Synthesizer Generative Art Synthesizer - a python program that generates python programs that generates generative art. Examples

Alexey Borsky 43 Dec 03, 2022
Image2scan - a python program that can be applied on an image in order to get a scan of it back

image2scan Purpose image2scan is a python program that can be applied on an image in order to get a scan of it back. For this purpose, it searches for

Kushal Shingote 2 Feb 13, 2022
A procedural Blender pipeline for photorealistic training image generation

BlenderProc2 A procedural Blender pipeline for photorealistic rendering. Documentation | Tutorials | Examples | ArXiv paper | Workshop paper Features

DLR-RM 1.8k Jan 02, 2023
Craft PNG files that appear completely different in Apple software

Ambiguous PNG Packer Craft PNG files that appear completely different in Apple software

David Buchanan 1k Dec 29, 2022
A functional and efficient python implementation of the 3D version of Maxwell's equations

py-maxwell-fdfd Solving Maxwell's equations via A python implementation of the 3D curl-curl E-field equations. This code contains additional work to e

Nathan Zhao 12 Dec 11, 2022
A simple programming language for manipulating images.

f-stop A simple programming language for manipulating images. Examples OPEN "image.png" AS image RESIZE image (300, 300) SAVE image "out.jpg" CLOSE im

F-Stop 6 Oct 27, 2022
Automatic picture transmission(APT) protocol decoder for NOAA weather satellites

Automatic picture transmission(APT) decoder Automatic picture transmission protocol is used by NOAA satellites. They constantly send a frequency modul

Jayachandra Kasarla 25 Aug 05, 2022
Command line utility for converting images to seamless tiles

img2texture Command line utility for converting images to seamless tiles. The resulting tiles can be used as textures in games, compositing and 3D mod

Artёm IG 24 Dec 26, 2022
HyperBlend is a new type of hyperspectral image simulator based on Blender.

HyperBlend version 0.1.0 This is the HyperBlend leaf spectra simulator developed in Spectral Laboratory of University of Jyväskylä. You can use and mo

SILMAE 2 Jun 20, 2022
Simple AI app that is guessing color of apple in picture

Apple Color Determinant Application that is guessing color of apple from image Install Pillow, sklearn and numpy, using command for your package manag

Gleb Nikitin 1 Oct 25, 2021
🎨 Generate and change color-schemes on the fly.

Generate and change color-schemes on the fly. Pywal is a tool that generates a color palette from the dominant colors in an image. It then applies the

dylan 6.9k Jan 03, 2023
Program designed to mass edit and watermark all photos in a directory

Photographer-All-In-One This is a program designed for photographers to mass edit or watermark photos (.jpg || .png) You can run this program from any

Brad Martin 2 Nov 23, 2021
This is the official source code of FreeCAD, a free and opensource multiplatform 3D parametric modeler.

Freedom to build what you want FreeCAD is an open-source parametric 3D modeler made primarily to design real-life objects of any size. Parametric modeling allows you to easily modify your design by g

FreeCAD 12.9k Jan 07, 2023
Ascify-Art - An easy to use, GUI based and user-friendly colored ASCII art generator from images!

Ascify-Art This is a python based colored ASCII art generator for free! How to Install? You can download and use the python version if you want, modul

Akash Bora 14 Dec 31, 2022