Pyramid integration¶
This page describes how to integrate keepluggable into
your existing Pyramid application by reusing the code in the
keepluggable.web.pyramid
package.
Of course you can always write your own Pyramid integration reusing our code.
Configuration¶
keepluggable is a pluggable sub-application that can be integrated into your app multiple times. Each time you start by creating a section in your INI file. Section names must start with “keepluggable “. In the following example 2 keepluggable storages are configured:
[app:main]
# Pyramid application settings go in this section.
# (...)
[keepluggable avatars]
# User images storage settings here
# (...)
[keepluggable products]
# The storage for product images is configured in this section.
# (...)
At application startup¶
For each keepluggable storage, you need to instantiate an Orchestrator:
from keepluggable.orchestrator import Orchestrator
Orchestrator.from_ini(
'avatars', # A unique name for this storage
global_settings['__file__'], # Path to INI configuration file
)
This will cause keepluggable to read the “[keepluggable avatars]” section you created earlier and set it up.
Repeat the call for each separate storage:
Orchestrator.from_ini(
'products', # A unique name for this storage
global_settings['__file__'], # Path to your INI configuration file
)
The Orchestrator class keeps track of its instances so that later, in a request, you can retrieve an instance like this:
orchestrator = Orchestrator.instances['avatars']
Create a resource for the file storage¶
We use traversal and provide a context resource mixin class which you must inherit in your own resource class:
from keepluggable.web.pyramid.resources import BaseFilesResource
class FilesResource(YourBaseResourceClass, BaseFilesResource):
keepluggable_name = "avatars" # name of the storage for this resource
namespace = 'myapp42'
The keepluggable_name
variable above lets the resource determine which
of the keepluggable storages is “mounted” on this URL.
You can use the namespace
setting to further separate files. So this
resource knows which namespace it manages. It was done above through a static
class variable, but it need not be so static. It could be a Python property,
or an instance variable set by the constructor. Your code might
calculate the namespace based on the URL.
More information is available on the component documentation:
keepluggable.web.pyramid.resources
We provide a RESTful HTTP API done with Pyramid¶
Once you have a resource, you can attach views to it. See
keepluggable.web.pyramid.views
.
Below we provide a description of what the HTTP API does.
List existing files and images¶
GET example URL: /users/joe/files
The JSON-encoded response contains, in its “items” variable, an array of metadata objects about the original uploaded files. Each metadata contains data such as id, md5, length, image_height, image_width, image_format, file_name, version etc.
For each metadata, if versions of the original were created (e. g. smaller images), they are inside the “versions” variable. They contain an “href” variable indicating the payload location.
Upload one or more files or images¶
POST example URL: /users/joe/files
Other requests in this API must be in JSON format. Not this method! It must be a common multipart/form-data POST request.
It must contain the upload(s) in a files
variable. You may also specify
other variables – they are forwarded to your metadata storage backend.
Most of the metadata is discovered on the server. This includes file length, file name, MD5 hash, image format, image size etc.
The response is in JSON format (only the request isn’t) and it has
items, an array in which each element is either
the metadata for an accepted file, or details of upload failure.
You can test failures by uploading zero-length files.
The order in the items
array is the same as the uploaded files.
Each failure has these variables:
"upload_failed": true
: A flag for you to identify the failureserror_type
: An error title, such as ‘“MY_FILE” was not stored. ‘error_msg
: A message that should be displayed to the userfile_name
: The uploaded file namemime_type
: The MIME type reported by the browser
Updating the metadata of a file or image¶
PUT example URL: /users/joe/files/<id>/@@metadata
In this case, the file is NOT identified by its MD5, but by its ID. There are 2 modes of operation:
If you do not implement and indicate a Colander schema, every variable in the request is set on the metadata entity.
If you do implement and indicate a Colander schema, it gets used for validation and the metadata entity only receives the “cleaned” data.
The most important variable that is set through this method is the description, since it is usually not sent with the original upload request.
Delete/remove a file¶
DELETE example URL: /users/joe/files/<MD5>
That last bit in the URL must be the MD5 hash (also known as the “key”) of the file that should be deleted.
This method deletes all the derivative files as well (“versions”). It deletes payloads as well as metadata entities.
No request body is necessary. May return 404 Not Found if the resource does not exist. When happy, returns 204 No Content, meaning the resource was deleted and the response has no body.