사진 올리는 API
1. Serverless Framework의 apps에서 create app클릭하여 python flask API생성 (이름은 aws-로 시작하게 하기)
2. 다음 화면에 나오는 npm(Node Package Manager) 코드에서 \부분 지우고 한줄로 만들기(이때 띄어쓰기된 부분은 그대로 살려야한다)
3. Anacomda Prompt열기, cd 프로젝트가 있는 경로이용해서 이동한 뒤 2.에서 만든 한줄을 입력 후 Enter, 그러면 해당 경로에 폴더가 만들어진다. (지금배포할거냐라는 질문에 n누른다)
4. vsc로 해당 폴더 열기, app.py로 이동 밑에 인터프리터를 내가 만든 가상환경으로 설정 후 app.py 수정
from flask import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
if __name__ == '__main__':
app.run()
※ pypi - 파이썬 라이브러리 검색할 수 있다
requirements.txt에 아직 추가 안된 라이브러리 추가해주기
Flask==1.1.4
Werkzeug==1.0.1
markupsafe==2.0.1
flask-restful
※postman - API 테스트할 수 있는 프로그램
postman으로 로컬 테스트 해주기
cmd창 열고 flask run 입력 후 Enter - 404에러 뜨면된다
5. 서버(vsc)에 boto3 깔아주기
※ boto3: 사진관련 라이브러리 (aws가 만든 라이브러리) / 이미 AWS Lambda에 깔려있으니까 requirements.txt.에 적을 필요 없다!
pypi에 boto3검색 후 설치하는 코드 복사해서 vsc에 깔아준다 (pip install boto3)
5. 포스트맨에 사진 올리는 API만들어준다
사진을 보내는 거니까 POST선택, url부분은 로컬 경로/photo로 한다
저장한 사진을 Value에 가져온다.
6. vsc에 해당 경로와 관련된 코드 추가한다.
app.py
from flask import Flask
from flask_restful import Api
from resources.photo import PhotoResource
app = Flask(__name__)
api = Api(app)
api.add_resource( PhotoResource ,'/photo')
if __name__ == '__main__':
app.run()
photo.py
from flask_restful import Resource
from flask import request
from datetime import datetime
from config import Config
import boto3
class PhotoResource(Resource) :
def post(self):
# 1. 클라이언트로부터 데이터 받아온다
print(request.files)
# 사진이 필수인 경우의 코드
if 'photo' not in request.files:
return{'result':'fail','error':'파일없음'},400
# 유저가 올린 파일을 변수로 만든다
file = request.files['photo']
# 파일명을 유니크하게 만들어준다
current_time = datetime.now()
print(current_time.isoformat().replace(':','_').replace('.','_')+'.jpg')
new_filename = current_time.isoformat().replace(':','_').replace('.','_')+'.jpg'
# 새로운 파일명으로, s3에 파일 업로드
try:
s3 = boto3.client('s3', #s3에 올릴거다
aws_access_key_id = Config.AWS_ACCESS_KEY_ID,
aws_secret_access_key = Config.AWS_SECRET_ACCESS_KEY) # 올릴려면 권한이 필요하다
# 그냥 액세스키를 넣어주면 짜면 회사에서 짤린다! 보안때문에!
s3.upload_fileobj(file,
Config.S3_BUCKET,
new_filename,
ExtraArgs = {'ACL':'public-read', 'ContentType':'image/jpeg'}) # 퍼블릭으로해야 웹페이지에서도 볼 수 있다? / 우리는 사진을 jpeg 타입으로 할거에요
except Exception as e:
print(str(e))
return{'result':'fail','error':str(e)},500
# 위에서 저장한 사진의 URL 주소를 DB에 저장해야 한다!
# URL 주소는 = 버킷명.S3주소/우리가 만든 파일명
file_url = Config.S3_BASE_URL+ new_filename
# 잘 되었으면, 클라이언트에 데이터를 응답한다
return {'result':'success','file_url':file_url}
※여기서 주의! ※
try:
s3 = boto3.client('s3',
aws_access_key_id = Config.AWS_ACCESS_KEY_ID,
aws_secret_access_key = Config.AWS_SECRET_ACCESS_KEY)
이 부분에서 access_key, secret_access_key를 그대로 넣어주면 나중에 배포할 때 외부에 알려지기 때문에 보안을 위해 config.py 파일을 만들어 따로 관리해줘야한다!
7. 아무사람이나 올릴 수 없게 권한과 사진저장을 위해 폴더가 있어야한다 그래서 우리는 AWS의 S3를 이용한다
AWS에 S3 검색하면 확장가능한 스토리지라 나오는데 필요하면 AWS에서 알아서 공간을 늘려준다
S3에서 버킷 만들기 클릭(폴더 = 버킷) 버킷 이름은 똑같은게 있으면 안만들어진다
ACL 활성화됨 선택, 모든 퍼블릭 엑세스 차단 체크해제, ~알고 있습니다 체크 그리고 버킷 만들기 클릭
만들어진 버킷 클릭하면 그 안에 폴더 여러개 만들 수 있다 그리고 파일 업로드 할 수 있다
속성 클릭하면 Amazon 리소스 이름(ARN)나오는데 아마존에서 쓰는 리소스 이름이다/ 권한 클릭 객체를 퍼블릭으로 설정할 수 있음이 되어있어야 한다
권한에서 ACL(액세스 제어 목록) 옆에 편집 클릭 - 모든 사람은 읽기에 체크, '이러한 변경 사항이 객체와 버킷에 미치는 영향을 이해합니다.'부분 체크 후 변경 사항 저장 클릭
IAM에 만든 유저에 S3 관련 권한 설정해줘야하는데 우리는 이미 만들때 넣어놨다
8. vsc에 sls deploy입력하여 배포하기