API Reference

attachments Module

Attachment

class sqlalchemy_media.attachments.Attachment[source]

Bases: sqlalchemy.ext.mutable.MutableDict

The base model for an attached file. All attachment types will be inherited from this class.

Actually this is an instance of sqlalchemy.ext.mutable.MutableDict which inherited from dict.

>>> from sqlalchemy_media import Attachment
>>> print(Attachment(key1='Value1'))
{'key1': 'Value1'}

This object should be used inside a StoreManager context.

    Changed in version 0.5:
  • removed __analyzer__ attribute, using __pre_processors__ instead.

  • removed __validate__ attribute, using __pre_processors__ instead.

    New in version 0.9.6:
  • reproducible

__directory__ = 'attachments'

The directory name of the file.

__prefix__ = 'attachment'

The prefix to be prepended an the name of the file.

__max_length__ = None

Limit the file’s maximum size.

__min_length__ = None

Limit the file’s minimum size.

__pre_processors__ = None
__auto_coercion__ = False
__reproducible__ = False

The reproducible of the file.

__descriptor__ = <class 'sqlalchemy_media.descriptors.AttachableDescriptor'>

It allows to customize the Descriptor.

attach(attachable: Union[str, dict, IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper, Iterable[Iterable[Any]]], content_type: str = None, original_filename: str = None, extension: str = None, store_id: str = None, overwrite: bool = False, suppress_pre_process: bool = False, suppress_validation: bool = False, **kwargs) → sqlalchemy_media.attachments.Attachment[source]

Attach a file. if the session is rolled-back, all operations will be rolled-back. The old file will be deleted after commit, if any.

Workflow:

                  +--------+
                  | Start  |
                  +---+----+
                      |
           +----------v-----------+
           | Wrap with Descriptor <----+
           +----------+-----------+    |
                      |                |
           +----------v-----------+    |
           | Nothing or Analyze   |    |
           +----------+-----------+    |
                      |                |
           +----------v-----------+    |
           | Nothing or Validate  |    |
           +----------+-----------+    |
                      |                |
           +----------v-----------+    |
           |Nothing or Pre Process+----+
           +------+---------------+
                  |
       +----------+-----------+
       |                      |
+------v---------+  +---------v------+
|  Store in DB   |  |Store In Storage|
+------+---------+  +---------+------+
       |                      |
       +----------+-----------+
                  |
                  |
              +---v----+
              | Finish |
              +--------+
Parameters:
  • attachable – file-like object, filename or URL to attach.
  • content_type – If given, the content-detection is suppressed.
  • original_filename – Original name of the file, if available, to append to the end of the the filename, useful for SEO, and readability.
  • extension – The file’s extension, is available.else, tries to guess it by content_type
  • store_id – The store id to store this file on. Stores must be registered with appropriate id via sqlalchemy_media.stores.StoreManager.register().
  • overwrite – Overwrites the file without changing it’s unique-key and name, useful to prevent broken links. Currently, when using this option, Rollback function is not available, because the old file will be overwritten by the given new one.
  • suppress_pre_process – When is True, ignores the pre-processing phase, during attachment.
  • suppress_validation – When is True, ignores the validation phase, during attachment.
  • kwargs – Additional metadata to be stored in backend.

Note

MaximumLengthIsReachedError and or MinimumLengthIsNotReachedError may be raised.

Warning

This operation can not be rolled-back, if overwrite=True given.

    Changed in version 0.1:
  • This method will return the self. it’s useful to chain method calls on the object within a single line.

  • Additional kwargs are accepted to be stored in database alongside the file’s metadata.

    Changed in version 0.5:
  • suppress_pre_process argument.

  • suppress_validation argument.

  • pre-processing phase.

classmethod coerce(key, value) → sqlalchemy_media.attachments.Attachment[source]

Converts plain dictionary to instance of this class.

content_type

file Content-Type

Type:str
copy() → sqlalchemy_media.attachments.Attachment[source]

Copy this object using deepcopy.

classmethod create_from(*args, **kwargs)[source]

Factory method to create and attach file with the same action.

Parameters:
Returns:

The loaded instance of this class.

delete() → None[source]

Deletes the file.

Warning

This operation can not be roll-backed.So if you want to delete a file, just set it to None or set it by new Attachment instance, while passed delete_orphan=True in StoreManager.

empty

Check if file is attached to this object or not. Returns True when a file is loaded on this object via attach() method or SqlAlchemy db load mechanism, else False.

Type:bool
extension

File extension.

Type:str
filename

The filename used to store the attachment in the storage with this format:

'{self.__prefix__}-{self.key}{self.suffix}{if self.extension
else ''}'
Type:str
get_objects_to_delete()[source]

Returns the files to be deleted, if the attachment is marked for deletion.

get_orphaned_objects()[source]

this method will be always called by the store when adding the self to the orphaned list. so subclasses of the Attachment has a chance to add other related objects into the orphaned list and schedule it for delete. for example the Image class can schedule it’s thumbnails for deletion also. :return: An iterable of Attachment to mark as orphan.

New in version 0.11.0.

