3👍
This isn’t too difficult. The steps are to generate a policy document, sign it, and then use that signature to POST the file to S3. I wrote a little application called sbit3 that does this. Take a look here: https://github.com/victortrac/sbit3/blob/master/server/sbit3.py, specifically the PostHandler class:
class PostHandler(tornado.web.RequestHandler):
def _generate_policy_doc(self, conditions, expiration=None):
if not expiration:
# Sets a policy of 15 minutes to upload file
expiration = datetime.datetime.utcnow() + datetime.timedelta(minutes=15)
conditions = [ { "bucket" : conditions["bucket"] },
[ "starts-with", "$key", "uploads/"],
{ "acl" : conditions["acl"] },
{ "success_action_redirect" : conditions["success_action_redirect"] } ]
conditions_json = json.dumps({ "expiration" : expiration.strftime("%Y-%m-%dT%H:%M:%SZ"),
"conditions" : conditions })
logging.debug("Policy doc generated: {0}".format(conditions_json))
return base64.b64encode(conditions_json)
def _sign_policy(self, policy):
signature = base64.b64encode(hmac.new(settings.aws_secret_key, policy, hashlib.sha1).digest())
return signature
def get(self, expiration):
try:
expiration = int(expiration)
# Set max expiration to 7200 minutes (5 days)
if not 0 < expiration < 7200:
raise tornado.web.HTTPError(403)
_expireTimestamp = datetime.datetime.utcnow() + datetime.timedelta(minutes=expiration)
except ValueError:
raise tornado.web.HTTPError(403)
# Associate _uuid to expiration in sdb
_uuid = uuid.uuid4().hex
sdb_conn.add_item(_uuid, expireTimestamp=_expireTimestamp)
conditions = { "bucket" : settings.bucket,
"acl" : settings.acl,
"success_action_redirect" : settings.site_url + "/f/" + _uuid }
policy_document = self._generate_policy_doc(conditions)
signature = self._sign_policy(policy_document)
self.render("post.html", conditions=conditions,
aws_access_id=settings.aws_access_id,
policy_document=policy_document,
signature=signature)
The look at the post.html that sets up the form:
<form action="https://{{ conditions["bucket"] }}.s3.amazonaws.com" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="uploads/${filename}">
<input type="hidden" name="AWSAccessKeyId" value="{{ aws_access_id }}">
<input type="hidden" name="acl" value="{{ conditions["acl"] }}">
<input type="hidden" name="success_action_redirect" value="{{ conditions["success_action_redirect"] }}">
<input type="hidden" name="policy" value="{{ policy_document }}">
<input type="hidden" name="signature" value="{{ signature }}">
File to upload to S3:
<input name="file" type="file">
<br>
<input type="submit" value="Upload File to S3">
</form>
- [Django]-Django – Admin – Inline – 'extra' value based on some condition
- [Django]-Get the first element in the for loops in the Django template
2👍
In order to upload directly to S3(bypassing your webserver) you will need to directly post through the browser to a pre-authorized url. Read this article from amazon that explains how it needs to work.
I don’t know of anything that will do this for you in django, but it is not too difficult to make the request yourself. You can also use something like uploadify to do the actual posting from the browser, you just need to give it the right url.
- [Django]-Why "no such table: django_session" when trying to use admin?
- [Django]-I can't insert a footnote into the copied text