📝이미지와 텍스트 포스팅하면 태그 가져오는 API만들기
순서
1. 클라이언트가 보낸 데이터 받아오기
2. 사진을 S3에 저장한다
- AWS콘솔로 가서 IAM 유저 만들고 S3로 가서 이 프로젝트의 버킷을 만들고 config.py에 입력해준다
- 날짜와 유저 아이디를 이용해 파일명을 유니크하게 만든다
- S3에 파일 업로드 한다(boto3 라이브러리 사용한다 설치 안되어있으면 pip install boto3로 설치)
3. S3에 저장된 사진을 Object Detectin(AWS Rekognition 이용)
- for루프로 Labels 안에 있는 Name만 가져온다
4. 위에서 가져온 imgURL과 태그로 저장할 Labels 이름을 DB에 저장한다(tag_name 과 tag 테이블에 인서트)
- tag_list가 tag_name 테이블에 있는지 확인해서 있으면 그 tag_name의 아이디를 가져오고 없으면 tag_name에 넣어준다
- tag테이블에 posting_id와 tag_id를 입력해 저장해준다
5. 결과를 클라이언트에 보내준다
※ 테이블 설계는 아래 사진처럼 했다
class PostingResource(Resource) :
# 포스팅 작성 API
@jwt_required()
def post(slef) :
userId = get_jwt_identity()
# from=data
# photo : file
# content : text
# 둘중 하나라도 없으면 안됨 세이프 코딩
if 'photo' not in request.files or 'content' not in request.form :
return {'error' : '데이터를 정확히 보내세요'}, 400
file = request.files['photo']
content = request.form['content']
# 이미지 데이터만 받게 세이프 코딩
if 'image' not in file.content_type :
return {'error' : '이미지 파일이 아닙니다.'}
# 사진명을 유니크하게 변경해서 S3에 업로드
# aws 콘솔로 가서 IAM 유저만들고 S3 버킷을 만들어서 config.py에 입력
# 파일명 유니크하게 변경
current_time = datetime.now()
new_file_name = str(userId) + current_time.isoformat().replace(':', '_') + '.' + file.content_type.split('/')[-1]
file.filename = new_file_name
# 파일 S3에 업로드 (boto3사용)
client = boto3.client('s3', aws_access_key_id= Config.ACCESS_KEY, aws_secret_access_key= Config.SECRET_ACCESS)
try :
client.upload_fileobj(file, Config.S3_BUCKET, new_file_name, ExtraArgs= {'ACL' : 'public-read', 'ContentType' : file.content_type})
except Exception as e :
return {"error" : str(e)}, 500
# 저장된 사진의 imgUrl
imgUrl = Config.S3_LOCATION + new_file_name
# S3저장된 사진을 Amazon Rekognition 사용하여 Object Detection
client = boto3.client('rekognition', 'ap-northeast-2', aws_access_key_id= Config.ACCESS_KEY, aws_secret_access_key= Config.SECRET_ACCESS)
response = client.detect_labels(Image= {'S3Object' : {'Bucket' : Config.S3_BUCKET, 'Name' : new_file_name}}, MaxLabels= 5)
# 태그 저장
tag_list = []
for row in response['Labels'] :
tag_list.append(row['Name'])
# DB에 저장
try :
connection = get_connection()
# 포스팅 테이블 저장
query = '''insert into posting
(userId, imgUrl, content)
values (%s, %s, %s);'''
record = (userId, imgUrl, content)
cursor = connection.cursor()
cursor.execute(query, record)
# 저장한 포스팅 테이블 id 가져오기
postingId = cursor.lastrowid
# 태그네임 테이블 저장
# tag_list가 tag_name 테이블에 들어있는지 확인해서 있으면
# 그 tag_name의 아이디를 가져오고 없으면 tag_name에 넣어준다
for name in tag_list :
query = '''select *
from tag_name
where name = %s ;'''
record = (name, )
cursor = connection.cursor(dictionary= True)
cursor.execute(query, record)
result_list = cursor.fetchall()
if len(result_list) == 0 :
query = '''insert into tag_name
(name)
values (%s);'''
record = (name, )
cursor = connection.cursor()
cursor.execute(query, record)
tagId = cursor.lastrowid
else :
tagId = result_list[0]['id']
# tag 테이블에 postingId와 tagId를 저장한다
query = '''insert into tag
(postingId, tagId)
values
(%s, %s)'''
record = (postingId, tagId)
cursor = connection.cursor()
cursor.execute(query, record)
# 커밋은 쿼리문이 끝난 마지막에 해준다
connection.commit()
cursor.close()
connection.close()
except Error as e :
print(e)
cursor.close()
connection.close()
return {"error" : str(e)}, 500
return {"result" : "success"}, 200
'Restful API' 카테고리의 다른 글
[Restful API] CLOVA Summary를 이용한 리뷰 요약 API 만들기 (0) | 2023.04.03 |
---|---|
[Error] TypeError: post() got an unexpected keyword argument (0) | 2023.01.17 |
[Restful API] 서버 개발 총 정리 (0) | 2023.01.16 |
[Restful API] 네이버 Open API 사용해보기 (0) | 2023.01.13 |
[Restful API] 이미지와 텍스트 포스팅하는 API만들기 (1) | 2023.01.13 |
댓글