get_store() → sqlalchemy_media.stores.base.Store[source]

Returns the sqlalchemy_media.stores.Store instance, which this file is stored on.

key

Unique key for tracking this attachment. it will be generated during attachment process in attach() method.

Type:Hashable
length

The length of the attached file in bytes.

Type:int
locate() → str[source]

Locates the file url.

original_filename

Original file name, it may be provided by user within cgi.FieldStorage.filename, url or Physical filename.

Type:str
path

Relative Path of the file used to store and locate the file.

Type:str
reproducible

The reproducible of the file.

Type:bool
store_id

Returns the id of the store used to put this file on.

Stores must be registered with appropriate id via StoreManager.register().

Type:str
suffix

The same as the sqlalchemy_media.attachments.Attachment.original_filename() plus a leading minus(-) if available, else empty string (‘’) will be returned.

Type:str
timestamp

The unix-time of the attachment creation.

Type:str

AttachmentCollection

class sqlalchemy_media.attachments.AttachmentCollection[source]

Bases: object

Mixin to make a mutable iterator as a collection of Attachment.

__item_type__ = <class 'sqlalchemy_media.attachments.Attachment'>

Type of items

AttachmentList

class sqlalchemy_media.attachments.AttachmentList[source]

Bases: sqlalchemy_media.attachments.AttachmentCollection, sqlalchemy.ext.mutable.MutableList

Used to create a collection of Attachment

class MyList(AttachmentList):
    __item_type__ = MyAttachment

class Person(BaseModel):
    __tablename__ = 'person'
    id = Column(Integer, primary_key=True)
    files = Column(MyList.as_mutable(Json))

me = Person()
me.files = MyList()
me.files.append(MyAttachment.create_from(any_file))
append(object) → None -- append object to end[source]
clear() → None -- remove all items from L[source]
classmethod coerce(index, value)[source]

Convert plain list to instance of this class.

extend(iterable) → None -- extend list by appending elements from the iterable[source]
insert(i, x)[source]

L.insert(index, object) – insert object before index

observe_item(item)[source]

A simple monkeypatch to instruct the children to notify the parent if contents are changed:

From sqlalchemy mutable documentation:

Note that MutableList does not apply mutable tracking to the values themselves inside the list. Therefore it is not a sufficient solution for the use case of tracking deep changes to a recursive mutable structure, such as a JSON structure. To support this use case, build a subclass of MutableList that provides appropriate coercion to the values placed in the dictionary so that they too are “mutable”, and emit events up to their parent structure.
Parameters:item – The item to observe
Returns:
pop([index]) → item -- remove and return item at index (default last).[source]

Raises IndexError if list is empty or index is out of range.

remove(value) → None -- remove first occurrence of value.[source]

Raises ValueError if the value is not present.

AttachmentDict

class sqlalchemy_media.attachments.AttachmentDict[source]

Bases: sqlalchemy_media.attachments.AttachmentCollection, sqlalchemy.ext.mutable.MutableDict

Used to create a dictionary of Attachment

class MyDict(AttachmentDict):
    __item_type__ = MyAttachment

class Person(BaseModel):
    __tablename__ = 'person'
    id = Column(Integer, primary_key=True)
    files = Column(MyDict.as_mutable(Json))

me = Person()
me.files = MyDict()
me.files['original'] = MyAttachment.create_from(any_file)
clear() → None. Remove all items from D.[source]
classmethod coerce(index, value)[source]

Convert plain dictionary to instance of this class.

pop(k[, d]) → v, remove specified key and return the corresponding value.[source]

If key is not found, d is returned if given, otherwise KeyError is raised

popitem() → (k, v), remove and return some (key, value) pair as a[source]

2-tuple; but raise KeyError if D is empty.

setdefault(k[, d]) → D.get(k,d), also set D[k]=d if k not in D[source]
update([E, ]**F) → None. Update D from dict/iterable E and F.[source]

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

File

class sqlalchemy_media.attachments.File[source]

Bases: sqlalchemy_media.attachments.Attachment

Representing an attached file. Normally if you want to store any file, this class is the best choice.

__directory__ = 'files'
__prefix__ = 'file'
__max_length__ = 2097152
__min_length__ = 0

FileList

class sqlalchemy_media.attachments.FileList[source]

Bases: sqlalchemy_media.attachments.AttachmentList

Equivalent to

class FileList(AttachmentList):
    __item_type__ = File
__item_type__ = <class 'sqlalchemy_media.attachments.File'>

FileDict

class sqlalchemy_media.attachments.FileDict[source]

Bases: sqlalchemy_media.attachments.AttachmentDict

Equivalent to

class FileDict(AttachmentDict):
    __item_type__ = File
__item_type__ = <class 'sqlalchemy_media.attachments.File'>

BaseImage

class sqlalchemy_media.attachments.BaseImage[source]

Bases: sqlalchemy_media.attachments.File

Base class for all images.

attach(*args, dimension: Tuple[int, int] = None, **kwargs)[source]

A new overload for Attachment.attach(), which accepts one additional argument: dimension.

Parameters:
Returns:

