AWS: Make a file downloadable by https link - python

I have a local .exe file and I want to make it available by https so everyone can download it.
example: "download my app here: https://look_how_downloadable_i_am.exe
If I can update the file with python and manually with interface, it would be perfect ! (the possibility to automate the process and keep it simple if done manually).
It's maybe possible with AWS S3 or/and Lambda.

The most straightforward way would be using an s3 bucket to enable downloads to the file.
Steps are:
Upload file to the bucket
Select the file after it gets uploaded, press actions and select make public
This will make the file publicly downloadable through its unique link. In order to use your own custom domain and link you will have to use CloudFront as #jordanm suggested.
You can also use a python script to update or download your file, you can find demo codes and documentations in Reference 3
Reference 1: How to create download link for an Amazon S3 bucket's object?
Reference 2: https://aws.amazon.com/premiumsupport/knowledge-center/read-access-objects-s3-bucket/
Reference 3: https://docs.aws.amazon.com/code-samples/latest/catalog/code-catalog-python-example_code-s3.html

You can use boto3 to programmatically upload a local file to a bucket, than just edit the buckets permissions to allow public read. Or instead of editing the buckets permissions, when uploading the file just edit the ACL s3.upload_file(upload_path, "bucket-name", file-key, ExtraArgs={'ACL': "public-read"})
upload_path just being the local file path, and file-key being the object name

Related

Images are not loading from an Amazon S3 bucket

I am doing a Django project. I have hosted my static files on Amazon S3. It has been successfully uploaded to it. But, the images are not loading when I run the server.
When I inspect the image field it shows:
https://django-ecommerce-files.s3.amazonaws.com/images/logo.png%22%20id=%22image%22%20style=%22width:%2040px;%20height:40px%22%3E
When I double clicked it. It shows this error:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>07PX6KHYASHT3008</RequestId>
<HostId>pJCxChq1JHlw/GL0Zy/W+PvX1TevOf/C60Huyidi8+0GMAs8geYlXSrEgo6m9vllL0PouTn6NAA=
</HostId>
</Error>
When working with S3 bucket, there is a need to make your resources(files) publicly accessible. You can either do that programmatically at the point of uploading to S3 or from the AWS console. please check how you can enable public access to your files here
Make sure that you have changed the public access settings for the S3 bucket, such that it allows files to be accessed by your app (with the right credentials).
Your requirement may vary, so take a look at their user manual.
Check the Permissions tab under the bucket.
Or, you can also take a look at the actions allowed on your S3 bucket, it must be configured to allow read/write. Refer the docs for a few examples
im not sure if this works. can you try enabling the static hosting on your s3?
go to your s3.
go to properties, scroll down to the bottom
enable the static hosting
a png file on s3 would look like this(the link works btw):
https://aws-cicd-react.s3.ap-southeast-1.amazonaws.com/logo512.png
addendum:
if you want to see the url of your file:
In your s3, click the file then go to properties
look at the Object URL

How to download a file from private S3 bucket using its URL?

I have a file that is stored on AWS s3 at https://xyz.s3.amazonaws.com/foo/file.json and I want to download that into my local machine using Python. However, the URL cannot be accessed publicly. I have the Account ID, IAM user name, and password (but NO Access Key or Secret Access Key and no permissions to view/change them either) to the resource that contains this file. How can I programmatically download this file instead of doing so from the console?
You could generate an Amazon S3 pre-signed URL, which would allow a private object to be downloaded from Amazon S3 via a normal HTTPS call (eg curl). This can be done easily using the AWS SDK for Python, or you could code it yourself without using libraries. Answer by John Rotenstein
here

How to read and write to a text file using python while deploying on heroku

