sqlalchemy_imageattach.entity
— Image entities¶This module provides a short way to attach resizable images to other object-relationally mapped entity classes.
For example, imagine there’s a fictional entity named
User
and it has its picture
and
front_cover
. So there should be two
image entities that subclass Image
mixin:
class UserPicture(Base, Image):
'''User's profile picture.'''
user_id = Column(Integer, ForeignKey('User.id'), primary_key=True)
user = relationship('User')
__tablename__ = 'user_picture'
You have to also inherit your own declarative_base()
class (Base
in the example).
Assume there’s also UserFrontCover
in the same way.
Note that the class can override object_id
property.
Backend storages utilize this to identify images e.g. filename, S3 key.
If the primary key of the image entity is integer, object_id
automatically uses the primary key value by default, but it can be
overridden if needed, and must be implemented if the primary key is not
integer or composite key.
There’s also object_type
property. Image
provides
the default value for it as well. It uses the class name (underscores
will be replaced by hyphens) by default, but you can override it.
These Image
subclasses can be related to the their
‘parent’ entity using image_attachment()
function.
It’s a specialized version of SQLAlchemy’s built-in
relationship()
function, so you can pass
the same options as relationship()
takes:
class User(Base):
'''Users have their profile picture and front cover.'''
id = Column(Integer, primary_key=True)
picture = image_attachment('UserPicture')
front_cover = image_attachment('UserFrontCover')
__tablename__ = 'user'
It’s done, you can store the actual image files using
from_file()
or from_blob()
method:
with store_context(store):
user = User()
with open('picture.jpg', 'rb') as f:
user.picture.from_blob(f.read())
with open('front_cover.jpg', 'rb') as f:
user.front_cover.from_file(f)
with session.begin():
session.add(user)
Or you can resize the image to make thumbnails using
generate_thumbnail()
method:
with store_context(store):
user.picture.generate_thumbnail(ratio=0.5)
user.picture.generate_thumbnail(height=100)
user.front_cover.generate_thumbnail(width=500)
sqlalchemy_imageattach.entity.
VECTOR_TYPES
= frozenset({'application/pdf', 'image/svg+xml'})¶(typing.AbstractSet
[str
]) The set of vector image types.
sqlalchemy_imageattach.entity.
BaseImageSet
¶The abstract class of the following two image set types:
The common things about them, abstracted by BaseImageSet
, are:
original
image, and has only one
original
image.original
image.generate_thumbnail()
method.find_thumbnail()
method.You can think image set of an abstract image hiding its size details.
It actually encapsulates physical images of different sizes but having
all the same look. So only its original
image is canon, and other
thumbnails are replica of it.
Note that it implements __html__()
method, a de facto
standard special method for HTML templating. So you can simply use
it in Jinja2 like:
{{ user.profile }}
instead of:
<img src="{{ user.profile|permalink }}"
width="{{ user.profile.original.width }}"
height="{{ user.profile.original.height }}">
find_thumbnail
(width=None, height=None)¶Finds the thumbnail of the image with the given width
and/or height
.
Parameters: |
|
---|---|
Returns: | the thumbnail image |
Return type: | |
Raises: | sqlalchemy.orm.exc.NoResultFound – when there’s no image of such size |
from_blob
(blob, store=sqlalchemy_imageattach.context.current_store, extra_args=None, extra_kwargs=None)¶Stores the blob
(byte string) for the image
into the store
.
Parameters: |
|
---|---|
Returns: | the created image instance |
Return type: |
New in version 1.0.0: The extra_args
and extra_kwargs
options.
from_file
(file, store=sqlalchemy_imageattach.context.current_store, extra_args=None, extra_kwargs=None)¶Stores the file
for the image into the store
.
Parameters: |
|
---|---|
Returns: | the created image instance |
Return type: |
New in version 1.0.0: The extra_args
and extra_kwargs
options.
from_raw_file
(raw_file, store=sqlalchemy_imageattach.context.current_store, size=None, mimetype=None, original=True, extra_args=None, extra_kwargs=None)¶Similar to from_file()
except it’s lower than that.
It assumes that raw_file
is readable and seekable while
from_file()
only assumes the file is readable.
Also it doesn’t make any in-memory buffer while
from_file()
always makes an in-memory buffer and copy
the file into the buffer.
If size
and mimetype
are passed, it won’t try to read
image and will use these values instead.
It’s used for implementing from_file()
and
from_blob()
methods that are higher than it.
Parameters: |
|
---|---|
Returns: | the created image instance |
Return type: |
New in version 1.0.0: The extra_args
and extra_kwargs
options.
generate_thumbnail
(ratio=None, width=None, height=None, filter='undefined', store=sqlalchemy_imageattach.context.current_store, _preprocess_image=None, _postprocess_image=None)¶Resizes the original
(scales up or down) and
then store the resized thumbnail into the store
.
Parameters: |
|
---|---|
Returns: | the resized thumbnail image. it might be an already existing image if the same size already exists |
Return type: | |
Raises: |
locate
(store=sqlalchemy_imageattach.context.current_store)¶The shorthand of locate()
for
the original
.
Parameters: | store (Store ) – the storage which contains the image files.
current_store
by default |
---|---|
Returns: | the url of the original image |
Return type: | str |
make_blob
(store=sqlalchemy_imageattach.context.current_store)¶The shorthand of make_blob()
for
the original
.
Parameters: | store (Store ) – the storage which contains the image files.
current_store
by default |
---|---|
Returns: | the byte string of the original image |
Return type: | str |
open_file
(store=sqlalchemy_imageattach.context.current_store, use_seek=False)¶The shorthand of open_file()
for
the original
.
Parameters: |
|
---|---|
Returns: | the file-like object of the image, which is a context
manager (plus, also seekable only if |
Return type: |
|
sqlalchemy_imageattach.entity.
BaseImageQuery
(entities, session=None)¶The subtype of Query
specialized
for Image
. It provides more methods and properties over
Query
.
New in version 1.0.0.
sqlalchemy_imageattach.entity.
Image
¶The image of the particular size.
Note that it implements __html__()
method, a de facto
standard special method for HTML templating. So you can simply use
it in HTML templates like:
{{ user.profile.find_thumbnail(120) }}
The above template is equivalent to:
{% with thumbnail = user.profile.find_thumbnail(120) %}
<img src="{{ thumbnail.locate() }}"
width="{{ thumbnail.width }}"
height="{{ thumbnail.height }}">
{% endwith %}
object_type
¶(str
) The identifier string of the image type.
It uses __tablename__
(which replaces underscores with
hyphens) by default, but can be overridden.
created_at
= Column('created_at', DateTime(timezone=True), table=None, nullable=False, default=ColumnDefault(<sqlalchemy.sql.functions.now at 0x7ff650598ef0; now>))¶(datetime.datetime
) The created time.
height
= Column('height', Integer(), table=None, primary_key=True, nullable=False)¶(numbers.Integral
) The image’s height.”“”
identity_attributes
()¶A list of the names of primary key fields.
Returns: | A list of the names of primary key fields |
---|---|
Return type: | typing.Sequence [str ] |
New in version 1.0.0.
identity_map
¶(typing.Mapping
[str
, object
])
A dictionary of the values of primary key fields with their names.
New in version 1.0.0.
locate
(store=sqlalchemy_imageattach.context.current_store)¶Gets the URL of the image from the store
.
Parameters: | store (Store ) – the storage which contains the image.
current_store
by default |
---|---|
Returns: | the url of the image |
Return type: | str |
make_blob
(store=sqlalchemy_imageattach.context.current_store)¶Gets the byte string of the image from the store
.
Parameters: | store (Store ) – the storage which contains the image.
current_store
by default |
---|---|
Returns: | the binary data of the image |
Return type: | str |
mimetype
= Column('mimetype', String(length=255), table=None, nullable=False)¶(str
) The mimetype of the image
e.g. 'image/jpeg'
, 'image/png'
.
object_id
¶(numbers.Integral
) The identifier number of the image.
It uses the primary key if it’s integer, but can be overridden,
and must be implemented when the primary key is not integer or
composite key.
object_type
(str
) The identifier string of the image type.
It uses __tablename__
(which replaces underscores with
hyphens) by default, but can be overridden.
open_file
(store=sqlalchemy_imageattach.context.current_store, use_seek=False)¶Opens the file-like object which is a context manager
(that means it can used for with
statement).
If use_seek
is True
(though False
by default)
it guarentees the returned file-like object is also seekable
(provides seek()
method).
Parameters: | store (Store ) – the storage which contains image files.
current_store
by default |
---|---|
Returns: | the file-like object of the image, which is a context
manager (plus, also seekable only if use_seek
is True ) |
Return type: | file ,
FileProxy ,
file-like object |
original
= Column('original', Boolean(), table=None, nullable=False, default=ColumnDefault(False))¶(bool
) Whether it is original or resized.
width
= Column('width', Integer(), table=None, primary_key=True, nullable=False)¶(numbers.Integral
) The image’s width.
sqlalchemy_imageattach.entity.
ImageSet
¶Alias of SingleImageSet
.
Deprecated since version Use: SingleImageSet
to distinguish from
MultipleImageSet
.
Changed in version 1.0.0: Renamed to SingleImageSet
, and this remains only for backward
compatibility. It will be completely removed in the future.
alias of SingleImageSet
sqlalchemy_imageattach.entity.
ImageSubset
(_query, **identity_map)¶Image set which is contained by MultipleImageSet
.
It contains one canonical original
image and
its thumbnails, as it’s also a subtype of BaseImageSet
like SingleImageSet
.
New in version 1.0.0.
sqlalchemy_imageattach.entity.
MultipleImageSet
(entities, session=None)¶Used for image_attachment()
is congirued with uselist=True
option.
Like SingleImageSet
, it is a subtype of BaseImageQuery
.
It can be filtered using filter()
method or sorted using order()
method.
Unlike SingleImageSet
, it is not a subtype of
BaseImageSet
, as it can contain multiple image sets.
That means, it’s not image set, but set of image sets.
Its elements are ImageSubset
objects, that are image sets.
New in version 1.0.0.
get_image_set
(**pk)¶Choose a single image set to deal with. It takes criteria through keyword arguments. The given criteria doesn’t have to be satisfied by any already attached images. Null image sets returned by such criteria can be used for attaching a new image set.
Parameters: | **pk – keyword arguments of extra discriminating primary key column names to its values |
---|---|
Returns: | a single image set |
Return type: | ImageSubset |
image_sets
¶(typing.Iterable
[ImageSubset
]) The set of
attached image sets.
sqlalchemy_imageattach.entity.
SingleImageSet
(entities, session=None)¶Used for image_attachment()
is congirued uselist=False
option (which is default).
It contains one canonical original
image and
its thumbnails, as it’s a subtype of BaseImageSet
.
New in version 1.0.0: Renamed from ImageSet
.
sqlalchemy_imageattach.entity.
image_attachment
(*args, **kwargs)¶The helper function, decorates raw
relationship()
function, sepcialized for
relationships between Image
subtypes.
It takes the same parameters as relationship()
.
If uselist
is True
, it becomes possible to attach multiple
image sets. In order to attach multiple image sets, image entity types
must have extra discriminating primary key columns to group each image set.
If uselist
is False
(which is default), it becomes
possible to attach only a single image.
Parameters: |
|
---|---|
Returns: | the relationship property |
Return type: |
New in version 1.0.0: The uselist
parameter.