본문 바로가기

Gen AI/LLM - [Project] ChatGPT로 Application 만들기

[생성형AI Project #1] 3. 웹서비스 구축을 위한 라이브러리(Backend) : FastAPI

#1 Fast API 소개
- 굉장히 간결하게 학습을 수가 있고, 백엔드에서 RESTful API 만들 있는 프레임워크

  • API = Application Programming Interface 약어로, open AI사의 각종 API들을 사용했던 처럼 정확한 구조는 몰라도 사용 방법만 알면 사용할 있음
  • RESTful API : Representational State Transfer (REST) 아키텍처 스타일을 따르는 웹 API를 의미하며, REST는 웹 서비스 개발을 위한 아키텍처 스타일이고, 클라이언트와 서버 간의 통신을 용이하게 하며 확장성을 높이기 위해 고안되었음

공식 홈페이지

> 설치 : 아래 화면의 두 가지를 설치해줘야 한다.

 

 

 

 

#2 get 메소드 기본 예제 실습

- 공식 홈페이지에서의 '설치' 이후 부분부터 참고

fast api 실행 (터미널)

 

 

root 경로

 

실행하면 나오는 경로를(위 캡처본의 좌측부분) 브라우저에 입력하면 아래와 같이 접근이 된다.

 

 

root경로의 items의 item id를 주소에 입력하면 해당되는 페이지가 뜬다.

(fastapi에서 경로 해석)

    • 127.0.0.1 : 현재 컴퓨터/서버 (자기 자신)
    • 8000 : 포트 (자기자신을 노출시킬 어떤 숫자(포트)로 노출시킬 정할 있음)
      • , 프로그램은 자기 자신의 8000 포트로 접근을 하면 우리가 만든 main.py 서버에 접근할 수가 있는 것임

 

> 코드 상세풀이 ( 코드 중에서 아랫부분은 삭제)

 

 

  •  fastapi라는 클래스(설계도) (import fastapi) 인스턴스화 시킴 (app =)
  • @app.get("/") : 데코레이터
    • 데코레이터를 사용하면 함수의 외곽에 많은 기능을 감싸주게 한다는 의미
    • , read_root 수행하게되면 fastAPI 구현한 다른 코드들까지 같이 수행이 된게 된다.
    • get 메소드로 만약 접근을 root로(\) 한다면 hello world 리턴해라

 

(참고)

 

(참고2, python에서의 메소드 (from ChatGPT 4O))

 

 

 

(참고3, 데코레이터란? (from ChatGPT4O))

 

 

 

 

#3 get 메소드 방식 2가지 : path/query parameter 

 

item id = 0으로 접근을 하면 에러가 난다.

 

  • path parameter 있는 값을 기본적으로 string으로 인식한다.
    (위 캡처본의 에러코드에서 볼 수 있듯 문자('0')로 기본적으로 인식한다.)
  • 이에, item_id 숫자형으로 받아오고 싶기때문에 이에 대한 힌트를 줘야한다. (아래, fast api에서는 typing이라는 기능을 제공)

typing : typing자체는 파이썬 문법이며, 아래와 같이 item_id int라는 힌트를 준다. (실행에 영향은 안준다.)

 

 

- 즉, 위처럼 변수별로 type이 뭔지를 힌트를 주는 것 (일반적인 python에서는 실제적인 영향도는 없으나 FastAPI에서는 실제적인 도움을 준다.)

 

> path parameter 확장 (key 추가)

 

0/name

 

위와같이 변경했기에 서버가 알아서 변경이 되었음 (아래에서 확인하면서 코드 상세 설명)

- 코드를 변경할 때마다 fast API 알아서 프로그램을 변경해준다.

 

 

    • uvicorn : 서버 실행, main : 파일이름(.py 빼고 적어준다.), app : 인스턴스 이름(fast api 서버를 담당하는 이름이다라는 것을 의미), --reload : 변경사항이 파이썬 파일 안에 있을 때마다 자동으로 로드해서 다시 띄어줘라. -> 실행하면 코드 변경에 따라 편하게 결과 확인 가능

 

- 즉, path parameter 아래와 같이 순서에 맞춰 써줘야 한다.

 

 

 

> Query Parameter

  • path parameter 비해 제약이 덜하다.
  • 실습을 위에 위의 path parameter 함수명들 수정

 

  • 37 : items.items()에서 items() 딕셔너리 순회를 위한 것이고, 위의 items 변수와는 아무 관련이 없음
  • 37 : items 변수에서 0 item_id, item  {name : bread}..

 

item-by-name?name=bread

 

query parameter에서는 ? 사용함

 

 

  • 에러 원인 : 위의 path_patameter 함수들과 혼동이 있음
    (read_item, read_item_and_key)

 

위와 같은 혼동을 피하기 위해 path_parameter 수정 (24,29 line 수정)

 

 

#4 Post 메소드

 

 

> post

  • post 다소 특이한 처리가 필요하다.

 

 

        • pydantic 통해서 외부로부터 받아올 있는 데이터에 대한 정의가 필요함
          (즉, 위 예시에서 item이 어떤식으로 외부로부터 오는지)
        • pydantic : 어떠한 타입을 지정하는 것을 도와주고, 데이터 주고받을 규약을 정해주는 라이브러리
        • 49 line : 외부로부터 post 메서드를 통해서 서버에 요청이 오게 된다면 item 형식에 맞는 입력이 있을 item 입력대로 파싱을 해서 정보를 우리가 갖고오게 된다.
        • get/post/put/delete 메서드
          :
          /서버 사이에서 http 통신을 통해서 정보를 서로 전달한다.
          • 메서드별로 정보를 전달하는 방식이 조금 다른 부분이 있음예시
            1. get 메서드 : 어떠한 정보를 url 정보에만 담아서 서로 전달 -> 정보가 많이 노출
            2. post 메서드는 바디라는 영역에서 item 같은 정보를 따로 갖고올 있음
              • , post 44~46 같이 받고자하는 정보에 대한 형태를 먼저 정의해서 item 타입으로 지정 (49 라인 오른쪽)

 

○ item을 받으면 딕셔너리로 바꿔준다.
§ 딕셔너리로 변환을 해주면 16번 ~21번 라인처럼 사용
§ 딕셔너리로 변환을 안해준다면  -> 위의  44번 라인 class를 그대로 사용
○ post는 get처럼 url로 변경하여 사용하는 것이 불가능하다.
§ 사용방법이 여러가지가 있지만, 우리가 사용할 수 있는 가장 간단한 방법은 FastAPI에서 제공하는 
스웨거라는 기능을 사용

 

> POST 요청 방식 중 가장 쉬운 방식: FAST API가 제공해주는 스웨거

 

- 예시 : items 딕셔너리에 cake 정보 추가

 

 

  • 스웨거 : 백엔드 개발자가 API 만들면 프론트엔드 개발자가 이를 활용해서 웹개발을 한다. 

 

- 위처럼 터미널/URL로도 확인 가능

 

 

- json : 딕셔너리와 거의 같지만, 쌍따옴표만 사용 가능하다는 점, key로 문자만 사용 가능하다는 점이 다름

 

#5 Put 메소드

 

 

- 위 코드의 문제 : Item을 위처럼 받아오게 되면 밑에서 name이나 price가 없으면 에러가 뜨게됨

 

라이브러리 추가 import (typing / optional)

 

0의 가격을 800으로 변경

 

Success : Ok 된 것 확인
0번의 가격이 800으로 변경되었는지 확인 1

 

0번의 가격이 800으로 변경되었는지 확인 2

 

#6 Delete 메소드

 

 

  • @app.delete("/items/{item_id}"): 이 부분은 데코레이터로, /items/{item_id} 경로에 DELETE 요청이 들어왔을 때 delete_item 함수를 실행하겠다는 뜻입니다.
    • @app.delete("/items/{item_id}"): /items/{item_id} 경로로 DELETE 요청이 들어오면 delete_item 함수를 호출하도록 지정합니다.
    • delete_item(item_id: int): items 리스트 또는 딕셔너리에서 item_id에 해당하는 항목을 제거하고 성공 메시지를 반환합니다.
    • 이 데코레이터를 사용하지 않고 경로와 함수를 매핑하려면, 요청을 수동으로 처리하고 경로와 메서드를 검사해야 하는 복잡한 코드가 필요할 것입니다. 데코레이터를 사용하면 이러한 작업을 쉽게 처리할 수 있습니다.
    • 따라서, 데코레이터를 사용하면 코드가 더 명확하고 유지보수가 쉬워지며, 웹 프레임워크의 다양한 기능을 간단하게 활용할 수 있습니다.
  • delete_item(item_id: int): 이 함수는 item_id라는 정수형 인자를 받습니다.
  • items.pop(item_id): 이 부분이 핵심인데, pop 함수는 items라는 목록(또는 딕셔너리)에서 item_id에 해당하는 항목을 제거합니다. pop 함수는 제거된 항목을 반환하기도 하지만, 여기서는 반환된 값을 사용하지 않고 단순히 제거만 하고 있습니다.
    • pop 함수는 일반적으로 리스트나 딕셔너리에서 특정 요소를 제거하고, 그 제거된 요소를 반환하는 함수입니다.
  • return {"success": "ok"}: 마지막으로, 삭제가 성공했다는 의미로 JSON 형식의 응답을 반환합니다.

0번 item 제거
제대로 제거된 것 확인 가능

 

정말 없어졌나 get을 통해 재확인

 

internal server error

 

internal server error

 

 

- 즉, 0번 아이템 삭제 메소드가 정상적으로 작동한 것 확인 가능

 

#7 첨언

 

 

- 실무에서는 위처럼 데이터가 dictionary 형식으로 되어있는 게 아니고, DB에 저장되어있어 이를 불러오는 등의 처리를 해줘야 함