동아리에서 TIL 활동을 같이하는 형이 있는데, 그 형이 S3에 대한 이야기를 올린 적이 있다. 이번 해커톤 프로젝트로 개발중인 서비스에는 이미지 파일을 업로드하고 읽어오는 기능이 필요하다. 그래서 그 글을 읽었던 경험이 떠올랐고, S3에 대해 알아봐야겠다는 생각을 했다.
원래 오늘 django-storages까지 알아보려 했는데, 해커톤 프로젝트랑 병행하니깐 시간이 없어서, django-storages부터는 내일 알아보고자 한다. 역시 이번에도 옵시디언 노트를 복붙한 것이다. 여담으로, 이번 옵시디언 업데이트로 Base라는 기능이 생겼다. 그래서 이것에 대해 알아볼까 생각했는데, 조금 만져보니까 딱히 사용법이 어려운 것도 아니라서 굳이 정리할 필요는 없을 것 같다. 간단히 써봤을 때 들었던 느낌은 뭔가 옵시디언을 노션처럼 활용하고 싶은 사람들에게 유용할 것 같다는 느낌이었다.
Boto3를 이용하기 위해선 액세스 키와 시크릿 키가 필요함
루트에서 액세스 키를 발급할 수도 있지만 IAM에서 발급하는 것을 추천하고 있음
AmazonS3FullAccess를, 읽기만 원한다면 AmazonS3ReadOnlyAccess 권한 정책 연결하면 될듯$ pip install boto3
Boto3은 여러 location에서 설정값을 탐색할 수 있는데, 탐색 순서는 후술할 각 방법들의 제목 순서와 같음 (1->2->3)
botocore.config의 Config 객체를 이용하는 방법
공식 문서의 예시 코드
import boto3
from botocore.config import Config
my_config = Config(
region_name = 'us-west-2',
signature_version = 'v4',
retries = {
'max_attempts' = 'v4'
}
)
Boto3는 기본적으로 ~/.aws/config 파일에서 설정을 검색함
이 파일은 ini 포맷으로 작성된 파일이며, [default] 섹션을 반드시 포함
이 설정 파일로 인한 설정값은 환경 변수나 Config 객체에 의해 덮어씌워질 수 있음(앞서 서술한 탐색 순서에 의해 무시될 수 있음)을 유의
s3 = boto3.resource('s3', aws_access_key_id=(액세스 키), aws_secret_access_key=(시크릿 키))
export$ export AWS_ACCESS_KEY_ID=(액세스 키)
$ export AWS_SECRET_ACCESS_KEY=(시크릿 키)
⚠️ 주의: Config 객체의 생성자에는 액세스 키와 시크릿 키 매개변수가 없음
import boto3
s3 = boto3.resource('s3',
aws_access_key_id='액세스 키',
aws_secret_access_key='시크릿 키',
config=Config(
region_name='ap-northeast-2',
signature_version='s3v4'),)
)
Config에서 region_name과 signature_version을 위와 같이 지정해야 Presigned URL 생성했을 때 오류가 생기지 않았음with open('helloworld.txt', 'rb') as data:
s3.Bucket('버킷이름').put_object(Key='helloworld.txt', Body=data)
helloworld.txt 파일을 버킷에 업로드Key와 Body가 대문자로 시작하는 점 유의obj = s3.Object(bucket_name='버킷이름', key='helloworld.txt')
response = obj.get()
data = response['Body'].read()
with open('helloworld2.txt', 'wb') as f:
f.write(data)
helloworld.txt 파일을 읽어서 로컬에 helloworld2.txt라는 파일로 저장body가 아니라 Body인 점에 주의해야 하며, read 메소드는 bytes 객체를 반환obj = s3.Object(bucket_name='버킷이름', key='image.jpg')
obj.download_file('test.jpg')
write 메소드를 쓸 수도 있지만, s3.Object에는 download_file 메소드가 있음image.jpg 파일을 다운로드해서 로컬에 test.jpg라는 이름으로 저장https://버킷명.s3.리전명.amazonaws.com/[폴더명/]파일명모든 사람에 대한 읽기 권한이 없는 객체의 경우 위 url로 들어가면 액세스가 거부되었다고 나옴
이럴 때, Presigned URL (미리 서명된 URL)을 생성하여 지정된 시간동안 파일 공유 가능
그런데 이 기능은 resource에서는 불가능하고 client에서만 가능(generate_presigned_url)함
client = s3.meta.client
response = client.generate_presigned_url('get_object',
Params={'Bucket': '버킷이름', 'Key': 'image.jpg'},
ExpiresIn=300,)
print(response)
meta.client 속성을 통해 가져올 수 있음ExpiresIn의 값은 초 단위를 기준으로 함. 즉, 이 링크는 5분 후 만료됨