adding the s3 and cloudfront
All checks were successful
Deploy Beta (NATIVE) / deploy (push) Successful in 34s

This commit is contained in:
vickytechkey 2026-08-20 11:21:14 +05:30
parent 05e313b837
commit f1ee0b5774
6 changed files with 117 additions and 1 deletions

View file

@ -14,11 +14,29 @@ class CategoryListField(serializers.RelatedField):
class SupplierProfileSerializer(serializers.ModelSerializer):
onboarding_step = serializers.SerializerMethodField()
categories = CategoryListField(many=True, queryset=Category.objects.all(), required=False)
aadhar_url = serializers.SerializerMethodField()
pan_url = serializers.SerializerMethodField()
logo_url = serializers.SerializerMethodField()
class Meta:
model = SupplierProfile
exclude = ('user',)
def get_aadhar_url(self, obj):
from .views import get_document_url
request = self.context.get('request')
return get_document_url(obj.aadhar_s3_key, request)
def get_pan_url(self, obj):
from .views import get_document_url
request = self.context.get('request')
return get_document_url(obj.pan_s3_key, request)
def get_logo_url(self, obj):
from .views import get_document_url
request = self.context.get('request')
return get_document_url(obj.logo_s3_key, request)
def get_onboarding_step(self, obj):
if obj.is_profile_complete:
return 7

View file

@ -190,3 +190,52 @@ def test_wallet_withdrawal(api_client, create_user):
# Invalid amount (exceeds outstanding)
response = api_client.post(url, {'amount': '1500.00'}, format='json')
assert response.status_code == status.HTTP_400_BAD_REQUEST
@pytest.mark.django_db
def test_document_cloudfront_url_generation(api_client, create_user):
from django.conf import settings
from api.views import get_document_url
profile = create_user.profile
profile.aadhar_s3_key = 'suppliers/123/aadhar.pdf'
profile.save()
# Case 1: CloudFront Domain set
settings.AWS_CLOUDFRONT_DOMAIN = 'd12345.cloudfront.net'
url = get_document_url(profile.aadhar_s3_key)
assert url == 'https://d12345.cloudfront.net/suppliers/123/aadhar.pdf'
# Case 2: CloudFront Domain set with protocol prefix
settings.AWS_CLOUDFRONT_DOMAIN = 'https://d98765.cloudfront.net/'
url = get_document_url(profile.aadhar_s3_key)
assert url == 'https://d98765.cloudfront.net/suppliers/123/aadhar.pdf'
# Case 3: CloudFront Domain empty, fallback to Local Mock
settings.AWS_CLOUDFRONT_DOMAIN = ''
url = get_document_url(profile.aadhar_s3_key)
assert 'mock-download' in url
# Case 4: API Response includes aadhar_url, pan_url, logo_url
url = reverse('profile')
api_client.force_authenticate(user=create_user)
response = api_client.get(url)
assert response.status_code == status.HTTP_200_OK
assert 'aadhar_url' in response.data['profile']
assert 'pan_url' in response.data['profile']
assert 'logo_url' in response.data['profile']
@pytest.mark.django_db
def test_mock_download_view(api_client, create_user):
api_client.force_authenticate(user=create_user)
# 1. Upload mock file first using PUT request
upload_url = reverse('mock-upload') + '?key=test_key.pdf'
file_content = b'PDF content'
upload_resp = api_client.put(upload_url, data=file_content, content_type='application/octet-stream')
assert upload_resp.status_code == status.HTTP_200_OK
# 2. Download it
download_url = reverse('mock-download') + '?key=test_key.pdf'
download_resp = api_client.get(download_url)
assert download_resp.status_code == status.HTTP_200_OK
assert b"".join(download_resp.streaming_content) == file_content

View file

@ -4,7 +4,7 @@ from rest_framework_simplejwt.views import TokenRefreshView
from .views import (
RegisterView, LoginView, LogoutView, VerifyOtpView, ProfileView,
ProductViewSet, BulkUploadView, OrderViewSet, ReturnRequestViewSet,
WalletView, WithdrawView, SubmitGstinView, PresignedUrlView, MockUploadView
WalletView, WithdrawView, SubmitGstinView, PresignedUrlView, MockUploadView, MockDownloadView
)
router = DefaultRouter()
@ -22,6 +22,7 @@ urlpatterns = [
path('profile/submit-gstin/', SubmitGstinView.as_view(), name='submit-gstin'),
path('profile/presigned-url/', PresignedUrlView.as_view(), name='presigned-url'),
path('profile/mock-upload/', MockUploadView.as_view(), name='mock-upload'),
path('profile/mock-download/', MockDownloadView.as_view(), name='mock-download'),
path('products/bulk-upload/', BulkUploadView.as_view(), name='bulk-upload'),
path('wallet/', WalletView.as_view(), name='wallet'),
path('wallet/withdraw/', WithdrawView.as_view(), name='withdraw'),

View file

@ -7,6 +7,7 @@ import io
import os
import zipfile
from django.conf import settings
from django.http import FileResponse, Http404
from datetime import date, datetime, timedelta
from django.utils import timezone
from django.contrib.auth import authenticate
@ -286,6 +287,48 @@ class MockUploadView(APIView):
except Exception as e:
return Response({"error": f"Failed to save file locally: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
def get_document_url(s3_key, request=None):
if not s3_key:
return None
# 1. CloudFront distribution
cloudfront_domain = getattr(settings, 'AWS_CLOUDFRONT_DOMAIN', None)
if cloudfront_domain:
domain = cloudfront_domain.replace('https://', '').replace('http://', '').strip('/')
return f"https://{domain}/{s3_key}"
# 2. AWS S3 fallback
aws_access = os.environ.get('AWS_ACCESS_KEY_ID') or os.environ.get('AWS_ACCESS_KEY')
aws_secret = os.environ.get('AWS_SECRET_ACCESS_KEY') or os.environ.get('AWS_SECRET_KEY')
bucket_name = os.environ.get('AWS_STORAGE_BUCKET_NAME') or os.environ.get('AWS_BUCKET_NAME') or 'betasupplierdocument-764709663363-ap-south-2-an'
region_name = os.environ.get('AWS_REGION', 'ap-south-2')
if aws_access and aws_secret:
return f"https://{bucket_name}.s3.{region_name}.amazonaws.com/{s3_key}"
# 3. Local Mock fallback
path = f"/api/profile/mock-download/?key={s3_key}"
if request:
return request.build_absolute_uri(path)
return path
class MockDownloadView(APIView):
permission_classes = [AllowAny]
def get(self, request):
s3_key = request.query_params.get('key')
if not s3_key:
return Response({"error": "key query param is required"}, status=status.HTTP_400_BAD_REQUEST)
base_dir = os.environ.get('UPLOAD_MOUNT_DIR', '/home/ubuntu/mnt/s3files/supplierdocuments')
if not os.path.exists('/home/ubuntu/mnt/s3files/supplierdocuments') and not os.environ.get('UPLOAD_MOUNT_DIR'):
base_dir = os.path.join(settings.BASE_DIR, 'mnt/s3files/supplierdocuments')
file_path = os.path.join(base_dir, s3_key)
if os.path.exists(file_path):
return FileResponse(open(file_path, 'rb'))
raise Http404("File not found")
class PresignedUrlView(APIView):
permission_classes = [IsAuthenticated]

View file

@ -314,3 +314,7 @@ LOGGING = {
# Media files (uploads)
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# CloudFront Domain Configuration
AWS_CLOUDFRONT_DOMAIN = os.environ.get('AWS_CLOUDFRONT_DOMAIN', '')

View file

@ -0,0 +1 @@
PDF content