Fastapi

[FastAPI] HTML 사용해 보기 (3)

Suda_777 2024. 8. 22. 00:12
반응형

1. 개요

먼저 FastAPI에서 HTML을 사용한다는 것은,
HTML에서 보여주는 내용을 동적으로 보여준다는 것이다.

즉, FastAPI에서 Return한 변수를
HTML에서 보여주겠다는 것이다.


2. 설치

먼저 jinja2를 설치해 주자

# pip 설치 방법
pip install jinja2

# poetry 설치 방법
poetry add jinja2

 

 


3. 기본적인 HTML 다루는 방법

만약 프론트엔드 서버와 FastAPI가 통신한다면, 클라이언(유저)가 프론트엔드에 Request를 날리면 프론트엔드 서버에서 Json 등의 데이터를 FastAPI에 요청하는 형식으로 진행되겠지만, HTML만 이용할 때에는 클라이언트가 FastAPI에게 request를 요청하면 HTML을 반환하는 형식으로 코드를 작성하게 된다.

'FastAPI'는 Jinja2Templates 클래스를 사용하여 HTML 파일을 넣어둘 디렉토리를 설정한다.
아래 예시 코드에서는 'templates'디렉토리에 HTML 파일을 넣어둔 것으로 설정했다.

from fastapi import FastAPI, Request
from fastapi.templating import Jinja2Templates

app = FastAPI()
templates = Jinja2Templates(directory="templates")

다음으로 get 형식으로 요청을 받아 HTML을 반환하는 코드를 만들어 보겠다.

@app.get("/items/{id}", response_class=HTMLResponse)
async def read_item(request: Request, id: int):
    return templates.TemplateResponse("item.html", {"request": request, "id": id})

코드 설명

  1. get 데코레이션의 파라미터로 response_class=HTMLResponse를 추가해 준다. get의 response를 HTML로 하겠다는 것이다.
  2. request: Request를 함수의 파라미터로 받고 있는데, 이는 get을 요청할 때의 url에 넣는 변수가 아니다. FastAPI에서는 특정 매개변수 이름이 Request, Depends 또는 그 외의 몇 가지 특별한 타입인 경우, 이를 의존성 주입을 통해 처리하고, 이러한 매개변수들은 경로 파라미터나 쿼리 파라미터로 취급되지 않는다. fastapi.Request 타입의 매개변수는 현재 HTTP 요청 객체로, 모든 요청 정보를 포함합니다. 이 값은 templates.TemplateResponse()함수에 인풋으로 넣기 위해 필요하다.
  3. templates.TemplateResponse()는 HTTP 응답으로 반환하는 데 사용되는 메서드이다. html파일, 데이터를 동시에 넘겨준다.

4. HTML에서 FastAPI의 변수 받아서 사용하기

자 위 예시코드에서는 'id'라는 key값과 데이터를 html로 넘겨주었다.
이를 HTML화면으로 띄워주는 방법은 아래와 같다.

{{}} 중괄호를 2중으로 사용하고, 그 안에 key값을 넣어준다.
아래 예시코드를 보자

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Item {{ id }}</title>
</head>
<body>
    <h1>아이템의 id값 입니다: {{ id }}</h1>
    <p>This is the details page for item with ID {{ id }}.</p>
</body>
</html>

 

실행 결과

- url에서 파라미터를 1로 주면 html 본문에서도 id값이 1로 출력되는 것을 볼 수 있다.

 


5. HTML에서 FastAPI로 데이터 전달하기

multipart/form-data 형식의 폼 데이터를 처리하기 위한 패키지를 설치하자

# pip 이용
pip install python-multipart

# poetry 이용
poetry add python-multipart

 

HTML에서 FastAPI로 데이터를 전송할 때에는

post 방식을 이용한다.

즉, 서버로 값을 전달하고 데이터베이스이 이 값을 저장한다는 것이다.

아직 FastAPI에서 데이터베이스에 접근하는 방법은 공부하지 않았으니

데이터베이스에 접근하기 이전까지만 공부해 보도록 하자.

 

먼저 html에서는 <form> 태그를 사용한다.

그리고 action, method 속성을 설정해준다.

  • action: 폼 데이터가 전송될 URL 경로를 지정
  • method: 폼 데이터 전송 방식을 지정합니다. 일반적으로 GET 또는 POST 방식이 사용
<!-- templates/form.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Submit Data</title>
</head>
<body>
    <form action="/submit" method="post">
        <label for="username">Username:</label>
        <input type="text" id="username" name="username" required>
        
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" required>
        
        <button type="submit">Submit</button>
    </form>
</body>
</html>

 

먼저, 위 html을 띄워줄 코드를 작성한다. @app.get() 으로 만들어준다.

위 HTML 코드에서 데이터가 전송될 경로를 "/submit"으로 만들었기 때문에 FastAPI에서 해당 경로로 데이터를 받아 처리하면 된다.

 

다음으로 @app.post("/submit") 코드를 이용해 데이터를 받아서 처리하면 된다. 끝!

참고로 html에서 <input>태그에서 name 속성이 서버로 전달되는 데이터의 키(key) 역할을 한다.

키값에 맞게, 함수의 파라미터를 만들어 주면 된다.

여기서는 "username", "email"이다. 그리고  두 값에 각각 Form(...) 값을 디폴트값으로 넣어준다.

 

Form이란...? FastAPI에서 HTML 폼을 통해 데이터를 전송할 때는 Form 클래스를 사용하여 데이터를 쉽게 받을 수 있다.

이 클래스는 pydantic과 비슷하게 동작하며, 폼 필드 데이터를 경로 함수의 매개변수로 쉽게 매핑할 수 있습니다.

Form(...)에서 ...는 이 필드가 필수임을 나타내는 Python의 Ellipsis 객체입니다. 이는 기본값 없이 필수로 입력받아야 하는 값을 정의할 때 사용됩니다.

 

username: str = Form(...)는 HTML 폼의 name="username" 필드에서 전송된 데이터를 받아서 username 변수에 할당합니다.

 

from fastapi import FastAPI, Form, Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse

app = FastAPI()

# templates 디렉터리를 지정하여 Jinja2Templates 객체 생성
templates = Jinja2Templates(directory="templates")

@app.get("/form", response_class=HTMLResponse)
async def form_get(request: Request):
    return templates.TemplateResponse("form.html", {"request": request})

@app.post("/submit")
async def submit_form(username: str = Form(...), email: str = Form(...)):
    return {"username": username, "email": email}

 

위 코드에서는 json 형식으로 값을 리턴해주고 끝나고 있다. (데이터베이스에 값 저장하지 않음)

반응형