The same as the: Attachment.attach().

Image

class sqlalchemy_media.attachments.Image[source]

Bases: sqlalchemy_media.attachments.BaseImage

Equivalent to

class Image(Attachment):
    __directory__ = 'images'
    __prefix__ = 'image'
    __max_length__ = 2 * MB
    __min_length__ = 4 * KB
__directory__ = 'images'
__prefix__ = 'image'
__max_length__ = 2097152
__min_length__ = 4096
generate_thumbnail(width: int = None, height: int = None, ratio: float = None, ratio_precision: int = 5) → sqlalchemy_media.attachments.Thumbnail[source]

New in version 0.3.

Generates and stores a thumbnail with the given arguments.

Warning

If none or more than one of the width, height and or ratio are given, ValueError will be raised.

Parameters:
  • width – The width of the thumbnail.
  • height – The Height of the thumbnail.
  • ratio – The coefficient to reduce, Must be less than 1.0.
  • ratio_precision – Number of digits after the decimal point of the ratio argument to tune thumbnail lookup precision. default: 2.
Returns:

the Newly generated Thumbnail instance.

get_objects_to_delete()[source]

Returns the files to be deleted, if the attachment is marked for deletion.

get_orphaned_objects()[source]

Mark thumbnails for deletion when the Image is being deleted. :return: An iterable of Thumbnail to mark as orphan.

get_thumbnail(width: int = None, height: int = None, ratio: float = None, ratio_precision: int = 2, auto_generate: bool = False) → sqlalchemy_media.attachments.Thumbnail[source]

Search for the thumbnail with given arguments, if auto_generate is False, the ThumbnailIsNotAvailableError will be raised, else tries to call the generate_thumbnail() to create a new one.

Parameters:
  • width – Width of the thumbnail to search for.
  • height – Height of the thumbnail to search for.
  • ratio – Ratio of the thumbnail to search for.
  • ratio_precision – Number of digits after the decimal point of the ratio argument to tune thumbnail lookup precision. default: 2.
  • auto_generate – If True, tries to generate a new thumbnail.
Returns:

Thumbnail instance.

Warning

if auto_generate is True, you have to commit the session, to store the generated thumbnails.

thumbnails

A List[Tuple[int, int, float, Thumbnail]], to hold thumbnails.

You may use generate_thumbnail() and or get_thumbnail() with auto_generate=True to fill it.

ImageList

class sqlalchemy_media.attachments.ImageList[source]

Bases: sqlalchemy_media.attachments.AttachmentList

Used to create a collection of Image.

__item_type__ = <class 'sqlalchemy_media.attachments.Image'>

Thumbnail

class sqlalchemy_media.attachments.Thumbnail[source]

Bases: sqlalchemy_media.attachments.BaseImage

Representing an image thumbnail.

You may use generate_thumbnail() and or get_thumbnail() with auto_generate=True to get one.

descriptors Module

BaseDescriptor

class sqlalchemy_media.descriptors.BaseDescriptor(min_length: int = None, max_length: int = None, content_type: str = None, content_length: int = None, extension: str = None, original_filename: str = None, header_buffer_size: int = 1024, reproducible: bool = False, **kwargs)[source]

Bases: object

Abstract base class for all descriptors. Instance of this class is a file-like object.

Descriptors are used to get some primitive information from an attachable(file-like object, filename or URI) and also allow seeking over underlying file-object. users may not be using this class directly.

See also

AttachableDescriptor to know how to use it.

    New in version 0.5:
  • min_length argument

Parameters:
  • min_length – Maximum allowed file size.
  • max_length – Maximum allowed file size.
  • content_type – The file’s mimetype to suppress the mimetype detection.
  • content_length – The length of the file in bytes, if available. Some descriptors like UrlDescriptor are providing this keyword argument.
  • extension – The file’s extension to suppress guessing it.
  • original_filename – Original filename, useful to detect content_type and or extension.
  • kwargs – Additional keyword arguments to set as attribute on descriptor instance.
  • header_buffer_size – Amount of bytes to read and buffer from underlying file-like object for analysis purpose if file-like object is not seekable.
  • reproducible – The reproducible of the file-like objects.
_tell_source() → int[source]

[Abstract]

Should be overridden in inherited class and return the underlying file-object’s current position.

_read_source(size: int) → bytes[source]

[Abstract]

Should be overridden in inherited class and read from underlying file-object.

Parameters:size – Amount of bytes to read.
close(check_length=True) → None[source]

Do nothing here.

content_type = None

Content type of the underlying file-object.

extension = None

Extension of the underlying file-object.

get_header_buffer() → bytes[source]

Returns the amount of header_buffer_size from the beginning of the underlying file-object. this method should be called many times before the read() method is called on non-seekable descriptors.

Warning

The DescriptorOperationError will be raised if this method is called after calling the read(). This situation is only happened on non-seekable descriptors.

See also

seekable()

header = None

Buffer to store cached header on non-seekable file-like objects.

header_buffer_size = 1024

Amount of bytes to cache from header on non-seekable file-like objects.

original_filename = None

