1) style.css 파일 적용
from fastapi.staticfiles import StaticFiles
from fastapi import FastAPI
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
- FastAPI가 초기화된 위치를 기준으로 /static 폴더의 경로를 설정한다.
- html 코드 내에서 아래와 같이 호출이 가능하다.
- <link href="{{ url_for('static', path='/css/style.css') }}" rel="stylesheet" type="text/css" id="cssLink"/>
2) Jinja2Template 예제
from pathlib import Path
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
from fastapi import APIRouter, Request
import json
BASE_DIR = Path(__file__).resolve().parent.parent.parent
templates = Jinja2Templates(directory=BASE_DIR / "templates")
router = APIRouter()
@router.get(
"/url",
response_class=HTMLResponse,
)
async def jinja2_template_example(request: Request):
form_data = await request.form()
return templates.TemplateResponse('./index.html', {
"request": request,
"json_data": json.dumps(form_data._dict, ensure_ascii=False),
})
- index.html은 해당 파일 기준으로 BASE_DIR / templates 폴더 안에 존재한다.
- “request”: request는 필수이며, html에 넘겨줄 데이터를 key-value 구조로 넘긴다.
- html 태그 안에서 "{{ key }}" 로 클라이언트가 넘겨준 데이터를 확인할 수 있다.
- json_data를 넘기면, <script> 안에서 데이터 처리를 해줘야 한다. (개인적으로 비선호)
// script 태그 안에서 데이터 처리 var tempParams = document.getElementById('json_data').innerHTML; tempParams = JSON.parse(tempParams); /* 콤마, &, ;, \n, \, |, ', ", < 특수 문자는 포함되면 안됨. */ for (var key in tempParams) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", tempParams[key].replace("&", "&")); document.form_auth.appendChild(hiddenField); } ... // body에 이렇게 태그를 선언해둬야 한다. <body oncontextmenu="return false;" ondragstart="return false;" onselectstart="return false;"> <form name="form_auth" method="post"> <div id="sbParam" style="display: none;">{{ sbParam }}</div> </form> </body>
- form_data에서 데이터를 하나 하나 꺼내서 넘기는 것을 개인적으로는 선호한다.
- 아래 예제를 예시로 들면, "tid": form_data['tid]
- 외부 결제 연동 시, 예제 템플릿
<!DOCTYPE html> <html> <head> <title>Jinja2</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script language="javascript"> // Function to submit form window.onload=function() { function submit() { var sendfrm = document.getElementById("SendForm_id"); sendfrm.action = return_url; sendfrm.submit(); } let return_url = "{{ returnUrl }}"; // 내부 API 또는 Front url submit(); } </script> </head> <body> <form id="SendForm_id" name="SendForm" method="POST"> <input type="hidden" class="input" style="width: 100%; color: gray;" name="mid" value="{{ mid }}" readOnly><br /> <input type="hidden" class="input" style="width: 100%;" name="payUserKey" value="{{ payUserKey }}" readOnly><br /> <input type="hidden" class="input" style="width: 100%;" name="tid" value="{{ tid }}" readOnly><br /> </form> </body> </html>
- returnUrl을 통해 내부적인 로직을 더 타거나 마지막에 프론트 화면으로 리다이렉트시킨다.
3) 스크립트 리턴
from fastapi.responses import HTMLResponse
from jinja2 import Template
def invalid_error(resultMsg: str = ""):
return_url = f"{RETURN_HOST}/order" # 프론트 주소
template_str = """
<script>
function result_error() {
alert('{{ resultMsg }}');
window.opener.postMessage('paymentError', '{{ return_url }}');
window.close();
}
result_error();
</script>
"""
template = Template(template_str)
rendered_template = template.render(resultMsg=resultMsg, return_url=return_url)
return rendered_template
@router.post(
"/url",
response_class=HTMLResponse,
)
def example(request: Request):
return invalid_error()
- 에러가 발생한 경우, html script 코드를 리턴해서 에러 처리를 할 수 있다.
'FastAPI tips' 카테고리의 다른 글
엑셀 다운로드 (Pandas, Workbook) (0) | 2024.05.08 |
---|---|
Middleware 커스텀해서 사용하기 (0) | 2024.05.03 |