Error loading ASGI app. Import string "app" must be in format ":"
main에서 uvicorn.run("app”) 이 아닌, uvicorn.run("main:app”) 형태로 해야 함
fastapi.exceptions.FastAPIError: Invalid args for response field!
async def return_prediction(request: Request,
input_text: str = Form(...),
model: T5ForConditionalGeneration = get_model(),
tokenizer: T5TokenizerFast = get_tokenizer()
):
async def return_prediction(request: Request,
input_text: str = Form(...),
model: T5ForConditionalGeneration = Depends(get_model),
tokenizer: T5TokenizerFast = Depends(get_tokenizer),
):
왜 Depends로 의존성을 주입하니 해결이 되는가?
↓↓↓↓↓↓↓↓↓↓
Depends
의존성 주입이란?
dependency가 걸린 함수는 데코레이터가 없는 path operation 이라고 생각
Class Dependency
Sub Dependency
def query_extractor(q: Optional[str] = None):
return q
def query_or_cookie_extractor(
q: str = Depends(query_extractor), last_query: Optional[str] = Cookie(None)
):
if not q:
return last_query
return q
@app.get("/items/")
async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
return {"q_or_cookie": query_or_default}
read_query() 함수는 query_or_cookie_extractor() 를 dependency로 가지며, query_or_cookie_extractor() 함수는 query_extractor() 함수를 dependency로 가짐Code
from typing import Optional
from fastapi import Depends, FastAPI
app = FastAPI()
async def common_parameters(q: Optional[str] = None, skip: int = 0, limit: int = 100):
return {"q": q, "skip": skip, "limit": limit}
@app.get("/items/")
async def read_items(commons: dict = Depends(common_parameters)):
return commons
@app.get("/users/")
async def read_users(commons: dict = Depends(common_parameters)):
return commons
class CommonQueryParams:
def __init__(self, q: Optional[str] = None, skip: int = 0, limit: int = 100):
self.q = q
self.skip = skip
self.limit = limit
@app.get("/items/")
async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
common_parameters() 함수를 다음과 같이 class로 변경해서 사용 가능commons: CommonQueryParams = Depends(CommonQueryParams)
commons = Depends(CommonQueryParams)
commons: CommonQueryParams = Depends()
Depends() 처럼 파라미터를 넘겨주지 않으면 commons의 명시된 type으로 인스턴스를 만들어 리턴form 형식으로 값을 받을 때, html에서 name과 fastAPI에서 변수명은 일치해야 함
<form method="post">
<textarea name="input_text" rows="20" cols="100"></textarea>
<input type="submit" value="요약">
</form>
@app.post('/')
def return_prediction(request: Request,
input_text: str = Form(...)
):
summary = predict(input_text)
return template.TemplateResponse('front.html', context={"request": request, "summary": summary})
textarea name을 input_text로 지정했으므로, 함수에서 변수도 input_text로 사용해야 함
현재는 요약문이 완성되면 다시 html을 뿌려주는 방식
BaseModel
왜 사용하는가?
데이터 모델링
유효성 검사
FastAPI (main.py)
from fastapi import FastAPI, Form, Request
from fastapi.templating import Jinja2Templates
import uvicorn
from pydantic import BaseModel
from model import get_model, get_tokenizer, predict
from transformers import T5TokenizerFast, T5ForConditionalGeneration
from fastapi.param_functions import Depends
app = FastAPI()
template = Jinja2Templates(directory='./')
class Text(BaseModel):
text: str
@app.get('/')
def get_html(request: Request):
return template.TemplateResponse('front.html', context={"request": request})
@app.post('/', response_model=Text)
async def return_prediction(request: Request,
input_text: str = Form(...),
model: T5ForConditionalGeneration = Depends(get_model),
tokenizer: T5TokenizerFast = Depends(get_tokenizer),
):
summary = predict(input_text, model, tokenizer)
return template.TemplateResponse('front.html', context={"request": request, "summary": summary})
if __name__ == "__main__":
uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)
Text BaseModel을 사용해 return
근데 return은 TemplateResponse인데 왜 response_model=Text 을 해도 에러가 안 나는가?
return Text(text=template.TemplateResponse('front.html',
context={"request": request, "summary": summary}))
return을 위와 같이 변경하니 type match가 안 된다며 error가 뜸

chatgpt 피셜
JSON 직렬화(serialization) 이란, JSON으로 변환 가능한 객체를 의미
HTML (front.html)
<!DOCTYPE html>
<html>
<head>
<title>텍스트 요약</title>
</head>
<body>
<h1>텍스트 요약</h1>
<form method="post">
<textarea name="input_text" rows="20" cols="100"></textarea>
<input type="submit" value="요약">
</form>
<br>
<textarea rows="20" cols="50">{{summary}}</textarea>
</body>
</html>