Fork me on GitHub

sqlalchemy_imageattach.stores.fs — Filesystem-backed image storage

It provides two filesystem-backed image storage implementations:

FileSystemStore
It stores image files into the filesystem of the specified path, but locate() method returns URLs of the hard-coded base URL.
HttpExposedFileSystemStore
The mostly same to FileSystemStore except it provides WSGI middleware (wsgi_middleware()) which actually serves image files and its locate() method returns URLs based on the actual requested URL.
class sqlalchemy_imageattach.stores.fs.BaseFileSystemStore(path)

Abstract base class of FileSystemStore and HttpExposedFileSystemStore.

class sqlalchemy_imageattach.stores.fs.FileSystemStore(path, base_url)

Filesystem-backed storage implementation with hard-coded URL routing.

class sqlalchemy_imageattach.stores.fs.HttpExposedFileSystemStore(path, prefix='__images__', host_url_getter=None, cors=False)

Filesystem-backed storage implementation with WSGI middleware which serves actual image files.

from flask import Flask
from sqlalchemy_imageattach.stores.fs import HttpExposedFileSystemStore

app = Flask(__name__)
fs_store = HttpExposedFileSystemStore('userimages', 'images/')
app.wsgi_app = fs_store.wsgi_middleware(app.wsgi_app)

To determine image urls, the address of server also has to be determined. Although it can be automatically detected using wsgi_middleware(), WSGI unfortunately is not always there. For example, Celery tasks aren’t executed by HTTP requests, so there’s no reachable Host header.

When its host url is not determined you would get RuntimeError if you try locating image urls:

Traceback (most recent call last):
  ...
  File "/.../sqlalchemy_imageattach/stores/fs.py", line 93, in get_url
    base_url = self.base_url
  File "/.../sqlalchemy_imageattach/stores/fs.py", line 151, in base_url
    type(self)
RuntimeError: could not determine image url. there are two ways to workaround this:
- set host_url_getter parameter to sqlalchemy_imageattach.stores.fs.HttpExposedFileSystemStore
- use sqlalchemy_imageattach.stores.fs.HttpExposedFileSystemStore.wsgi_middleware
see docs of sqlalchemy_imageattach.stores.fs.HttpExposedFileSystemStore for more details

For such case, you can optionally set host_url_getter option. It takes a callable which takes no arguments and returns a host url string like 'http://servername/'.

fs_store = HttpExposedFileSystemStore(
    'userimages', 'images/',
    host_url_getter=lambda:
        'https://{0}/'.format(app.config['SERVER_NAME'])
)
Parameters:
  • path (str) – file system path of the directory to store image files
  • prefix (str) – the prepended path of the url. '__images__' by default
  • host_url_getter (Callable[[], str]) – optional parameter to manually determine host url. it has to be a callable that takes nothing and returns a host url string
  • cors (bool) – whether or not to allow the Cross-Origin Resource Sharing for any origin

New in version 1.0.0: Added host_url_getter option.

wsgi_middleware(app, cors=False)

WSGI middlewares that wraps the given app and serves actual image files.

fs_store = HttpExposedFileSystemStore('userimages', 'images/')
app = fs_store.wsgi_middleware(app)
Parameters:app (Callable[[], Iterable[bytes]]) – the wsgi app to wrap
Returns:the another wsgi app that wraps app
Return type:StaticServerMiddleware
class sqlalchemy_imageattach.stores.fs.StaticServerMiddleware(app, url_path, dir_path, block_size=8192, cors=False)

Simple static server WSGI middleware.

Parameters:
  • app (Callable[[], Iterable[bytes]]) – the fallback app when the path is not scoped in url_path
  • url_path (str) – the exposed path to url
  • dir_path (str) – the filesystem directory path to serve
  • block_size (numbers.Integral) – the block size in bytes
  • cors (bool) – whether or not to allow the Cross-Origin Resource Sharing for any origin
sqlalchemy_imageattach.stores.fs.guess_extension(mimetype)

Finds the right filename extension (e.g. '.png') for the given mimetype (e.g. image/png).

Parameters:mimetype (str) – mimetype string e.g. 'image/jpeg'
Returns:filename extension for the mimetype
Return type:str