00 프로젝트 소개 및 환경 구축 - ToDo 서비스
1. ToDo (Version 1) 서비스 만들기
1) ToDo 서비스의 기능
- 할 일을 적고 수행 여부 체크
2) ToDo API
- 생성할 API 5가지: 1) 전체 ToDo 조회, 2) 단일 ToDo 조회, 3) ToDo 생성, 4) ToDo 수정, 5) ToDo 삭제
Method | 기능 | url |
GET | 전체 ToDo 조회 | /api/v1/todos |
단일 ToDo 조회 | /api/v1/todos/<id> | |
POST | ToDo 생성 | /api/v1/todos |
PATCH | ToDo 수정 | /api/v1/todos/<id> |
DELETE | ToDo 삭제 | /api/v1/todos/<id> |
2. 환경 구축
1) projects라는 폴더를 원하는 경로에 생성
mkdir <원하는 경로>/projects
2) 파이썬 가상환경 생성 후 해당 폴더로 이동
# todos라는 가상환경 폴더 생성
$ python3.10 -m venv todos # 강사님
$ python -m venv todos # 나
# todos로 이동
$ cd todos
# 목록 확인
$ ls
Include/ Lib/ pyvenv.cfg Scripts/
3) 가상환경 활성화/설정
$ source bin/activate # 강사님
$ source Scripts/activate # 나
# 잘 작동하는지 확인
(todos)$ python --version
Python 3.12.1
01 전체 ToDo 조회하기 (GET Method 사용)
- 목표: GET Method를 이용해 전체 ToDo 내용 조회하기
1. todos 폴더 > src 폴더 > main.py 파일 생성
- 여기서 src는 source의 약자
(todos)$ pwd # 현재 디렉토리 확인
/c/Users/관리자/Desktop/projects/todos
(todos)$ python --version # 잘 작동하는지 확인
Python 3.12.1
(todos)$ mkdir src # src 폴더 생성
(todos)$ cd src # src 폴더로 이동
(todos)$$ touch main.py # main.py라는 파이썬 빈 파일 생성
1) PyCharm 사용 시
- src 폴더 우클릭 > Mark Directory as > Source Root
- Python 파일들을 import하는 경로에서 이 src 디렉토리를 root path로 잡도록 설정하는 것
2. 필요한 library 설치: fastapi, uvicorn
(todos)$ pip install fastapi
(todos)$ pip install uvicorn
- uvicorn: fastapi를 동작시키기 위한 라이브러리
- 일반적으로 fastapi와 uvicorn 같이 사용됨
3. main.py에 쓰기
# todos > src > main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/") # @app.get에 root path를 매핑
def health_check_handler(): # health_check_handler라는 함수 생성
return {"ping": "pong"} # 핑퐁 반환
1) FastAPI import 및 app 객체에 FastAPI() instantiate
- from fastapi import FastAPI: fastapi 라이브러리에서 FastAPI import
- app = FastAPI(): app이라는 이름으로 FastAPI을 instantiate
- instantiate (v.): 생성된 오브젝트의 인스턴스를 반환하도록 함
2) root path에 GET 요청을 보내는 API 생성
- app이라는 객체에 API를 연결하여 서버를 띄우면 서버로 어떤 HTTP 요청 보내기 가능
- @app.get("/"): @app.get에 root path를 매핑
- def health_check_handler(): : health_check_handler라는 함수 생성
- return {"ping": "pong"}: 핑퐁 반환
- 작동 방식:
- @ 뒤에 있는 app (앞서 app=FastAPI() 선언하여 가능)이라는 FastAPI 서버에 root path로 개인 요청을 보내게 되면 아래에 있는 health_check_handler() 함수가 실행되어서 해당 API 요청을 처리할 것
- health_check_handler() API는 핑퐁을 반환해주는 기능을 지님
4. FastAPI 웹 서버 띄워서 기능 확인하기
(todos)$ cd /c/Users/관리자/Desktop/projects/todos/src
(todos)$ uvicorn main:app
INFO: Started server process [18956]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
- $ cd /c/Users/관리자/Desktop/projects/todos/src: 기능을 확인하기 위해 src 경로를 기준으로 작업을 진행할 것이기에 src로 이동
- $ uvicorn main:app: uvicorn 사용하여 main에 app을 매핑 즉, main.py에 있는 app 객체를 이용하겠다는 의미
- (후에 추가)
- uvicorn main:app --reload
- --reload 옵션을 주면 파일을 수정하고 저장하면 저절로 업데이트가 되서 uvicorn을 껐다 키지 않아도 됨. 그래서 앞으로는 --reload 옵션을 줄 것임!
- 위에까지만 써도 괜찮음
- 뒤에 port 추가 가능하나 우리는 기본 8000 port를 사용하도록 하겠음 (강사님 )
- 실행 시 로그 메시지 출력됨
- 로그 내용: local host(127.0.0.1)에 8000번 port로 앱이 뜸
- http://127.0.0.1:8000을 ctrl + 마우스 좌클릭 또는 브라우저에 입력 시 {"ping": "pong"}이 출력 되는 것 확인 가능
- http://127.0.0.1:8000/docs라는 path로 이동 시
- FastAPI가 자동으로 swagger 문서를 생성해 놓은 것 확인 가능
- Health Check Handler가 매핑돼있다는 정보 확인 가능
- (후에 추가)
5.FastAPI 웹 서버 종료하기
- 웹 서버 실행 후 코드 변경 시 변경사항을 SwaggerUI에 반영하기 위해선 웹 서버 재시작 (uvicorn 종료 후 다시 실행) 필수
- 종료 방법: Ctrl + C
6.전체 ToDo 조회하는 API 생성하기
1) 데이터를 담을 딕셔너리 생성
- 현재 데이터베이스와 연동되어있지 않기에 메모리상에서 딕셔너리 생성하여 거기서 데이터 관리하도록 할 것
- main.py에 아래를 추가
# todos > src > main.py
...
todo_data = {
1: {
"id": 1,
"contents": "실전! FastAPI 섹션 0 수강",
"is_done": True,
},
2: {
"id": 2,
"contents": "실전! FastAPI 섹션 1 수강",
"is_done": False,
},
3: {
"id": 3,
"contents": "실전! FastAPI 섹션 2 수강",
"is_done": False,
},
}
- todo_data라는 딕셔너리 생성
- key와 value를 갖게 될 것
- key → 개별 todo를 식별할 수 있는 식별자로 int 값 정해주기 (위에선 1, 2, 3)
- 각 key 당 딕셔너리의 value를 갖게 될 것
- value → 하나의 todo를 모델링 해주기
- "id"라는 컬럼에 앞에 key와 동일한 int 타입의 값 설정해주기
- "contents"라는 컬럼에 하나의 todo가 갖는 str 타입의 실제 내용 설정해주기
- "is_done"라는 컬럼에 todo의 완료 여부를 확인하는 bool 타입의 값 설정해주기
- key → 개별 todo를 식별할 수 있는 식별자로 int 값 정해주기 (위에선 1, 2, 3)
- 위 예시에선 3개의 item들을 갖는 ToDo 데이터 생성
2) API 요청에 데이터 반환하도록 설정
- main.py에 아래를 추가
# todos > src > main.py
...
@app.get("/todos") # @app.get("/path")
def get_todos_handler(): # def 핸들러명():
return list(todo_data.values()) # return 반환값
- ToDo API를 추가하기 위해선 앞에서 한 것과 같이 해야 됨
- @app.get("/todos"): app의 GET method에 path (i.e., "/todos") 매핑해주기
- 일반적으로 REST API에서는 자원(resource)를 복수형으로 적기에 ToDos라는 이름의 path를 지정할 것
- def get_todos_handler():: todos API를 핸들링하는 핸들러의 역할을 하는 함수 생성
- returb list(todo_data.values()): todo_data의 각 key의 value들의 값들을 추출해서 list에 담긴 것을 반환
7. 변경된 SwaggerUI 및 화면 확인
- 코드 변경 후 SwaggerUI에 변경사항 반영하기 위해선 uvicorn 종료 및 재시작 필수
- terminal에서 ctrl + C 입력하여 종료 후 아래를 입력
(todos)$ uvicorn main:app
INFO: Started server process [13812]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
1) API 확인
- http://127.0.0.1:8000을 ctrl + 마우스 좌클릭 또는 브라우저에 입력 시 {"ping": "pong"}이 출력 되는 것 확인
- http://127.0.0.1:8000/todos을 브라우저에 입력 시
2) Swagger 문서 확인
- http://127.0.0.1:8000/docs을 브라우저에 입력 시
- SwaggerUI 반영된 것 확인 가능
- ToDos API가 추가된 것 확인 가능
- 안보일 경우 새로고침 해보기
- /todos의 drop down 버튼 클릭 시
- 200번대의 response가 응답된다는 것을 API 문서에서 확인 가능
- 현재는 따로 설정한 값들이 없기에 단순한 형태로만 보임
3) ToDos API 호출
- Try it out 버튼 클릭 > Execute 클릭 시
- 위 사진 (사진 1) 설명: localhost 8000번에 todos라는 path로 get 요청이 감
- 위 사진 (사진 2)설명: 200번대의 response가 위와 같은식으로 응답 됨
- 작업한 api가 잘 동작됨을 확인 가능
8. query parameter
1) 필수 값으로 설정
- query parameter: get 요청 뒤 path의 가장 끝부분에 ? 형태로 작성 가능
- 예시: "/todos?order=DESC"에서 하이라이트 된 부분
- order 값을 통하여 조회수에 추가적인 어떤 정렬 (DESC - descending으로 내림차순 정렬)을 할 수 있음
- order=DESC 대신 query=apple 같은 것으로 apple이 들어간 item만 찾는 것 등을 할 수 있음
- FastAPI에서는 query parameter를 인자로 전달하여 이용함
# todos > src > main.py
...
@app.get("/todos")
def get_todos_handler(order: str):
rt = list(todo_data.values())
if order == "DESC":
return rt[::-1]
return rt
- order라는 str 값을 인자로 전달하여 query parameter로 이용하기
- order가 DESC라면 rt를 역정렬해서 반환
- 아닐 시 그냥 rt(todo_data의 value값들의 리스트 형태)를 오름차순으로 반환
2) API 확인
- uvicorn 재시작: ctrl + C 후 uvicorn main:app을 터미널에 입력
- 브라우저에 http://127.0.0.1:8000/todos?order=DESC 입력 시
- 변경된 api 잘 작동하는 것 (order=DESC라는 쿼리 파라미터를 todos path 뒤에 ? 후 적어줬을 때 역정렬된 todo_data 값들이 출력되는 것) 확인 가능
3) Swagger 문서 확인
- 브라우저에 http://127.0.0.1:8000/docs 입력 시
- 이 중,
- query parameter에 order가 추가된 것 확인 가능
- Try it out 클릭 > (order에 값 안 넣고) Execute 클릭 시
- 앞서 main.py에서 order을 필수값으로 넣었기에 에러가 남
- order 값에 ASC 값을 입력 후 Execute 클릭 시
- 정상적으로 오름차순 정렬이 되어 반환되는 것 확인 가능
- order 값에 DESC 값 입력 후 Execute 클릭 시
- 정상적으로 내림차순 정렬이 되어 반환되는 것 확인 가능
4) optional 값으로 설정
# todos > src > main.py
...
@app.get("/todos")
def get_todos_handler(order: str | None = None):
rt = list(todo_data.values())
if order and order == "DESC":
return rt[::-1]
return rt
- def get_todos_handler(order: str | None = None): order 값을 str 값 또는(or) None을 받을 수 있도록 하고, = None을 통하여 기본값 (default값)을 None이라고 설정
- if order and order == "DESC":: order 값이 있고 order 값이 DESC인 경우 다음을 실행
5) API 확인
- uvicorn 재시작: ctrl + C 후 uvicorn main:app을 터미널에 입력
6) Swagger 문서 확인
- 브라우저에 http://127.0.0.1:8000/docs 입력 후 /todos path에서
- Try it out 클릭 > (order 값에 아무것도 안 넣고) Execute 클릭 시
- 오름차순 정렬로 잘 출력되는 것 확인
이때까지의 코드들:
# .../todos/src/main.py 내용
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def health_check_handler():
return {"ping": "pong"}
todo_data = {
1: {
"id": 1,
"content": "실전! FastAPI 섹션 0 수강",
"is_done": True,
},
2: {
"id": 2,
"content": "실전! FastAPI 섹션 1 수강",
"is_done": False,
},
3: {
"id": 3,
"content": "실전! FastAPI 섹션 2 수강",
"is_done": False,
},
}
@app.get("/todos")
def get_todos_handler(order: str | None = None):
rt = list(todo_data.values())
if order and order == "DESC":
return rt[::-1]
return rt
'Web 개발 > FAST API (인프런 강의 내용)' 카테고리의 다른 글
1 실습4 PATCH API todo 수정 (0) | 2024.04.16 |
---|---|
1 실습3 POST API todo 생성 (0) | 2024.04.15 |
1 실습2 GET API 단일조회 (0) | 2024.04.09 |
1 FastAPI 알아보기 (0) | 2024.03.26 |
0 오리엔테이션 (0) | 2024.03.26 |