FastAPI + AWS S3

형석이의 성장일기·2023년 10월 9일
0
post-thumbnail

이번엔 FastAPI에서 만들어낸 오디오 파일을 S3에 저장하고 그 저장한 파일의 URL을 Spring Boot로 리턴하는 코드를 만들어야 한다.

전에 Spring boot와 S3에서 사용했던 S3 그대로 사용하자

프로젝트 구조

main.py

# -*- coding: utf-8 -*-
import os

from aiohttp import ClientError
from fastapi import FastAPI, File, UploadFile
from pathlib import Path

# ipynb 실행용
import nbformat
from nbconvert import PythonExporter
from nbconvert.preprocessors import ExecutePreprocessor

from typing import List

import boto3

import dotenv

dotenv.load_dotenv()

app = FastAPI()

# S3 연결 준비
client_s3 = boto3.client(
    's3',
    aws_access_key_id=os.getenv("CREDENTIALS_ACCESS_KEY"),
    aws_secret_access_key=os.getenv("CREDENTIALS_SECRET_KEY")
)

class ImageURLRequest(BaseModel):
    # meditationIdx: int
    images: List[str]

@app.post("/ai/text")
def ipynb(imageRequest: ImageURLRequest):
    audioUrl = []
    fileName = []

    # IPython 노트북 파일 경로 설정
    ipynb_file_path = "ipynb/image_chatgpt.ipynb"

    # IPython 노트북 파일을 읽기
    with open(ipynb_file_path, 'r', encoding='utf-8') as nb_file:
        notebook = nbformat.read(nb_file, as_version=4)

    print(imageRequest.images)

    # 매개변수 전달
    for image in imageRequest.images:
        for cell in notebook.cells:
            if cell.cell_type == 'code':
                cell.source = cell.source.replace("{{ imageUrl }}", image)

        # Python 코드로 변환
        python_exporter = PythonExporter()
        python_code, _ = python_exporter.from_notebook_node(notebook)

        # Python 코드 실행 및 결과 추출
        exec_preprocessor = ExecutePreprocessor(timeout=600)
        exec_preprocessor.preprocess(notebook, {'metadata': {'path': './'}})

        # 실행 결과 가져오기
        cell_outputs = notebook.cells[-1].outputs

        # 결과를 문자열로 가져옴
        result = ""
        for output in cell_outputs:
            if 'text' in output:
                result += output['text']
            elif 'data' in output and 'text/plain' in output['data']:
                result += output['data']['text/plain']

        # 명상용 텍스트 -> 음성 (미완성부분)

        file_path = "./audio/" + "파일명"

        # 파일 저장 (UploadFile -> 실제 저장할 파일). 로컬에 저장되어 있어야 S3에 저장할 수 있겠죠?
		# 그러기 위해선 로컬에 저장된 파일의 위치와 이름만 알면 됨!
         with file_path.open("wb") as f:
             f.write(UploadFile.file.read())

		# S3에 저장할 파일명을 담고있는 리스트
        fileName.append("파일명")

		# Spring boot로 리턴
    return {"audios": saveAudioAtS3(fileName)}

# Audio 파일을 S3에 저장하는 코드
def saveAudioAtS3(audio):
    audioUrl = []

    try:
        for a in audio:
			# 지정한 S3 버킷에 audio 파일 저장
            client_s3.upload_file(
                "./audio/"+a,
                os.getenv("S3_BUCKET"),
                "audio/" + a,
                ExtraArgs={'ContentType': 'audio/mp3'}
            )

            # 로컬에 저장되어있는 음성파일 삭제
            os.remove("./audio/" + a)
						
			# S3에 저장한 음성파일의 URL
            audioUrl.append(os.getenv("S3_URL") + "/" + a)

        return audioUrl
    except ClientError as e:
        print(f'Credential error => {e}')
    except Exception as e:
        print(f"Another error => {e}")

전체적인 흐름은 로컬에 저장하고 싶은 파일을 저장한 뒤, 저장한 파일의 경로와 파일명을 가지고 S3 버킷에 저장하는 흐름!

.env

CLARIFAI_API_KEY=
CHATGPT_API_KEY=

# S3 관련 정보
S3_BUCKET=
S3_URL=
CREDENTIALS_ACCESS_KEY=
CREDENTIALS_SECRET_KEY=

requirements.txt

fastapi
jupyter
uvicorn
openai
clarifai
nbformat
nbclient
nbconvert
python-dotenv
boto3
pydantic
ipython

프로젝트에 필요한 라이브러리!

profile
이사중 .. -> https://gudtjr2949.tistory.com/

0개의 댓글