API 서버

사진 올리는 API

클로버냥 2023. 6. 26. 12:42

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로 한다

포스트맨에서 사진은 form-data에서 file이다

저장한 사진을 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입력하여 배포하기