DEV Community

Rak
Rak

Posted on

Secure Upload URLs Buckets with Nitric in Python

Creating a secure method for users to upload files directly to an S3 bucket is a common requirement in modern web applications.

By using pre-signed URLs, you can allow a client to upload a file directly to S3 without exposing your AWS credentials, they also provide a secure mechanism to upload files directly to S3 from a client, avoiding the need to pass the file data through your server.

In this tutorial, we will leverage the Nitric SDK in Python to generate secure upload URLs for an S3 bucket, which can then be used from your front-end application.

If you haven't used the Nitric SDK before, then start with this tutorial.

Step 1: Initialize Nitric Bucket Instance

Inside the main function, initialize a new Nitric bucket instance with the name of your S3 bucket.

from nitric.resources import api, bucket
from nitric.application import Nitric
from nitric.context import HttpContext

main_api = api('main')
images = bucket('images').allow('reading')
Enter fullscreen mode Exit fullscreen mode

Step 2: Generate a Secure Upload URL

Now, generate a secure upload URL for a specific file. In this example, we are creating a URL for uploading a file named cat.png. We also specify a time-to-live (TTL) for the URL of 300 seconds (5 minutes).

from nitric.resources import bucket
from nitric.application import Nitric

assets = bucket('assets').allow('reading')

logo = assets.file('images/logo.png')

logo_url = await logo.download_url(expiry=300)

Nitric.run()
Enter fullscreen mode Exit fullscreen mode

Now, you have a secure upload URL for your cat.png file. You can use this URL in your front-end application to securely upload the cat.png file to your S3 bucket. The URL will expire after 1 hour, ensuring that the upload URL cannot be misused after a reasonable amount of time.

This setup abstracts much of the boilerplate and complexity involved in generating pre-signed URLs for S3, allowing developers to focus more on building their applications.

In the case that you want to get an image url for rendering, then simply redirect the URL with a 303 status and a location.

from nitric.resources import api, bucket
from nitric.application import Nitric
from nitric.context import HttpContext

main_api = api('main')
images = bucket('images').allow('reading')

@main_api.get('/images/:id')
async def get_image(ctx: HttpContext):
  id = ctx.req.params['id']
  url = await images.file(id).download_url()
  ctx.res.status = 303
  ctx.res.headers['Location'] = [url]

Nitric.run()
Enter fullscreen mode Exit fullscreen mode

The Nitric SDK offers a streamlined approach to interacting with AWS S3, among other cloud services, in a cloud-agnostic manner.

Top comments (0)