반응형
Django에서 boto3를 사용하여 S3와 연결 및 파일 업로드
준비사항
- AWS IAM user 셋업
- AWS S3 bucket 셋업
1. boto3 라이브러리 설치
- boto3는 파이썬용 AWS라이브러리이다.
pip install boto3
2. 코드 작성
2-1. 엔드포인트
우선 호출하는 부분에서 어떻게 호출할 것인지를 작성해본다.
- 장고에서는 전송된 파일이
request.FILES
를 통해 전달된다. FileUpload
라는 wrapper class를 통해 S3 클라이언트를 생성하고 ,파일업로드 기능을 수행하는 함수를 호출하여 profile_image_url 값을 리턴받는다.
from storages import FileUpload, s3_client
class ProfileUploadView(View):
def post(self, request):
# ...
file = request.FILES['filename']
profile_image_url = FileUpload(s3_client).upload(file)
# ...
2-2. storages.py
storages.py에서는 FileUpload
, MyS3Client
클래스와 MyS3Client 클래스로 s3_client 인스턴스
를 생성해줄 것이다.
FileUpload 클래스
- 어떤 Service client를 받더라도 엔드포인트에서는 FileUpload클래스의 인스턴스를 받아서 사용하면 된다.
- 이런 class를 wrapper class라고 하며, 파일업로드를 구현하는 개발자는 storages.py안의 FileUpload클래스와 service client만 알고 있으면 된다.
class FileUpload:
def __init__(self, client):
self.client = client
def upload(self, file):
return self.client.upload(file)
- FileUpload 클래스를 초기화할 때 인자로 service client를 받는다.
s3_client = FileUpload(s3_client)
- upload() 메서드를 호출하면 client.upload() 메서드를 호출한다.
s3_client = FileUpload(s3_client).upload(File)
MyS3Client 클래스
- S3 클라이언트를 생성해서 연결하고, 파일을 업로드 하는 부분
uuid
를 사용해서 파일이름이 중복되어 덮어씌워지는 것을 방지하였다.- MyS3Client의 인스턴스(
s3_client
)를 생성해놓고 사용할 수 있도록 하였다.
import boto3
import uuid
from config.settings import AWS_ACCESS_KEY, AWS_SECRET_KEY, S3_BUCKET_NAME
class MyS3Client:
def __init__(self, access_key, secret_key, bucket_name):
boto3_s3 = boto3.client(
's3',
aws_access_key_id = access_key,
aws_secret_access_key = secret_key
)
self.s3_client = boto3_s3
self.bucket_name = bucket_name
def upload(self, file):
try:
file_id = str(uuid.uuid4())
extra_args = { 'ContentType' : file.content_type }
self.s3_client.upload_fileobj(
file,
self.bucket_name,
file_id,
ExtraArgs = extra_args
)
return f'https://{self.bucket_name}.s3.ap-northeast-2.amazonaws.com/{file_id}'
except:
return None
# MyS3Client instance
s3_client = MyS3Client(AWS_ACCESS_KEY, AWS_SECRET_KEY, S3_BUCKET_NAME)
마치며...
S3를 처음 사용해보면서 이미지를 클라우드에 저장해놓고 거기서 생성된 Url을 Database에 저장한다는 개념이 낯설었는데 직접 해보니깐 개념이 잡히는 것 같았다.
또 파일업로드 하는 부분을 클래스화하면서 완벽하진 않겠지만, 좀 더 구조적으로 깔끔하게 작성한 것 같아서 만족스럽다. 😀️
반응형
'프로그래밍 > 인프라' 카테고리의 다른 글
Amazon Virtual Private Cloud (VPC) (0) | 2021.11.24 |
---|---|
AWS (0) | 2021.11.17 |