The file does not pass through Django.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # ====================================================================== # Q: Customers upload videos of up to 2 GB. How do you design it? # # The file does not pass through Django. The API hands out a presigned URL for a # direct upload to S3, the browser uploads (multipart for large files), and then # calls confirm. At that point a Celery task on the heavy queue checks the file # type, transcodes and creates a thumbnail. Screens download the file from a # CDN. # A quota limit per subscription plan, a check that the file really is a # video/image (not just by its extension), and an S3 lifecycle rule for uploads # that were never confirmed. # ====================================================================== def create_upload(request): media = Media.objects.create(workspace=request.user.workspace, status='pending', name=request.data['name']) key = f'ws/{media.workspace_id}/media/{media.pk}/{uuid4()}' url = s3.generate_presigned_url( 'put_object', Params={'Bucket': BUCKET, 'Key': key, 'ContentType': request.data['content_type']}, ExpiresIn=900) Media.objects.filter(pk=media.pk).update(s3_key=key) return Response({'media_id': media.pk, 'upload_url': url}, status=201) def confirm_upload(request, pk): media = get_object_or_404(Media, pk=pk, workspace=request.user.workspace) transaction.on_commit(lambda: process_media.delay(media.pk)) return Response(status=202) # Accepted: asynchronous processing |