Original filename of the underlying file-object.

read(size: int = None) → bytes[source]

Read from the underlying file.

Parameters:size – Amount of bytes ro read.
read_source(size: int) → bytes[source]

Used to read from underlying file-object.

Parameters:size – Amount of bytes to read.
reproducible = False

The reproducible of the file-like objects.

seek(position: int, whence: int = 0) → None[source]

Seek the file at the given position.

Note

The io.UnsupportedOperation will be raised if the underlying file-object is not seekable().

Parameters:
  • position – the position to seek on.
  • whence – optional whence argument.
seekable() → bool[source]

[Abstract]

Should be overridden in inherited class and return True if the underlying file-object is seekable.

tell() → int[source]

Get the current position of the file-like object. Even if the underlying file-object is not seekable(), this method should return the current position which counted internally.

tell_source()[source]

Returns the underlying file-object’s current position. even if the underlying file-object is not seekable().

StreamDescriptor

class sqlalchemy_media.descriptors.StreamDescriptor(stream: Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper], **kwargs)[source]

Bases: sqlalchemy_media.descriptors.BaseDescriptor

This class is used for describing a file-like object. so it’s just a proxy for file-like objects. The underlying file-object is not meant to be closed after calling the close() method.

Parameters:
  • stream – File-like object to wrap.
  • kwargs – the same as the BaseDescriptor
close(**kw) → None[source]

We are not closing the file-like object here, because we’ve not opened it.

filename

Retrieve the filename of the backend file-like object is available.

prepare_to_read(backend: str = 'temp') → None[source]

New in version 0.5.

If the underlying file-object is not seekable, tries to store the underlying non-seekable file-like object as an instance of io.BytesIO, tempfile.NamedTemporaryFile and tempfile.TemporaryFile.

Warning

Anyway, this method will seeks the descriptor to 0.

Warning

If any physical file is created during this operation, This will be deleted after the close() has been called.

Warning

DescriptorOperationError may be raised, if the current position is greater than zero 0, and also if called on a seekable instance.

Note

The file option is also a temp file but file is guaranteed to have a visible name in the file system (on Unix, the directory entry is not unlinked). filename will be retrieved by the filename.

Parameters:backend – Available choices are: memory, file and temp.
replace(attachable: [<class '_io.BytesIO'>, <class '_io.FileIO'>], position=None, **kwargs)[source]

New in version 0.5.

Replace the underlying file-object with a seekable one.

Parameters:
  • attachable – A seekable file-object.
  • position – Position of the new seekable file-object. if None, position will be preserved.
  • kwargs – the same as the BaseDescriptor
seek(position: int, whence: int = 0)[source]

Seek the file at the given position.

Note

The io.UnsupportedOperation will be raised if the underlying file-object is not seekable().

Parameters:
  • position – the position to seek on.
  • whence – optional whence argument.
seekable()[source]

[Abstract]

Should be overridden in inherited class and return True if the underlying file-object is seekable.

StreamCloserDescriptor

class sqlalchemy_media.descriptors.StreamCloserDescriptor(stream: Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper], **kwargs)[source]

Bases: sqlalchemy_media.descriptors.StreamDescriptor

The same as the StreamDescriptor, the only difference is that this class tries to close the file-like object after calling the close() method.

close(**kw) → None[source]

Overridden to close the underlying file-object.

LocalFileSystemDescriptor

class sqlalchemy_media.descriptors.LocalFileSystemDescriptor(filename: str, original_filename: str = None, **kwargs)[source]

Bases: sqlalchemy_media.descriptors.StreamCloserDescriptor

Representing a file on the local file system.

Parameters:
  • filename – The filename on the local storage to open for reading.
  • kwargs – the same as the BaseDescriptor

Note

the filename will be passed as original_filename to the parent class.

readline()[source]

Just to be compatible with underlying file-like object.

UrlDescriptor

class sqlalchemy_media.descriptors.UrlDescriptor(uri: str, content_type: str = None, original_filename: str = None, **kwargs)[source]

Bases: sqlalchemy_media.descriptors.StreamCloserDescriptor

Open a remote resource with urllib and pass the content_type and content_length to the parent class.

Parameters:

Note

the uri will be passed as original_filename to the parent class, if the original_filename is None.

CgiFieldStorageDescriptor

class sqlalchemy_media.descriptors.CgiFieldStorageDescriptor(storage: cgi.FieldStorage, content_type: str = None, **kwargs)[source]

Bases: sqlalchemy_media.descriptors.StreamCloserDescriptor

Describes a cgi.FieldStorage.

Parameters:
  • storage – The cgi.FieldStorage instance to be described.
  • kwargs – the same as the BaseDescriptor

AttachableDescriptor

class sqlalchemy_media.descriptors.AttachableDescriptor(min_length: int = None, max_length: int = None, content_type: str = None, content_length: int = None, extension: str = None, original_filename: str = None, header_buffer_size: int = 1024, reproducible: bool = False, **kwargs)[source]

Bases: sqlalchemy_media.descriptors.BaseDescriptor

This is an abstract factory for descriptors based on the first argument