I use a bot that writes (file ids) of the files that sent from user to a text file and then read from this text file the (file ids) then send it back to the user.The method worked, but when I deploy it to Heroku, I can no longer see, process, or download the text file.
Is there a way to view the text files that we deploy to heroku? Or is there a way to upload the text files on a cloud website and then make the bot open (read & write) the text file using the text file URL (but I think this would allow any user on the internet to access and modify my text files, which means it is not safe)? Create SQL database and upload text files and link each text file with its own URL (But I'm new to SQL)?
Is there any other simple method to solve this problem? What do you advise me to do in this case?
https://github.com/zieadshabkalieh/a
NOTE: The text file in my code named first.txt
Heroku has an ephemeral filesystem: every file created by the application will be removed (also any change to existing files deployed with the application) when there is a new deployment or application restart.
Heroku Dynos also restart every 24 hours.
It is a good idea to persist data to a remote storage (like S3) or a DB (always a good option but requires a little bit more work).
For reading/writing simple files you can check HerokuFiles repository with some Python examples and options. I would suggest S3 (using Python boto module) as it is easy to use, even if the number/size of files will one day increase.

How to copy a file via the browser to Amazon S3 using Python (and boto)?

Creating a file (key) into Amazon S3 using Python (and boto) is not a problem.
With this code, I can connect to a bucket and create a key with a specific content:
bucket_instance = connection.get_bucket('bucketname')
key = bucket_instance.new_key('testfile.txt')
key.set_contents_from_string('Content for File')
I want to upload a file via the browser (file dialogue) into Amazon S3.
How can I realize this with boto?
Thanks in advance
You can't do this with boto, because what you're asking for is purely client-side - there's no direct involvement from the server except to generate the form to post.
What you need to use is Amazon's browser-based upload with POST support. There's a demo of it here.
do you mean this one? Upload files in Google App Engine

Asynchronous File Upload to Amazon S3 with Django

I am using this file storage engine to store files to Amazon S3 when they are uploaded:
http://code.welldev.org/django-storages/wiki/Home
It takes quite a long time to upload because the file must first be uploaded from client to web server, and then web server to Amazon S3 before a response is returned to the client.
I would like to make the process of sending the file to S3 asynchronous, so the response can be returned to the user much faster. What is the best way to do this with the file storage engine?
Thanks for your advice!
I've taken another approach to this problem.
My models have 2 file fields, one uses the standard file storage backend and the other one uses the s3 file storage backend. When the user uploads a file it get's stored localy.
I have a management command in my application that uploads all the localy stored files to s3 and updates the models.
So when a request comes for the file I check to see if the model object uses the s3 storage field, if so I send a redirect to the correct url on s3, if not I send a redirect so that nginx can serve the file from disk.
This management command can ofcourse be triggered by any event a cronjob or whatever.
It's possible to have your users upload files directly to S3 from their browser using a special form (with an encrypted policy document in a hidden field). They will be redirected back to your application once the upload completes.
More information here: http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1434
There is an app for that :-)
https://github.com/jezdez/django-queued-storage
It does exactly what you need - and much more, because you can set any "local" storage and any "remote" storage. This app will store your file in fast "local" storage (for example MogileFS storage) and then using Celery (django-celery), will attempt asynchronous uploading to the "remote" storage.
Few remarks:
The tricky thing is - you can setup it to copy&upload, or to upload&delete strategy, that will delete local file once it is uploaded.
Second tricky thing - it will serve file from "local" storage until it is not uploaded.
It also can be configured to make number of retries on uploads failures.
Installation & usage is also very simple and straightforward:
pip install django-queued-storage
append to INSTALLED_APPS:
INSTALLED_APPS += ('queued_storage',)
in models.py:
from queued_storage.backends import QueuedStorage
queued_s3storage = QueuedStorage(
'django.core.files.storage.FileSystemStorage',
'storages.backends.s3boto.S3BotoStorage', task='queued_storage.tasks.TransferAndDelete')
class MyModel(models.Model):
my_file = models.FileField(upload_to='files', storage=queued_s3storage)
You could decouple the process:
the user selects file to upload and sends it to your server. After this he sees a page "Thank you for uploading foofile.txt, it is now stored in our storage backend"
When the users has uploaded the file it is stored temporary directory on your server and, if needed, some metadata is stored in your database.
A background process on your server then uploads the file to S3. This would only possible if you have full access to your server so you can create some kind of "deamon" to to this (or simply use a cronjob).*
The page that is displayed polls asynchronously and displays some kind of progress bar to the user (or s simple "please wait" Message. This would only be needed if the user should be able to "use" (put it in a message, or something like that) it directly after uploading.
[*: In case you have only a shared hosting you could possibly build some solution which uses an hidden Iframe in the users browser to start a script which then uploads the file to S3]
You can directly upload media to the s3 server without using your web application server.
See the following references:
Amazon API Reference : http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?UsingHTTPPOST.html
A django implementation : https://github.com/sbc/django-uploadify-s3
As some of the answers here suggest uploading directly to S3, here's a Django S3 Mixin using plupload:
https://github.com/burgalon/plupload-s3mixin
I encountered the same issue with uploaded images. You cannot pass along files to a Celery worker because Celery needs to be able to pickle the arguments to a task. My solution was to deconstruct the image data into a string and get all other info from the file, passing this data and info to the task, where I reconstructed the image. After that you can save it, which will send it to your storage backend (such as S3). If you want to associate the image with a model, just pass along the id of the instance to the task and retrieve it there, bind the image to the instance and save the instance.
When a file has been uploaded via a form, it is available in your view as a UploadedFile file-like object. You can get it directly out of request.FILES, or better first bind it to your form, run is_valid and retrieve the file-like object from form.cleaned_data. At that point at least you know it is the kind of file you want it to be. After that you can get the data using read(), and get the other info using other methods/attributes. See https://docs.djangoproject.com/en/1.4/topics/http/file-uploads/
I actually ended up writing and distributing a little package to save an image asyncly. Have a look at https://github.com/gterzian/django_async Right it's just for images and you could fork it and add functionalities for your situation. I'm using it with https://github.com/duointeractive/django-athumb and S3

Categories

Resources