Step-by-Step Guide to Building an Image Uploader Using AWS S3 and Django
Upload and Fetch Images on AWS S3 with Django using Pre-Signed URLs
Here we are going to build a Web Page, where we can Upload images and fetch back from S3 bucket, where S3 Bucket is a service offered by Amazon Web Services for storing Objects which can include all file types. Here the project being a Image Upload we will be using Images. For fetching back from S3 Bucket we will be using Pre-Signed URLs with time expiry.
Requirements
AWS Account
Python
pip
AWS Account
Login to your AWS Console - https://aws.amazon.com/ - as an IAM User or Root User
After login, you can change to Dark Theme using the settings icon beside Region
Creating Access Keys and Secret Access Keys
Click on the Security credentials in the Top right drop down menu - link - https://us-east-1.console.aws.amazon.com/iam/home#/security_credentials
If not you can use your root account to create Access Keys, but Best Practice is creating a IAM user and using their Access Keys
-
Click on the Create Access Key
Below is creating the Access Keys for Root user
Store the created Access Keys and Secret access key for Root User or you can Download then as
.csv
Best Practice - Once the Project is completed, you should delete the created Access Keys and Secret access key for Root User
Creating a New IAM User
You can create IAM user and can give permissions to the IAM user by attaching
S3 bucket Policy
Now, we are creating New User - type IAM in the Search bar and click the link
You will lead to this below page
Here Left side, click on Users Tab and click on the Create User in the Users page
It will lead to below image - add User name and select AWS Console Access
- Click Next - select Attach Policies - here I had given S3 Full Access Policy - If needed you can fine grain them
Click Create User - it will shows you the Console link to login, User Name and Password - store them - you can download the them as
.csv
fileGo back to the Users tab - you can see a list of Users created - click on the User - created in the last step
You can see the Security Credentials tab - Click the Create Access Key
-
Select the Command Line Interface(CLI)
Add the Description click Create Access Key
Store the created Access Keys and Secret access key for IAM User or you can Download then as
.csv
Best Practice - Once the Project is completed, you should delete the created Access Keys and Secret access key for IAM User - if you are not using the IAM user once project is done - you can delete the IAM user
S3 Bucket Creation
If you logging as IAM User, make sure you had S3 Bucket creation, list, delete access
Search for "S3" in the search bar - click the link
You can see the below Image
On the Top Right Corner - you can see Mumbai which is my region - you can change your region based on your location or you can host your S3 bucket over in the region (nearer the region faster access to the objects in S3 bucket)
Click on Create Bucket
In the General configuration - check the AWS Region Name - you can change the region if needed
Give an Unique Bucket name - it should be unique - I had given django-image-upload-2024
Then don't change any settings - scroll down and click Create Bucket
After creating the S3 Bucket, upload a file to check if the file can accessible from Internet or Outside - while creating the S3 Bucket we had blocked All Public access - click on the Permissions tab to check
-
Click on the Upload - Add Files - Select the Image you want to upload and click Upload
You can see Image is upload - click on the image - you can check all the Details
Here you need to consider Object URL and Open at the top - if you click Open the Image open in New tab with Pre signed URL and when Open with the Object URL you can't access
Below is with Object URL - if you are not Blocking Public Access the Bucket will available to Outside world or Internet - they can fetch your data. To overcome this issue we are using Pre-Signed URLs
Below is with Pre Signed URL - here you can see text after
.jpg
while compared to Object URL - Pre Signed URL is like token with Object URL - it is accessible for 12 HoursIn the Object Actions - click the Share with a Pre-Signed URL - here you can mention the number of interval Minutes - then after the Link expires you can't access them
So, using Pre-Signed URLs you can Access the objects in S3 Buckets with Block Public Access
So, now we move to our Project we implement Images Upload to S3 Bucket, using Pre-signed with certain time interval access using Django
Git Repository
Git clone this repo - https://github.com/harshakp06/django-image-upload.git
Make sure git installed on your system.
git clone https://github.com/harshakp06/django-image-upload.git
Open folder in Code Editor
Create Virtual Environment
For Unix/Linux
python3 -m venv .venv
source .venv/bin/activate
For Windows
python -m venv .venv
.venv\Scripts\activate
Deactivate a virtual environment
Don't use the command now - once the project is finished use this
deactivate
Install Dependencies
Dependencies list requirements.txt
is present in src/
folder
cd src/
pip install -r requirements.txt
Once all the dependencies are installed
Run Django Server
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
Default port of Django is :8000 - open http://127.0.0.1:8000/
on any browser - if you can see below image as Home Page - all the configuration went well and working
If you got any error/exception about app_image
table - it means migration haven't happen for app
folder where our models are present
Run below command to migrate app
models
python manage.py makemigrations app
python manage.py migrate
python manage.py runserver
Now you can see the above Home Page Image
By now, our Django project is running. But you can't upload files using the upload.
We need to configure S3 bucket with Django
Configuring S3 Bucket with Django App
Adding required values to.env
file
Check
.env.example
file present insrc/
folderRename
.env.example
file name to.env
file nameEdit the values with which we got from AWS Account and the Save the file as
.env
# AWS settings AWS_ACCESS_KEY_ID = "AWS_ACCESS_KEY_ID" AWS_SECRET_ACCESS_KEY = "AWS_SECRET_ACCESS_KEY" AWS_STORAGE_BUCKET_NAME = "AWS_STORAGE_BUCKET_NAME" AWS_S3_REGION_NAME = "AWS_S3_REGION_NAME" AWS_S3_CUSTOM_DOMAIN = "AWS_STORAGE_BUCKET_NAME_REPLACE.s3.amazonaws.com" #replace storage bucket name above
If your Django App is running and stop the App by using
Ctrl+c
or you can Kill terminalStart the Django App again
python manage.py runserver
Now go the
http://127.0.0.1:8000/
you can see the Home PageClick the Browse Button, select the image to Upload and click Upload
Check the S3 Bucket in the IAM User or Root AWS Account - you can see a Folder name
images/
- where all your uploaded Images are stored-
Click on the folder
media/
folder - you can see the upload image - you can check the Details of the object -
After Uploading Image name changes - it is in the code you can check at
src/app/
models.py
-unique_file_path
You can opening the Object/Image with Object URL - it will be access denied as mentioned
But with Open with Pre signed URL it is accessible
-
Open the same image in New tab on the Django App Home Page - you can observe the Object URL extends with AWS Access Key Id provided and added token with expiry time
Here we made it work with Access Key Id which one of the way to access S3 Objects from Outside
The Pre Signed URL will expire in 10mins - to access again reload the Home Page and then open the Image in New Tab
You can change the expiry time - check code at src/app/utils.py -
def generate_presigned_url(object_name, expiration=600):
change the expiration value to increase or decrease in expiry time, value is in secsYou can upload any number of Images to S3 Bucket
Using Code Spaces from GitHub
You can use the Code Spaces on GitHub and it's free for this project
Fork my repo on GitHub - https://github.com/harshakp06/django-image-upload
Then click on the Code after the Fork - click on Create Code Spaces
It will open in the VS Code editor in a container - the changes made in the Code Space won't reflect on the GitHub Repo - until you commit and Push to the Repo
-
You can steps steps from above Configuring S3 Bucket
You can delete the Code Space after completion of the project
Here the project came to an end, now you can deactivate your environment as mentioned above and you can remove, delete Access Key Id or IAM User.
Happy coding !