>>> from sqlalchemy_media import AttachableDescriptor
>>> with AttachableDescriptor('index.rst') as descriptor:
...     print(type(descriptor))
<class 'sqlalchemy_media.descriptors.LocalFileSystemDescriptor'>

So this callable, should determine the appropriate descriptor and return an instance of it.

Parameters:
  • attachable – filename, uri or file-like object
  • kwargs – the same as the BaseDescriptor

stores Module

Store

class sqlalchemy_media.stores.Store[source]

Bases: object

The abstract base class for all stores.

cleanup()[source]

In derived class should cleanup all dirty stuff created while storing and deleting file. If not overridden, no error will be raised.

delete(filename: str) → None[source]

[Abstract]

Should be overridden in inherited class and deletes the given file.

Parameters:filename – The filename to delete
locate(attachment) → str[source]

[Abstract]

If overridden in the inherited class, should locates the file’s url to share in public space.

Parameters:attachment – The Attachment object to
open(filename: str, mode: str = 'rb') → Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper][source]

[Abstract]

Should be overridden in inherited class and return a file-like object representing the file in the store.

Note

Caller of this method is responsible to close the file-like object.

Parameters:
  • filename – The filename to open.
  • mode – same as the mode in famous open() function.
put(filename: str, stream: Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper]) → int[source]

[Abstract]

Should be overridden in inherited class and puts the file-like object as the given filename in the store.

    Changed in version 0.5:
  • min_length has been removed.

  • max_length has been removed.

Parameters:
  • filename – the target filename.
  • stream – the source file-like object
Returns:

length of the stored file.

FileSystemStore

class sqlalchemy_media.stores.FileSystemStore(root_path: str, base_url: str, chunk_size: int = 32768)[source]

Bases: sqlalchemy_media.stores.base.Store

Store for dealing with local file-system.

Parameters:
  • root_path – The path to a directory to store files.
  • base_url – The base url path to include at the beginning of the file’s path to yield the access url.
  • chunk_size – Length of the chunks to read/write from/to files. default: 32768 = 32 * 1024
delete(filename: str)[source]

[Abstract]

Should be overridden in inherited class and deletes the given file.

Parameters:filename – The filename to delete
locate(attachment) → str[source]

[Abstract]

If overridden in the inherited class, should locates the file’s url to share in public space.

Parameters:attachment – The Attachment object to
open(filename: str, mode: str = 'rb') → Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper][source]

[Abstract]

Should be overridden in inherited class and return a file-like object representing the file in the store.

Note

Caller of this method is responsible to close the file-like object.

Parameters:
  • filename – The filename to open.
  • mode – same as the mode in famous open() function.
put(filename: str, stream: Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper])[source]

[Abstract]

Should be overridden in inherited class and puts the file-like object as the given filename in the store.

    Changed in version 0.5:
  • min_length has been removed.

  • max_length has been removed.

Parameters:
  • filename – the target filename.
  • stream – the source file-like object
Returns:

length of the stored file.

S3Store

class sqlalchemy_media.stores.S3Store(bucket: str, access_key: str, secret_key: str, region: str, max_age: int = 31536000, prefix: str = None, base_url: str = None, cdn_url: str = None, cdn_prefix_ignore: bool = False, acl: str = 'private')[source]

Bases: sqlalchemy_media.stores.base.Store

Store for dealing with s3 of aws

New in version 0.9.0.

    New in version 0.9.6:
  • prefix

delete(filename: str)[source]

[Abstract]

Should be overridden in inherited class and deletes the given file.

Parameters:filename – The filename to delete
locate(attachment) → str[source]

[Abstract]

If overridden in the inherited class, should locates the file’s url to share in public space.

Parameters:attachment – The Attachment object to
open(filename: str, mode: str = 'rb') → Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper][source]

[Abstract]

Should be overridden in inherited class and return a file-like object representing the file in the store.

Note

Caller of this method is responsible to close the file-like object.

Parameters:
  • filename – The filename to open.
  • mode – same as the mode in famous open() function.
put(filename: str, stream: Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper])[source]

[Abstract]

Should be overridden in inherited class and puts the file-like object as the given filename in the store.

    Changed in version 0.5:
  • min_length has been removed.

  • max_length has been removed.

Parameters:
  • filename – the target filename.
  • stream – the source file-like object
Returns:

length of the stored file.

OS2Store

class sqlalchemy_media.stores.OS2Store(bucket: str, access_key: str, secret_key: str, region: str, max_age: int = 31536000, base_headers: dict = None, prefix: str = None, base_url: str = None, cdn_url: str = None, cdn_prefix_ignore: bool = False, acl: str = 'private')[source]

Bases: sqlalchemy_media.stores.base.Store

Store for dealing with oss of aliyun

delete(filename: str)[source]

[Abstract]

Should be overridden in inherited class and deletes the given file.

Parameters:filename – The filename to delete
locate(attachment) → str[source]

[Abstract]

If overridden in the inherited class, should locates the file’s url to share in public space.

Parameters:attachment – The Attachment object to
open(filename: str, mode: str = 'rb') → Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper][source]

