DEPOT - File Storage Made Easy

Welcome to the DEPOT Documentation. DEPOT is a framework for easily storing and serving files in web applications on Python2.6+ and Python3.2+.

Depot can be used Standalone or with your ORM to quickly provide attachment support to your model.

Modern web applications need to rely on a huge amount of stored images, generated files and other data which is usually best to keep outside of your database. DEPOT provides a simple and effective interface for storing your files on a storage backend at your choice (Local, S3, GridFS, Google Cloud Storage) and easily relate them to your application models (SQLAlchemy, Ming) like you would for plain data.

Depot is a swiss army knife for files that provides:

  • Multiple backends: Store your data on all of them with a single API
  • In Memory storage depot.io.memory.MemoryFileStorage provided for tests suite. Provides faster tests and no need to clean-up fixtures.
  • Meant for Evolution: Change the backend anytime you want, old data will continue to work
  • Integrates with your ORM: When using SQLAlchemy, attachments are handled like a plain model attribute. It’s also session ready: Rollback causes the files to be deleted.
  • Smart File Serving: When the backend already provides a public HTTP endpoint (like S3) the WSGI depot.middleware.DepotMiddleware will redirect to the public address instead of loading and serving the files by itself.
  • Flexible: The depot.manager.DepotManager will handle configuration, middleware creation and files for your application, but if you want you can manually create multiple depots or middlewares without using the manager.

DEPOT was presented at PyConUK 2014 and PyConFR 2014, for a short presentation you can have a look at the PyConFR slides:

Installing Depot

Installing DEPOT can be done from PyPi itself by installing the filedepot distribution:

$ pip install filedepot

Keep in mind that DEPOT itself has no dependencies, if you want to use GridFS storage, S3, GCS or any other storage that requires third party libraries, your own application is required to install the dependency. In this specific case pymongo and boto (or boto3) and google-cloud-storage are respectively needed for GridFS, S3 and GCS support.

Depot Standalone

Depot can easily be used to save and retrieve files in any Python script, Just get a depot using the depot.manager.DepotManager and store the files. With each file, additional data commonly used in HTTP like last_modified, content_type and so on is stored. This data is available inside the depot.io.interfaces.StoredFile which is returned when getting the file back:

from depot.manager import DepotManager

# Configure a *default* depot to store files on MongoDB GridFS
DepotManager.configure('default', {
    'depot.backend': 'depot.io.gridfs.GridFSStorage',
    'depot.mongouri': 'mongodb://localhost/db'
})

depot = DepotManager.get()

# Save the file and get the fileid
fileid = depot.create(open('/tmp/file.png'))

# Get the file back
stored_file = depot.get(fileid)
print stored_file.filename
print stored_file.content_type

Depot with your WebFramework

To start using DEPOT with your favourite Web Framework you can have a look at the web framework examples and read the DEPOT for Web guide.

Attaching Files to Models

Depot also features simple integration with SQLAlchemy by providing customized model field types for storing files attached to your ORM document. Just declare columns with these types inside your models and assign the files:

from depot.fields.sqlalchemy import UploadedFileField
from depot.fields.specialized.image import UploadedImageWithThumb


class Document(Base):
    __tablename__ = 'document'

    uid = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(Unicode(16), unique=True)
    content = Column('content_col', UploadedFileField)  # plain attached file

    # photo field will automatically generate thumbnail
    photo = Column(UploadedFileField(upload_type=UploadedImageWithThumb))


# Store documents with attached files, the source can be a file or bytes
doc = Document(name=u'Foo',
               content=b'TEXT CONTENT STORED AS FILE',
               photo=open('/tmp/file.png'))
DBSession.add(doc)
DBSession.flush()

# DEPOT is session aware, commit/rollback to keep or delete the stored files.
DBSession.commit()

Fetching back the attachments is as simple as fetching back the documents themselves:

d = DBSession.query(Document).filter_by(name=u'Foo').first()
print d.content.file.read()
print d.photo.url
print d.photo.thumb_url

In case the backend doesn’t already provide HTTP serving of the files you can use the DepotMiddleware to serve them in your application:

wsgiapp = DepotManager.make_middleware(wsgiapp)

API Reference

If you are looking for information on a specific function, class or method, this part of the documentation is for you.