본문 바로가기



AiDAOps개발/개발 준비

FastAPI를 기반으로 데이터 파일 전송 및 읽기

이번 글에서는 FastAPI를 기반으로 데이터 파일 읽기를 해 보겠습니다.
머신러닝이든 데이터 분석이든 가장 처음 처리해야 할 내용은 바로 데이터를 읽고 처리하는 과정이죠.
그래서 데이터 파일을 읽는 것을 가장 먼저 해 보기로 했습니다.

 

데이터 파일을 서버로 전송하고 읽어들이기 위해서는 해당 API를 호출하도록 만들어진 웹 페이지 또는 애플리케이션이 필요합니다만..
일단 이번에는 그 과정은 제외하고 FastAPI에서 제공되는 REST API 문서를 이용하도록 하겠습니다.
그리고 이번에 구현하는 코드는 다중파일이 아닌 단일 파일만을 처리하도록 하겠습니다.

 

아래에서 다루는 내용은 FastAPI 공식 튜토리얼을 참고하였습니다.

 

먼저 파일을 전송하는 기능을 구현합니다.
FastAPI에서는 File 클래스를 이용하여 클라이언트에서 업로드할 파일을 정의할 수 있습니다.
그리고 업로드된 파일은 Form 데이터의 형태로 저장되기 때문에 업로드된 파일을 사용하기 위해서는 python-multipart 라이브러리를 사용해야 합니다.
우리는 FastAPI를 설치할 때 [All] 모드로 설치했기 때문에 이미 설치가 되어 있습니다.
만약 설치되지 않은 경우에는 다음과 같이 설치해줍니다.

pip install python-multipart

 

설치가 끝나면 코드를 작성해 봅니다.

from fastapi import FastAPI, File, UploadFile
 
app = FastAPI()
 
@app.get("/")
async def root():
    return {"Message": "Hello World"}
 
@app.post("/files/")
async def create_file(file: bytes = File()):
    return {"file_size": len(file)}
 
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

 

코드를 보면 create_file이라는 함수와 create_upload_file이라는 함수를 정의했는데...
먼저 REST API 함수의 매개변수를 bytes 로 선언하는 경우 FastAPI는 파일을 읽고 bytes 형태의 내용을 전달하며, 이렇게 전달된 파일은 전체 내용이 메모리에 저장된다는 것을 의미합니다.
다시 말하면 큰 사이즈의 파일을 사용할 때에는 다소 문제가 있을 수 있다 것이죠.
그래서 이런 경우에는 UploadFile을 사용하는 것이 더 유리하다고 할 수 있습니다.
특히 데이터 분석이나 머신러닝에서 사용하는 데이터는 매우 큰 용량을 사용하기 때문에 UploadFile을 사용하는 것을 권장합니다.

 

코드의 작성이 완료되면 아래 그림과 같이 API 문서가 잘 만들어진 것을 확인할 수 있습니다.

 

정의한 API들이 잘 표시되고 있음

 

그럼 API 문서를 이용해서 파일 업로드를 실행시켜 보겠습니다.

 

"Files" API를 실행시켰을 때

 

"uploadfile" API를 실행시켰을 때

 

위와 같이 업로드한 파일의 메타데이터를 확인할 수 있습니다.
참고로 지난 글에서의 실행 이미지와 다르게 IP 주소가 "127.0.0.1" 이 아닌 "192.168.0.4"로 되어 있는데, 이 경우처럼 서버가 아닌 시스템에서의 브라우저를 통해 접속하려면 아래와 같이 "--host=0.0.0.0"을 지정하여 모든 IP에서의 접근을 허용해주면 됩니다.

uvicorn main:app --host=0.0.0.0 --reload

 

그럼 이제 실제로 파일을 저장해 보도록 하겠습니다.
아래와 같이 코드를 수정합니다.
UploadFile을 사용할 것이기 때문에 기존의 Files 함수는 삭제하였습니다.
그리고 파일의 경로 지정을 위하여 os 패키지를 임포트하도록 합니다.

import os
from fastapi import FastAPI, File, UploadFile
 
app = FastAPI()
 
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATAFILE_DIR = os.path.join(BASE_DIR,'datafiles/')
 
@app.get("/")
async def root():
    return {"Message": "Hello World"}
 
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    file_location = os.path.join(DATAFILE_DIR, file.filename)
 
    with open(file_location, "wb+") as file_object:
        file_object.write(file.file.read())
 
    return {"filename": file.filename}

 

코드의 작성이 끝나면 서버를 리로드한 후 API문서를 통해 다시 한 번 파일 업로드를 실행해 봅니다.

 

오류 없이 잘 처리되었음

 

파일이 잘 저장되었음

 

위의 이미지와 같이 파일이 잘 저장된 것을 확인할 수 있습니다.
다음으로 파일을 읽는 기능인데.. 이것은 간단합니다.
일단 파일이 잘 전송, 저장되었기 때문에 그냥 파일 읽기 기능을 사용하면 됩니다.
여기서는 Pandas를 사용하여 읽어보겠습니다.

 

Pandas가 설치되어 있지 않다면 설치하고 진행해야겠죠.

pip install pandas

pandas 설치

 

이제 코드를 다시 수정합니다.
별도의 API를 만들지 않고 일단 파일 업로드 API에 기능을 같이 집어넣었습니다.

import os
from fastapi import FastAPI, File, UploadFile
import pandas as pd
 
app = FastAPI()
 
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATAFILE_DIR = os.path.join(BASE_DIR,'datafiles/')
 
@app.get("/")
async def root():
    return {"Message": "Hello World"}
 
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    file_location = os.path.join(DATAFILE_DIR, file.filename)
 
    with open(file_location, "wb+") as file_object:
        file_object.write(file.file.read())
 
    df = pd.read_csv(filepath)
    print(df)
 
    return {"filename": file.filename}

파일 업로드 후 Pandas를 통해 읽은 내용이 서버에 표시되고 있음

 

이렇게 서버로 데이터 파일을 전송하고 저장한 후 읽어보는 것까지 확인을 해 보았습니다.
이번 글에서는 단순히 기능만을 구현하고 확인해 보았기 때문에 실제로 사용하기 위해서는 더 많은 작업이 요구됩니다.
읽어들인 데이터를 브라우저에 보기좋게 표현하는 기능이나... 업로드된 데이터를 관리하는 기능 등 많은 작업이 필요할 것입니다.
어차피 한꺼번에 할 수 없는 내용이므로 하나씩 차근차근 진행을 해 보겠습니다.

 

 

 

 

 

반응형