[Abstract]

Should be overridden in inherited class and return a file-like object representing the file in the store.

Note

Caller of this method is responsible to close the file-like object.

Parameters:
  • filename – The filename to open.
  • mode – same as the mode in famous open() function.
put(filename: str, stream: Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper])[source]

[Abstract]

Should be overridden in inherited class and puts the file-like object as the given filename in the store.

    Changed in version 0.5:
  • min_length has been removed.

  • max_length has been removed.

Parameters:
  • filename – the target filename.
  • stream – the source file-like object
Returns:

length of the stored file.

SSHStore

class sqlalchemy_media.stores.SSHStore(hostname, root_path, base_url, ssh_config_file=None, **kwargs)[source]

Bases: sqlalchemy_media.stores.base.Store

Store for SSH protocol. aka SFTP

New in version 0.12.0.

Parameters:
  • hostname – The ssh server’s hostname to connect to. It will be looked-up from ssh config file to find another options if given. An instance of the paramiko.SSHClient may be passed instead of the hostname.
  • root_path – The path to a directory on the ssh server to store files.
  • base_url – The base url path to include at the beginning of the file’s path to yield the access url.
  • ssh_config_file – The standard ssh config file. is not given, the file $HOME/.ssh/config will be tried.
  • kwargs – Additional keyword arguments to pass to the paramiko.SSHClient
delete(filename: str) → None[source]

[Abstract]

Should be overridden in inherited class and deletes the given file.

Parameters:filename – The filename to delete
locate(attachment) → str[source]

[Abstract]

If overridden in the inherited class, should locates the file’s url to share in public space.

Parameters:attachment – The Attachment object to
open(filename: str, mode: str = 'rb')[source]

[Abstract]

Should be overridden in inherited class and return a file-like object representing the file in the store.

Note

Caller of this method is responsible to close the file-like object.

Parameters:
  • filename – The filename to open.
  • mode – same as the mode in famous open() function.
put(filename: str, stream: Union[IO[_io.BytesIO], _io.BytesIO, _io.FileIO, _io.TextIOWrapper]) → int[source]

[Abstract]

Should be overridden in inherited class and puts the file-like object as the given filename in the store.

    Changed in version 0.5:
  • min_length has been removed.

  • max_length has been removed.

Parameters:
  • filename – the target filename.
  • stream – the source file-like object
Returns:

length of the stored file.

StoreManager

class sqlalchemy_media.stores.StoreManager(session, delete_orphan=False)[source]

Bases: object

This is an context manager.

Before using you must register at least one store factory function as default with-in store registry with register() by passing default=true during registration.

This object will call the registered factory functions to instantiate one per sqlalchemy_media.context.get_id().

import functools

from sqlalchemy.orm.session import Session

from sqlalchemy_media import StoreManager, FileSystemStore

StoreManager.register(
    'fs',
    functools.partial(FileSystemStore, '/tmp/sa_temp_fs', 'http'),
    default=True
)
StoreManager.register(
    'fs2',
    functools.partial(FileSystemStore, '/tmp/sa_temp_fs2', 'http')
)

with StoreManager(Session) as store_manager:
    assert StoreManager.get_current_store_manager() == store_manager

    print(store_manager.get().root_path)  # fs1 default store
    print(store_manager.get('fs2').root_path)  # fs2 store

This would output:

/tmp/sa_temp_fs
/tmp/sa_temp_fs2
__enter__()[source]

Enters the context: bind events and push itself into context stack.

Returns:self
__exit__(exc_type, exc_val, exc_tb)[source]

Destroy the context, pop itself from context stack and unbind all events.

adopted(*attachments) → None[source]

Opposite of orphaned()

bind_events() → None[source]

Binds the required event on sqlalchemy session. to handle commit & rollback.

cleanup()[source]

Calls the Store.cleanup() for each store is stores and clears the stores also.

default_store

The same as the get() without parameter.

get(key=None) → sqlalchemy_media.stores.base.Store[source]

Lookup the store in available instance cache, and instantiate a new one using registered factory function, if not found.

If the key is None, the default store will be instantiated(if required) and returned.

Parameters:key – the store unique id to lookup.
classmethod get_current_store_manager() → sqlalchemy_media.stores.StoreManager[source]

Find the current StoreManager in context stack if any. else ContextError will be raised.

classmethod make_default(key) → None[source]

Makes a pre-registered store as default.

Parameters:key – the store id.
classmethod observe_attribute(attr, collection=False)[source]

Attach some event handlers on sqlalchemy attribute to handle delete_orphan option.

on_commit(session) → None[source]

Will be called when session commit occurred.

on_delete(session, instance)[source]

Will be called when an model instance deleted.

on_rollback(session, transaction)[source]

Will be called when session rollback occurred.

orphaned(*attachments) → None[source]

Mark one or more attachment(s) orphaned, So if delete_orphan is True, the attachment(s) will be deleted from store after session commit.

classmethod register(key: str, store_factory, default: bool = False)[source]

Registers the store factory into stores registry, use unregister() to remove it.

