카테고리 없음

[FastAPI] 파일 전송

왕초보코딩러 2024. 10. 21. 20:14
728x90

2024.09.24 - [분류 전체보기] - [FastAPI] 파이썬으로 서버 만들기

 

[FastAPI] 파이썬으로 서버 만들기

파이썬으로 서버를 만들기 위한 프레임 워크1. Flask2. Django 3. FastAPI 이 중 쉽고 빠른 FastAPI로 서버를 만들어 보겠습니다.FastAPI 장점: 비동기 지원동기: 클라이언트 요청이 오면 하나를 처리하고

dogfoot1.tistory.com

 

2024.09.25 - [분류 전체보기] - [FastAPI] 데이터 받기

 

[FastAPI] 데이터 받기

2024.09.24 - [분류 전체보기] - [FastAPI] 파이썬으로 서버 만들기 [FastAPI] 파이썬으로 서버 만들기파이썬으로 서버를 만들기 위한 프레임 워크1. Flask2. Django 3. FastAPI 이 중 쉽고 빠른 FastAPI로 서버를

dogfoot1.tistory.com

 


동기와 비동기

동기: 클라이언트 요청이 오면 다 처리 할 때까지 다른 일은 하지 않음(클라이언트 요청이 동시에 들어오면 비효율적)

비동기: 클라이언트 요청이 동시에 오면 동시에 실행

 

 

파일 전달 받기 위한 라이브러리

from fastapi import UploadFile

 

파일 전송을 위한 라이브러리

from fastapi.responses import FileResponse

 

 

 

전체 라이브러리 임포트

from fastapi import FastAPI, Form
import uvicorn

# 클라이언트로부터 파일을 처리하기 위한
from fastapi import UploadFile

# 클라이언트에게 파일을 보내기 위한
from fastapi.responses import FileResponse

 

app = Fastapi()

 

 

파일 받기

참고

https://kkminseok.github.io/posts/fastapi20/

 

FastAPI 공식문서 따라하기[20] - Request Files

https://fastapi.tiangolo.com/tutorial/request-files/ 공식문서 따라하는 글

kkminseok.github.io

 

파일 처리에는 POST, 비동기 방식을 써야 한다

@app.post('/upload')
async def upload(file: UploadFile):

Body의 Form fields name이 file이다

 

 

Postman에서 보내는 법

 

 

@app.post('/upload')
async def upload(file: UploadFile):
    return file.file

if __name__ == "__main__":
    uvicorn.run(app, host='0.0.0.0', port=9100)

 

 

결과

이렇게 나온다

 

file.size

file.filename 등이 있다

https://fastapi.tiangolo.com/reference/uploadfile/#fastapi.UploadFile.headers

 

UploadFile class - FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production

fastapi.tiangolo.com

 

여러 파일 받기

@app.post('/upload')
async def upload(files: list[UploadFile]):
    return {"files": [f.filename for f in files]}
    

if __name__ == "__main__":
    uvicorn.run(app, host='0.0.0.0', port=9100)

 

결과

 

 

 

파일 읽기

file.read()를 할 때 async를 사용한다면 await를 사용해야 한다

@app.post('/upload')
async def upload(file: UploadFile):
    contents = await file.read()
    print(contents)
    return {"result": "200 OK"}
    

if __name__ == "__main__":
    uvicorn.run(app, host='0.0.0.0', port=9100)

 

print 결과

await file.read()를 하면 바이너리로 표현되는 것을 볼 수 있다.

 

 

 

 

파일 저장하기

@app.post('/upload')
async def upload(file: UploadFile):
    contents = await file.read()
    with open('./'+file.filename, 'wb') as f:
        f.write(contents)
    return {"result": "200 OK"}
    

if __name__ == "__main__":
    uvicorn.run(app, host='0.0.0.0', port=9100)

with open을 이용한다

 

+ 새로운 이름으로 저장하기

import uuid
@app.post('/upload')
async def upload(file: UploadFile):
    contents = await file.read()
    filepath =f'./{str(uuid.uuid4())}.jpg'
    with open(filepath, 'wb') as f:
        f.write(contents)
    return {"result": filepath}
    
if __name__ == "__main__":
    uvicorn.run(app, host='0.0.0.0', port=9100)

str(uuid.uuid4())를 사용한다

 

결과

 

 

 

파일 주기

https://fastapi.tiangolo.com/advanced/custom-response/?h=filere#default-response-class

 

Custom Response - HTML, Stream, File, others - FastAPI

FastAPI framework, high performance, easy to learn, fast to code, ready for production

fastapi.tiangolo.com

 

아까 result로 받은 87ce581d-591f-46df-801a-f5dbbf2c29c2.jpg를 클라이언트에 전송해보겠다

@app.post('/download')
async def download(filepath:str=Form()):
    path = f'./{filepath}'
    return FileResponse(path, 200)
    
if __name__ == "__main__":
    uvicorn.run(app, host='0.0.0.0', port=9100)

 

 

결과

 

클라이언트가 아까 받은 filename을 넣으면 이미지가 나온다