Skip to main content

Distillery

https://secure.travis-ci.org/Birdback/distillery.png

distillery is another factory_girl like library for python ORMs.

Installation

pip install distillery

Distilleries

Each distillery has a __model__ and a set of attributes and methods. The __model__ is the ORM model class from which instance will be produced:

class UserDistillery(MyOrmDistillery):
    __model__ = User

Attributes

A distillery class attribute defines default values for specific model field:

class UserDistillery(MyOrmDistillery):
    __model__ = User

    username = "defaultusername"

The distillery’s attribute values act as defaults. If a User object is created using this distillery, its username attribute will default to "defaultusername".

Lazy attributes

Using the lazy decorator, you can provide dynamic attributes.

from distillery import lazy

class UserDistillery(MyOrmDistillery):
    __model__ = User

    username = "defaultusername"

    @lazy
    def email_address(cls, instance, sequence):
        return "%s@%s" % (instance.username, instance.company.domain)

All new User created from UserDistillery will have an email_address computed from his username and his company domain.

Note: all lazies received an instance and a sequence that are the object instance and an auto-incremented sequence, respectively.

Hooks

A distillery can provide an _after_create class method to hook into the factory machinery.

class UserDistillery(MyOrmDistillery):
    __model__ = User

    username = "defaultusername"

    @classmethod
    def _after_create(cls, instance):
        # Do stuff after instance creation
        # ...

Distillery.init()

The init() method creates and populates a new instance.

user = UserDistillery.init()
assert user.username == "defaultusername"
assert user.id is None

user = UserDistillery.create(username="overriddenusername")
assert user.username == "overriddenusername"
assert user.id is None

Distillery.create()

The create() method initializes the object using init() and subsequently saves it.

user = UserDistillery.create()
assert user.username == "defaultusername"
assert user.id is not None

Distillery.bulk()

Creates instances in bulk.

users = UserDistillery.bulk(12, username="user_%(i)%")
assert users[7].username = 'user_7'

Sets

The distillery.Set class acts as a fixture container.

It’s required to define a __distillery__ attribute which is used to create objects.

from distillery import Set

class UserSet(Set):
    __distillery__ = UserDistillery

    class jeanphix:
        username = 'jeanphix'

To create the fixtures, simply instantiate the set.

users = UserSet()
assert users.jeanphix.username == 'jeanphix'

Importantly, as long as a reference to the instantiated set is held (e.g. the users variable in this example), the set can be called again and the same instance is returned:

assert UserSet() is UserSet()

You can reference other sets, too. Note that you must reference using the class, or use a lazy attribute (described later):

from distillery import Set

class CompanySet(Set):
    __distillery__ = CompanyDistillery

    class my_company:
        name = 'My company'

class UserSet(Set):
    __distillery__ = UserDistillery

    class jeanphix:
        username = 'jeanphix'
        company = CompanySet.company


users = UserSet()
assert users.jeanphix.company == 'My company'

In addition to classes, methods can be defined; each will result in an object which is added to the set.

class ProfileSet(Set)
    class __distillery__:
        __model__ = Profile

    admin = lambda s: UserDistillery.create(username='admin').profile

This functionality extends to class-based references. Note that the reference must be resolvable at the point of creation; circular relationships are currently not supported.

class UserSet(Set):
    class peter:
        friend = None

    class paul:
        friend = classmethod(lambda c: UserSet.peter)

If the on_demand flag is set, objects are created only when first accessed.

users = UserSet(on_demand=True)
users.jeanphix  # jeanphix will be created here.

Finally, sets can be nested.

class fixtures(Set):
    users = UserSet

assert fixtures().users.jeanphix.username == 'jeanphix'

Hooks

Each fixture in a set can provide an _after_create listener:

class ProfileSet(Set):
    class __distillery__:
        __model__ = Profile

    class admin:
        @classmethod
        def _after_create(cls, profile):
            profile.name = 'Full name'

assert ProfileSet().admin.name == 'Full name'

ORMs

Both Django and SQLAlchemy are supported.

Django

Django models could be distilled using DjangoDistillery that only requires a __model__ class member:

from distillery import DjangoDistillery

from django.auth.models import User

class UserDistillery(DjangoDistillery):
    __model__ = User

    #  ...

SQLAlchemy

SQLAlchemy distilleries require both the __model__ and __session__ attributes.

from distillery import SQLAlchemyDistillery

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite://', echo=False)
Session = sessionmaker()
Session.configure(bind=engine)
session = Session()
Base = declarative_base()

class User(Base):
    #  ...


class UserDistillery(SQLAlchemyDistillery):
    __model__ = User
    __session__ = session

    #  ...

Metadata

Release files for distillery 0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for distillery 0.5
File Size Uploaded Provenance Actions
distillery-0.5.tar.gz 5.6 kB Without provenance Details for distillery-0.5.tar.gz

Release files / distillery-0.5.tar.gz

Download URL distillery-0.5.tar.gz
Size 5.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e861f0f333c936771ae568ade129488d670d7b0c67055d703e69a6b50965371f
BLAKE2b-256 checksum
How to use checksums
64c65b6e53eee9fd4af84c6a1dc9bc438976e69999163c7e3a44f48b896a119e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Security for distillery 0.5

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page