Parameters:
  • key – The unique key for store.
  • store_factory – A callable that returns an instance of Store.
  • default – If True the given store will be marked as default also. in addition you can use make_default() to mark a store as default.
register_to_delete_after_commit(*attachments) → None[source]

Schedules one or more attachment(s) to be deleted from store just after sqlalchemy session commit.

register_to_delete_after_rollback(*files) → None[source]

Schedules one or more attachment(s) to be deleted from store just after sqlalchemy session rollback.

reset_files_state() → None[source]

Reset the object’s state and forget all scheduled tasks for commit and or rollback.

Warning

Calling this method without knowing what you are doing, will be caused bad result !

stores

The mapping str -> store factory.

Type:dict[str] -> callable
unbind_events() → None[source]

Opposite of bind_events().

classmethod unregister(key) → sqlalchemy_media.stores.base.Store[source]

Opposite of register(). KeyError may raised if key not found in registry.

Parameters:key – The store key to remove from stores registry.

processors Module

Processor

class sqlalchemy_media.processors.Processor[source]

Bases: object

New in version 0.5.

Abstract base class for all processors.

Processors are used to modify/replace the attachment before storing.

process(descriptor: sqlalchemy_media.descriptors.StreamDescriptor, context: dict) → None[source]

[Abstract]

Should be overridden in inherited class and apply the process on the file-like object. The result may be inserted info context argument.

Parameters:
  • descriptor – The BaseDescriptor instance, to read the blob info from.
  • context – A dictionary to put and get the info about the attachment. Which as content_type, width, height, length and etc …

Analyzer

class sqlalchemy_media.processors.Analyzer[source]

Bases: sqlalchemy_media.processors.Processor

The abstract base class for all analyzers.

process(descriptor: sqlalchemy_media.descriptors.StreamDescriptor, context: dict)[source]

Should be overridden in inherited class and analyzes the given BaseDescriptor instance.

Note

An instance of AnalyzeError or sub-types may raised

MagicAnalyzer

class sqlalchemy_media.processors.MagicAnalyzer[source]

Bases: sqlalchemy_media.processors.Analyzer

New in version 0.2.

    Changed in version 0.5:
  • Inherited from Processor

  • The analyze method renamed to process to override the parent method.

Analyze the file using the libmagic and it’s Python wrapper: python-magic.

Warning

You should install the python-magic in order, to use this class. otherwise, an OptionalPackageRequirementError will be raised.

process(descriptor: sqlalchemy_media.descriptors.StreamDescriptor, context: dict)[source]

Should be overridden in inherited class and analyzes the given BaseDescriptor instance.

Note

An instance of AnalyzeError or sub-types may raised

Validator

class sqlalchemy_media.processors.Validator[source]

Bases: sqlalchemy_media.processors.Processor

New in version 0.2.

    Changed in version 0.5:
  • Inherited from Processor

  • The validate method renamed to process to override the parent method.

The abstract base class for all validators.

process(descriptor: sqlalchemy_media.descriptors.StreamDescriptor, context: dict) → None[source]

[Abstract]

Should be overridden in inherited class and validate the validate the context.

Note

It should be appended after the Analyzer to the Attachment.__pre_processors__.

Note

An instance of ValidationError or sub-types may raised

Parameters:
  • descriptor – The BaseDescriptor instance, to read the blob info from.
  • context – A dictionary to to validate.

ContentTypeValidator

class sqlalchemy_media.processors.ContentTypeValidator(content_types: Iterable[str] = None)[source]

Bases: sqlalchemy_media.processors.Validator

New in version 0.2.

Assert content types.

Parameters:content_types – An iterable whose items are allowed content types.

Note

ContentTypeValidationError may be raised during validation.

process(descriptor: sqlalchemy_media.descriptors.StreamDescriptor, context: dict)[source]

[Abstract]

Should be overridden in inherited class and validate the validate the context.

Note

It should be appended after the Analyzer to the Attachment.__pre_processors__.

Note

An instance of ValidationError or sub-types may raised

Parameters:
  • descriptor – The BaseDescriptor instance, to read the blob info from.
  • context – A dictionary to to validate.

ImageValidator

class sqlalchemy_media.processors.ImageValidator(minimum: Tuple[int, int] = None, maximum: Tuple[int, int] = None, content_types=None, min_aspect_ratio: float = None, max_aspect_ratio: float = None)[source]

Bases: sqlalchemy_media.processors.ContentTypeValidator

New in version 0.4.

    Changed in version 0.5:
  • Renamed from ImageDimensionValidator to ImageValidator.

Validates image size

Parameters:
  • minimum – Minimum allowed dimension (w, h).
  • maximum – Maximum allowed dimension (w, h).
  • content_types – An iterable whose items are allowed content types.
  • min_aspect_ratio – Minimum allowed image aspect ratio.
  • max_aspect_ratio – Maximum allowed image aspect ratio.
    New in version 0.6:
  • min_aspect_ratio and max_aspect_ratio

Note

Pass 0 on None for disabling assertion for one of: (w, h).

Note

DimensionValidationError may be raised during validation.

