본문 바로가기
Python/FastAPI

FastAPI & Svelte - 프로젝트 기초 진행하기

by 깐테 2024. 1. 24.

Svelte, fastapi - 프로젝트 진행하기

1-07 안녕하세요 파이보

 

1-07 안녕하세요 파이보

* `[완성 소스]` : [https://github.com/pahkey/fastapi-book/tree/v1.07](https://github.com/pahkey/fastapi…

wikidocs.net

프로젝트의 모든 진행은 위키독스를 참조합니다.


 

웹 브라우저에 “안녕하세요 새로운 프로젝트입니다.” 문구를 출력하는 프로그램을 제작할 것이다.

단, 이 때 “안녕하세요 새로운 프로젝트입니다” 문구는 Svelte가 FastAPI 서버에 요청하여 돌려받은 값으로 출력할 수 있도록 처리한다.

 

Hello API 만들기

# proj/myapi/main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/hello")
def hello():
    return {" message": "안녕하세요 사용자님"}
  • FastAPI 클래스로 생성한 app 객체가 FastAPI의 핵심 객체. 모든 동작은 이 객체로부터 비롯된다.
  • @app.get 어노테이션은 /hello 라는 요청이 발생하면 해당 함수를 실행하여 결과를 리턴하라는 의미.
  • 해당 리턴값은 설정한 딕셔너리를 리턴할 것.

 

FastAPI를 구동할 서버를 위해 uvicorn 설치.

 

유비콘은 비동기 호출을 지원하는 파이썬용 웹 서버.

(myapi)C:\\proj\\myapi > pip install "uvicorn[standard]"

 

그 다음 FastAPI 서버 실행

(myapi)C:\\proj\\myapi > uvicorn main:app --reload
  • main.app 에서 main은 main.py 파일을 의미하고 app은 main.py의 app 객체를 의미한다.
  • --reload 옵션은 프로그램이 변경되면 서버 재시작 없이 그 내용을 변경하라는 의미.

 

Hello API 테스트하기

  1. 브라우저에 localhost:8000/docs 입력

  • docs는 FastAPI가 가지고 있는 테스트 가능한 API 문서.
  • 해당 화면은 React로 만들어졌다.
  • “Try it out” 버튼을 누른 후 execute 버튼을 누르면 Hello API의 동작을 테스트 할 수 있다.

 

  • hello 함수에서는 딕셔너리를 리턴했지만 FastAPI는 이를 자동으로 json 형태의 응답으로 리턴한다.
  • 만약 실행 가능한 문서 대신 읽기만 가능한 문서를 보고 싶다면 /docs 대신 /redoc을 사용한다.

 

Svelte 웹 페이지 만들기

App.svelte 파일을 다음과 같이 수정

// proj/myapi/frontend/src/App.svelte
<h1>hello</h1>

이후 브라우저 localhost:5173 호출 시 다음과 같이 중앙에 표시

첫 App.svelte를 실행하면 다음과 같이 표시된다

 

화면 좌상단이 아닌 중앙에 표시되는 이유는 app.css 파일에 작성된 스타일 때문.

app.css 파일의 내용도 모두 제거.

그러면 다음과 같이 화면 좌상단에 표시된다.

다음과 같이 좌상단에 표시된다.

 


FastAPI 서버와 통신하기

//proj/myapi/frontend/src/App.svelte
<script>
  let message;

  fetch("<http://127.0.0.1:8000/hello>").then((response) => {
    response.json().then((json) => {
      message = json.message;
    });
  });
</script>

<h1>{message}</h1>

Script 블록에 message 변수를 생성. FastAPI의 hello API를 호출하여 돌려받은 값을 message 변수에 담음.

담겨진 message 값을 {message}로 출력.

 

Svelte는 자바스크립트에 선언된 변수의 값을 HTML 태그에 중괄호 기호를 사용하여 표시할 수 있다.

 

CORS 정책에 의해 요청이 거부.

 

개발자 도구를 열어서 확인해 보면, CORS 정책에 의해 요청이 거부된 것을 확인할 수 있다.

즉, 프론트엔드에서 FastAPI 서버로 호출이 불가능한 상황을 의미한다.

 

해당 오류는 CORS 예외 URL을 등록하여 해결할 수 있다.

 

 

CORS란?

교차 출처 리소스 공유 (CORS) - HTTP | MDN

 

교차 출처 리소스 공유 (CORS) - HTTP | MDN

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라

developer.mozilla.org

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.

 

보안 상의 이유로, 브라우저는 스크립트에서 시작한 CORS HTTP 요청을 제한한다. 해당 API를 사용하는 웹 애플리케이션은 자신의 출처와 동일한 리소스만 불러올 수 있으며, 다른 출처의 리소스를 불러오려면 해당 API의 올바른 CORS 헤더를 포함한 응답을 반환해야 한다.

 

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F

 

🌐 악명 높은 CORS 개념 & 해결법 - 정리 끝판왕 👏

악명 높은 CORS 에러 메세지 웹 개발을 하다보면 반드시 마주치는 멍멍 같은 에러가 바로 CORS 이다. 웹 개발의 신입 신고식이라고 할 정도로, CORS는 누구나 한 번 정도는 겪게 된다고 해도 과언이

inpa.tistory.com

위 사이트에도 잘 정리되어 있다.

 

 

CORS 예외 등록

FastAPI의 main.py 파일을 다음과 같이 수정한다.

# proj/myapi/main.py
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost:5173", # 또는 "<http://127.0.0.1:5173>"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials = True,
    allow_methods = ["*"],
    allow_headers = ["*"],
)

@app.get("/hello")
def hello():
    return {"message": "안녕하세요 사용자님"}

 

결과

결과 사진.

main.py 파일을 수정하고 나면 위와 같이 정상적인 결과를 출력할 수 있다.

 

 

fetch 함수의 또 다른 사용법(비동기)

 

Svelte에서 fetch 함수는 다음과 같이 사용할 수 있다.

//proj/myapi/prontend/src/App.svelte
<script>
  async function hello() {
    const res = await fetch("<http://127.0.0.1:8000/hello>");
    const json = await res.json();

    if (res.ok) {
      return json.message;
    } else {
      alert("error");
    }
  }

  let promise = hello();
</script>

{#await promise}
  <p>...waiting</p>
{:then message}
  <h1>{message}</h1>
{/await}
  • fetch 함수는 비동기 함수.

npm 서버 실행 명령어: npm run dev (proj/myapi/frontend)

uvicorn Svelte 실행 명령어: uvicorn main:app --reload (proj/myapi)

 

반응형