Use it as follow

from sqlalchemy_media import Image, ImageAnalyzer, ImageValidator


class ProfileImage(Image):
    __pre_processors__ = [
        ImageAnalyzer(),
        ImageValidator(
            (64, 48),
            (128, 96),
            content_types=['image/jpeg', 'image/png']
        )
    ]
process(descriptor: sqlalchemy_media.descriptors.StreamDescriptor, context: dict) → None[source]

[Abstract]

Should be overridden in inherited class and validate the validate the context.

Note

It should be appended after the Analyzer to the Attachment.__pre_processors__.

Note

An instance of ValidationError or sub-types may raised

Parameters:
  • descriptor – The BaseDescriptor instance, to read the blob info from.
  • context – A dictionary to to validate.

ImageProcessor

class sqlalchemy_media.processors.ImageProcessor(fmt: str = None, width: int = None, height: int = None, crop=None)[source]

Bases: sqlalchemy_media.processors.Processor

Used to re-sampling, resizing, reformatting bitmaps.

Warning

  • If width or height is given with crop, Cropping will be processed after the resize.
  • If you pass both width and height, aspect ratio may not be preserved.
Parameters:
  • format – The image format. i.e jpeg, gif, png.
  • width – The new image width.
  • height – The new image height.
  • crop – Used to crop the image.

The crop argument is 4-tuple of (left, top, right, bottom)

ImageProcessor(crop=(10, 10, 120, 230))
process(descriptor: sqlalchemy_media.descriptors.StreamDescriptor, context: dict)[source]

[Abstract]

Should be overridden in inherited class and apply the process on the file-like object. The result may be inserted info context argument.

Parameters:
  • descriptor – The BaseDescriptor instance, to read the blob info from.
  • context – A dictionary to put and get the info about the attachment. Which as content_type, width, height, length and etc …

exceptions Module

exception sqlalchemy_media.exceptions.SqlAlchemyMediaException[source]

Bases: Exception

The base class for all exceptions

exception sqlalchemy_media.exceptions.MaximumLengthIsReachedError(max_length: int)[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

Indicates the maximum allowed file limit is reached.

exception sqlalchemy_media.exceptions.ContextError[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

Exception related to StoreManager.

exception sqlalchemy_media.exceptions.DefaultStoreError[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

Raised when no default store is registered.

exception sqlalchemy_media.exceptions.AnalyzeError[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

Raised when Analyzer can not analyze the file-like object.

exception sqlalchemy_media.exceptions.ValidationError[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

Raised when Validator can not validate the file-like object.

exception sqlalchemy_media.exceptions.DescriptorOperationError[source]

Bases: sqlalchemy_media.exceptions.DescriptorError

Raised when a subclass of BaseDescriptor is abused.

exception sqlalchemy_media.exceptions.DescriptorError[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

A sub-class instance of this exception may raised when an error has occurred in BaseDescriptor and it’s subtypes.

exception sqlalchemy_media.exceptions.OptionalPackageRequirementError(package_name: str)[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

Raised when an optional package is missing. The constructor is trying to search for package name in requirements-optional.txt and find the requirement and it’s version criteria to inform the user.

Parameters:package_name – The name of the missing package.
exception sqlalchemy_media.exceptions.ContentTypeValidationError(content_type=None, valid_content_types=None)[source]

Bases: sqlalchemy_media.exceptions.ValidationError

Raised by Validator.validate() when the content type is missing or invalid.

Parameters:content_type – The invalid content type if any.
exception sqlalchemy_media.exceptions.ThumbnailIsNotAvailableError[source]

Bases: sqlalchemy_media.exceptions.SqlAlchemyMediaException

Raised when requested thumbnail is not available(generated) yet.

exception sqlalchemy_media.exceptions.DimensionValidationError[source]

Bases: sqlalchemy_media.exceptions.ValidationError

Raises when width or height of the media is not meet the limitations.

Other Modules

mimetypes_ Module

Due the python bugs:

The database was hardcoded here.

New in version 0.3.

sqlalchemy_media.mimetypes_.magic_mime_from_buffer(buffer: bytes) → str[source]

Try to detect mimetype using magic library.

Warning

OptionalPackageRequirementError will be raised if python-magic is not installed.

Parameters:buffer – buffer from header of file.
Returns:The mimetype

optionals Module

This module is a helper for handing optional packages.

Optional packages are not included in setup.py. So OptionalPackageRequirementError will be raised if requested package is not provided.

sqlalchemy_media.optionals.ensure_aws4auth()[source]

Warning

OptionalPackageRequirementError will be raised if requests-aws4auth is not installed.

sqlalchemy_media.optionals.ensure_os2auth()[source]

Warning

OptionalPackageRequirementError will be raised if requests-aliyun is not installed.

sqlalchemy_media.optionals.ensure_paramiko()[source]

Warning

OptionalPackageRequirementError will be raised if paramiko is not installed.

constants Module

sqlalchemy_media.constants.KB = 1024

Represents Kilo-Bytes

sqlalchemy_media.constants.MB = 1048576

Represents Mega-Bytes