๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŒฑBackend

ํŒŒ์ด์ฌ FastAPI๋ฅผ ์ด์šฉํ•œ API ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ (0) - ์†Œ๊ฐœ ๋ฐ ์˜ˆ์ œ

by discphy 2024. 11. 26.
๋ฐ˜์‘ํ˜•

FastAPI๋ž€?

Python์˜ ์›น ํ”„๋ ˆ์ž„์›Œํฌํ•˜๋ฉด, ๋ณดํ†ต Django์™€ Flask๊ฐ€ ๋– ์˜ค๋ฅผ ๊ฒƒ์ด๋‹ค.

2023๋…„๋ถ€ํ„ฐ ์„ฑ๋Šฅ๊ณผ ๊ฐœ๋ฐœํŽธ์˜์„ฑ์— ์ตœ์ ํ™”๋œ FastAPI๊ฐ€ ๋“ฑ์žฅํ•˜๋ฉด์„œ ๊ธ‰ ๋ถ€์ƒ ์ค‘์ด๋‹ค.

FastAPI ํŠน์ง•


  • ๋น ๋ฆ„: (Starlette๊ณผ Pydantic ๋•๋ถ„์—) NodeJS ๋ฐ Go์™€ ๋Œ€๋“ฑํ•  ์ •๋„๋กœ ๋งค์šฐ ๋†’์€ ์„ฑ๋Šฅ. ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฐ€์žฅ ๋น ๋ฅธ ํŒŒ์ด์ฌ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜.
  • ๋น ๋ฅธ ์ฝ”๋“œ ์ž‘์„ฑ: ์•ฝ 200%์—์„œ 300%๊นŒ์ง€ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ ์†๋„ ์ฆ๊ฐ€.
  • ์ ์€ ๋ฒ„๊ทธ: ์‚ฌ๋žŒ(๊ฐœ๋ฐœ์ž)์— ์˜ํ•œ ์—๋Ÿฌ ์•ฝ 40% ๊ฐ์†Œ.
  • ์ง๊ด€์ : ํ›Œ๋ฅญํ•œ ํŽธ์ง‘๊ธฐ ์ง€์›. ๋ชจ๋“  ๊ณณ์—์„œ ์ž๋™์™„์„ฑ. ์ ์€ ๋””๋ฒ„๊น… ์‹œ๊ฐ„.
  • ์‰ฌ์›€: ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ๋ฐฐ์šฐ๋„๋ก ์„ค๊ณ„. ์ ์€ ๋ฌธ์„œ ์ฝ๊ธฐ ์‹œ๊ฐ„.
  • ์งง์Œ: ์ฝ”๋“œ ์ค‘๋ณต ์ตœ์†Œํ™”. ๊ฐ ๋งค๊ฐœ๋ณ€์ˆ˜ ์„ ์–ธ์˜ ์—ฌ๋Ÿฌ ๊ธฐ๋Šฅ. ์ ์€ ๋ฒ„๊ทธ.
  • ๊ฒฌ๊ณ ํ•จ: ์ค€๋น„๋œ ํ”„๋กœ๋•์…˜ ์šฉ ์ฝ”๋“œ๋ฅผ ์–ป์œผ์‹ญ์‹œ์˜ค. ์ž๋™ ๋Œ€ํ™”ํ˜• ๋ฌธ์„œ์™€ ํ•จ๊ป˜.
  • ํ‘œ์ค€ ๊ธฐ๋ฐ˜: API์— ๋Œ€ํ•œ (์™„์ „ํžˆ ํ˜ธํ™˜๋˜๋Š”) ๊ฐœ๋ฐฉํ˜• ํ‘œ์ค€ ๊ธฐ๋ฐ˜: OpenAPI (์ด์ „์— Swagger๋กœ ์•Œ๋ ค์กŒ๋˜) ๋ฐ JSON ์Šคํ‚ค๋งˆ.

FastAPI ๊ตฌ๊ธ€ ํŠธ๋ Œ๋“œ ์กฐ์‚ฌ


Django๊ฐ€ ์••๋„์ ์ด๊ธด ํ•˜๋‚˜, Flask์™€ ๋น„๊ตํ•ด๋ณด๋ฉด 2023๋…„๋ถ€ํ„ฐ ๋งŽ์€ ๊ด€์‹ฌ์„ ๋ฐ›์•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

ํŒŒ์ด์ฌ ์›น ํ”„๋ ˆ์ž„์›Œํฌ ์„ฑ๋Šฅ๊ณผ ์žฅ๋‹จ์  ๋น„๊ต (GPT ๋‹ต๋ณ€ ์ฒจ๋ถ€)

  ์„ฑ๋Šฅ ์žฅ์  ๋‹จ์ 
FastAPI ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์—ฌ ๋น ๋ฅธ ์†๋„์™€ ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” https://docs.python.org/ko/3/library/asyncio.html ๋ฐ https://www.uvicorn.org/๊ณผ ๊ฐ™์€ ๋น„๋™๊ธฐ ์›น ์„œ๋ฒ„์™€์˜ ํ†ตํ•ฉ์œผ๋กœ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. - ๋น ๋ฅธ ๊ฐœ๋ฐœ๊ณผ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

- Pydantic์„ ํ†ตํ•œ ์ž๋™ API ๋ฌธ์„œ ์ƒ์„ฑ๊ณผ ํƒ€์ž… ์ฒดํฌ๋ฅผ ์ง€์›ํ•˜์—ฌ API ๋ฌธ์„œํ™”๋ฅผ ์šฉ์ดํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

- Swagger UI์™€ OpenAPI๋ฅผ ์ง€์›ํ•˜์—ฌ API ๋ฌธ์„œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
- ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์— ๋Œ€ํ•œ ํ•™์Šต ๊ณก์„ ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- Flask๋‚˜ Django์— ๋น„ํ•ด ์•„์ง๊นŒ์ง€ ์ƒํƒœ๊ณ„๊ฐ€ ์ƒ๋Œ€์ ์œผ๋กœ ์ž‘์Šต๋‹ˆ๋‹ค.
Flask ๊ฐ€๋ณ๊ณ  ๊ฐ„๊ฒฐํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋ฏ€๋กœ ์†๋„ ๋ฉด์—์„œ ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ FastAPI๋ณด๋‹ค๋Š” ์„ฑ๋Šฅ์ด ๋‚ฎ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ๋ฏธ๋‹ˆ๋ฉ€ํ•œ ๋””์ž์ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์„ ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ํ™•์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- ๋‹ค์–‘ํ•œ ํ™•์žฅ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๋“ค์ด ์ต์ˆ™ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
- ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์•„ ๋Œ€๊ทœ๋ชจ ๋ฐ ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ์— ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- Flask ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๊ตฌ์กฐ๊ฐ€ ๋ณต์žกํ•ด์งˆ ๊ฒฝ์šฐ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Django Django๋Š” ์ „์ฒด์ ์œผ๋กœ ์•ˆ์ •์ ์ด๊ณ  ๋น ๋ฅธ ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— FastAPI๋ณด๋‹ค๋Š” ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. - ORM, ๊ด€๋ฆฌ์ž ํŒจ๋„, ์ธ์ฆ ์‹œ์Šคํ…œ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜์—ฌ ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

- ์•ˆ์ •์„ฑ๊ณผ ๋ณด์•ˆ์„ฑ์ด ๋†’์œผ๋ฉฐ, ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฐ ์ƒํƒœ๊ณ„๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์–ด ๋‹ค์–‘ํ•œ ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ง€์›์ด ์šฉ์ดํ•ฉ๋‹ˆ๋‹ค.
- ๋ฌด๊ฑฐ์šด ํ”„๋ ˆ์ž„์›Œํฌ์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž‘์€ ํ”„๋กœ์ ํŠธ๋‚˜ ๋น ๋ฅธ ํ”„๋กœํ† ํƒ€์ดํ•‘์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- Django์˜ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๊ณผ ๊ธฐ๋ณธ ์ œ๊ณต๋˜๋Š” ๊ธฐ๋Šฅ ๋•Œ๋ฌธ์— ํ”„๋กœ์ ํŠธ์˜ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ์„ ๊ฐ–๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•œ ๋งˆ๋””๋กœ ์ •๋ฆฌํ•˜์ž๋ฉด, FastAPI๋Š” ๊ฐœ๋ฐœ๊ณผ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ„๋‹จํ•˜๋ฉด์„œ API ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง€์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค!

FastAPI๋กœ ์›น ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ

์˜ˆ์ œ์†Œ์Šค : https://wikidocs.net/book/8531

๋…ธ๋งˆ๋“œ ์ฝ”๋”์—์„œ ์ œ๊ณตํ•˜๋Š” “Python์œผ๋กœ ์›น ์Šคํฌ๋ž˜ํผ ๋งŒ๋“ค๊ธฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” ์˜ˆ์ œ๋ฅผ ์‘์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•œ API ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜์ž.

1. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ๋ฐ Hello World


  1. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ : PyCharm IDE๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ํ”„๋กœ์ ํŠธ ์ด๋ฆ„๊ณผ ๊ฐ€์ƒํ™˜๊ฒฝ ์„ธํŒ… ํ›„ ์ƒ์„ฑ
  1. ๊ฐ€์ƒํ™˜๊ฒฝ ์ ์šฉ ํ™•์ธ
  2. # ํ™•์ธ์ด ์•ˆ๋œ๋‹ค๋ฉด, ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์ฐจ๋ก€๋Œ€๋กœ ์‹คํ–‰ cd .venv source activate
  3. .venv ๊ฐ€์ƒ ํ™˜๊ฒฝ ํด๋”๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ ํ™•์ธ ํ›„ ์ขŒ์ธก ํ•˜๋‹จ์— ์žˆ๋Š” ํ„ฐ๋ฏธ๋„ ์•„์ด์ฝ˜์„ ํด๋ฆญ ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ„ฐ๋ฏธ๋„์ด ๋“ฑ์žฅํ•˜๋Š”๋ฐ (.venv) ๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ™•์ธ ๋˜์–ด์•ผ ํ•œ๋‹ค.
  1. ํŒจํ‚ค์ง€ ์„ค์น˜
  2. # FastAPI ์„ค์น˜ pip install fastapi # FastAPI ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌ๋™ํ•˜๊ธฐ ์œ„ํ•œ ์›น ์„œ๋ฒ„ Uvicon(๋น„๋™๊ธฐ ํ˜ธ์ถœ์„ ์ง€์›ํ•˜๋Š” ํŒŒ์ด์ฌ ์›น ์„œ๋ฒ„) ์„ค์น˜ pip install "uvicorn[standard]"
  1. main.py ์ž‘์„ฑ ๋ฐ ๊ตฌ๋™
     # ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด ์‹คํ–‰ 
     uvicorn main:app --reload
    
     # main:app : main.py์˜ app์„ ์˜๋ฏธ 
     # --reload : ์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ์—†์ด ๋ฐ˜์˜ 
  2. # main.py ์ƒ์„ฑ from fastapi import FastAPI app = FastAPI() @app.get("/hello") def hello(): return {"message": "hello world"}
  1. ์ ‘์† ๋ฐ ์ž๋™์œผ๋กœ ์ƒ์„ฑ ๋œ API ๋ฌธ์„œํ™•์ธ
    • http://127.0.0.1:8000/hello ์ ‘์† ์‹œ main.py ์— ์ž‘์„ฑํ•œ ์‘๋‹ต ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.
- [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs) ์— ์ ‘์†ํ•˜๋ฉด ์‹คํ–‰ ๊ฐ€๋Šฅํ•œ `Swagger UI` ๊ฐ€ ์ œ๊ณต ๋˜๊ณ , [http://127.0.0.1:8000/redoc](http://127.0.0.1:8000/redoc) ์— ์ ‘์†ํ•˜๋ฉด ์ฝ๊ธฐ ์ „์šฉ์ธ `Redoc`๋ฌธ์„œ๊ฐ€ ์ž๋™์œผ๋กœ ์ œ๊ณต๋œ๋‹ค.

    > `Spring`์—์„œ๋Š” `API` ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋ ค๋ฉด ๊นŒ๋‹ค๋กœ์šด๋ฐ…(`Spring rest docs` ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ๊ตฌ์„ฑ, `Swagger`๋กœ ์ธํ•œ `Controller` ์†Œ์Šค ์นจํˆฌ๋กœ ์ธํ•œ ์ง๊ด€์„ฑ ๋–จ์–ด์ง) `FastAPI`๋Š”.. ์™€.. ๋Œ€๋‹จํ•œ ๊ฒƒ ๊ฐ™๋‹ค..
    >

2. DB & ORM ์„ค์ •


  1. ORM ํŒจํ‚ค์ง€ ์„ค์น˜ - ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” SQLAlchemy ์„ค์น˜
  2. pip install sqlalchemy
  1. database.py ์ƒ์„ฑ
    1.  
  2. from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker # Python ๊ธฐ๋ณธ ํŒจํ‚ค์ง€์— ํฌํ•จ ๋˜์–ด์žˆ๋Š” sqlite ์‚ฌ์šฉ SQLALCHEMY_DATABASE_URL = "sqlite:///./fastapi-scrap.db" engine = create_engine( SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False} ) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() # DB ์„ธ์…˜ ๊ฐ์ฒด ํ•จ์ˆ˜ def get_db(): db = SessionLocal() try: yield db finally: db.close()
  1. ๋ชจ๋ธ ์ƒ์„ฑ - ์ฑ„์šฉ์ •๋ณด ๋„๋ฉ”์ธ
     erDiagram
         employ{
             Integer id
             String platform
             String keyword
             String company_name
             String position
             DateTime create_date
         }
    2) models.py ์ƒ์„ฑ
  2. # models.py from sqlalchemy import Column, Integer, String, DateTime from database import Base class Employ(Base): __tablename__ = "employ" id = Column(Integer, primary_key=True) platform = Column(String, nullable=False) keyword = Column(String, nullable=False) company_name = Column(String, nullable=False) position = Column(String, nullable=False) create_date = Column(DateTime, nullable=False)
  3. 1) ์ฑ„์šฉ์ •๋ณด ๋ชจ๋ธ ์„ค๊ณ„
  1. alembic ์„ค์ •1) ํ„ฐ๋ฏธ๋„์—์„œ alembic ํŒจํ‚ค์ง€ ์„ค์น˜ ๋ฐ ์ดˆ๊ธฐํ™”2) ์ดˆ๊ธฐํ™” ์‹œ, ์ƒ๊ธด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์„ค์ • ํŒŒ์ผ ์ˆ˜์ • alembic.ini, migrations/env.py
     # alembic.ini ์ˆ˜์ •
     ...
     sqlalchemy.url = sqlite:///./fastapi-study.db # ์ˆ˜์ • 
     ...
     # migrations/env.py ์ˆ˜์ •
     ...
     import models
    
     ...
     target_metadata = models.Base.metadata
     ...
    3) ๋ฆฌ๋น„์ „ ํŒŒ์ผ ์ƒ์„ฑ4) fastapi-scrap.db ์ƒ์„ฑ ํ™•์ธ
  2. # ๋ฆฌ๋น„์ „ ํŒŒ์ผ ์ƒ์„ฑ - ํ…Œ์ด๋ธ” ์Šคํฌ๋ฆฝํŠธ ๋ฌธ ์ƒ์„ฑ alembic revision --autogenerate # ๋ฆฌ๋น„์ „ ํŒŒ์ผ ์‹คํ–‰ - ํ…Œ์ด๋ธ” ์Šคํฌ๋ฆฝํŠธ ์ ์šฉ alembic upgrade head
  3. # alembic ํŒจํ‚ค์ง€ ์„ค์น˜ pip install alembic # alembic ์ดˆ๊ธฐํ™” alembic init migrations
  4. alembic์ด๋ž€? SQLAlchemy์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋„๊ตฌ์ด๋‹ค.

3. API ์ž‘์„ฑ


  1. ๋„๋ฉ”์ธ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ - domain/employ
  1. Pydantic์„ ํ™œ์šฉํ•œ employ_schema.py ์ž‘์„ฑ
     from datetime import datetime
     from pydantic import BaseModel, field_validator
    
     # ์กฐํšŒ์‹œ, ์‘๋‹ต ์ŠคํŽ™ ์ •์˜
     class Employ(BaseModel):
         id: int
         platform: str
         keyword: str
         company_name: str
         position: str
         create_date: datetime
    
     # ๋“ฑ๋ก์‹œ, ์š”์ฒญ ์ŠคํŽ™ ์ •์˜
     class EmployCreate(BaseModel):
         keyword: str
         company_name: str
         position: str
    
         # ๋นˆ ๋ฌธ์ž์—ด ๊ฒ€์ฆ
         @field_validator('keyword', 'company_name', 'position')
         def not_empty(cls, v):
             if not v or not v.strip():
                 raise ValueError("Required value")
             return v
    
  2. Pydantic์ด๋ž€, ์ž…์ถœ๋ ฅ ์ŠคํŽ™์„ ์ •์˜ํ•˜๊ณ  ๊ฐ’์„ ๊ฒ€์ฆํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.
  1. employ_crud.py ์ž‘์„ฑ - ์‹ค์ œ ์ฟผ๋ฆฌ ์ ์šฉ ๊ตฌํ˜„ ๋ถ€
  2. from datetime import datetime from models import Employ from sqlalchemy.orm import Session from domain.employ.employ_schema import EmployCreate # ์ฑ„์šฉ ์ •๋ณด ์ „์ฒด ์กฐํšŒ def employ_list(db: Session): return db.query(Employ) \ .order_by(Employ.create_date.desc()) \ .all() # ์ฑ„์šฉ ์ •๋ณด ๋“ฑ๋ก def employ_create(db: Session, create_request: EmployCreate, platform): db.add(Employ(platform=platform, keyword=create_request.keyword, company_name=create_request.company_name, position=create_request.position, create_date=datetime.now())) db.commit()
  1. APIRouter์„ ํ™œ์šฉํ•œ employ_router.py ์ž‘์„ฑ
     from fastapi import APIRouter, Depends
     from sqlalchemy.orm import Session
     from database import get_db
    
     # ์œ„์—์„œ ์ •์˜ํ•œ employ_schema, employ_crud ์ฐธ์กฐ
     from domain.employ import employ_schema, employ_crud
    
     # prefix ์„ค์ •
     router = APIRouter(
         prefix="/api/employ"
     )
    
     # ์ฑ„์šฉ ์ •๋ณด ์ „์ฒด ์กฐํšŒ API
     @router.get("/list", response_model=list[employ_schema.Employ])  # employ_schema.py ์—์„œ ์ •์˜ํ•œ ์‘๋‹ต ์ŠคํŽ™ ๊ธฐ์žฌ
     def employ_list(db: Session = Depends(get_db)):
         return employ_crud.employ_list(db)
    
     # ์ฑ„์šฉ ์ •๋ณด ์ˆ˜๋™ ๋“ฑ๋ก API
     @router.post("/manual/create")
     def employ_manual_create(create_request: employ_schema.EmployCreate,  # employ_schema.py ์—์„œ ์ •์˜ํ•œ ์š”์ฒญ ์ŠคํŽ™ ํŒŒ๋ผ๋ฏธํ„ฐ
                              db: Session = Depends(get_db)):
         employ_crud.employ_create(db, create_request, "MANUAL")
    
  2. router ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ FastAPI ์•ฑ์— ๋“ฑ๋กํ•ด์•ผ๋งŒ ๋ผ์šฐํŒ… ๊ธฐ๋Šฅ ์ •์ƒ ๋™์ž‘
  1. router๋ฅผ main.py์— ๋“ฑ๋ก
  2. from fastapi import FastAPI from domain.employ import employ_router app = FastAPI() # ๋ผ์šฐํ„ฐ ๋“ฑ๋ก app.include_router(employ_router.router)
  1. ์‹คํ–‰ ํ›„ Swagger UI๋ฅผ ์ด์šฉํ•œ API ํ…Œ์ŠคํŠธ
     uvicorn main:app --reload
  2. 1) uvicorn ๋ช…๋ น์–ด๋กœ ์„œ๋ฒ„ ์žฌ์‹คํ–‰

2) http://127.0.0.1:8000/docs ์ ‘์† ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•œ API 2๊ฐœ๊ฐ€ ๋ณด์ธ๋‹ค.

3) ์ฑ„์šฉ ์ •๋ณด ๋“ฑ๋ก API ํ…Œ์ŠคํŠธ

  • Try it out ์„ ํด๋ฆญํ•˜๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  • Request Body๋ฅผ ์ž‘์„ฑ ํ›„ Execute ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด API ํ˜ธ์ถœ์ด ๋œ๋‹ค.

4) ๋“ฑ๋กํ•œ ์ฑ„์šฉ ์ •๋ณด๋ฅผ ์ฑ„์šฉ ์ •๋ณด ์กฐํšŒ API๋ฅผ ํ†ตํ•ด ํ™•์ธ

  • ์œ„์™€ ๊ฐ™์ด ์ฑ„์šฉ ์ •๋ณด ์กฐํšŒ API ๋ฅผ Try it out ๋ฒ„ํŠผ๊ณผ Execute ๋ฒ„ํŠผ์„ ์ฐจ๋ก€๋Œ€๋กœ ํด๋ฆญ ํ•˜๋ฉด ๋‹ค์Œ ์ด๋ฏธ์ง€์™€ ๊ฐ™์ด ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋งˆ๋ฌด๋ฆฌ

์œ„์˜ ๊ณผ์ •์—์„œ ์ž์„ธํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ์€ ์–ธ๊ธ‰ํ•˜์ง€ ์•Š์•˜๋‹ค. (์ €์ž๋„ ํŒŒ์ด์ฌ ์ดˆ๋ณด๋ผ… ๐Ÿ˜น)
์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ [์ฐธ๊ณ ] ๋งํฌ๋ฅผ ํ†ตํ•ด ํ™•์ธํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค.

FastAPI ์›น ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ํ™œ์šฉํ•˜๋‹ˆ API๋Š” ๊ณต์žฅ์ฒ˜๋Ÿผ ์ฐ์–ด ๋‚ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.
๋„ˆ๋ฌด ๊ฐ„๋‹จํ•˜๊ธฐ๋„ ํ•˜๊ณ .. ๋ฌธ์„œ๋„ ์ž๋™ํ™” ํ•ด์ฃผ๋‹ˆ.. ๋„ˆ๋ฌด ํŽธ๋ฆฌํ•˜์ง€ ์•Š๋Š”๊ฐ€!!!???

๋ถ„๋Ÿ‰์ด ๋งŽ์•„์ง„ ๊ด€๊ณ„๋กœ ์Šคํฌ๋ž˜ํ•‘ํ•œ ์ฑ„์šฉ ์ •๋ณด ๋“ฑ๋ก์„ API๋กœ ๊ตฌ์„ฑํ•˜๋Š” ์˜ˆ์ œ๋Š” ๋‹ค์Œ ๊ธ€์—์„œ ๋ต™๋„๋ก ํ•˜๊ฒ ๋‹ค. ๐Ÿ‘‹๐Ÿป

https://github.com/discphy/fastapi-scrap

[์ฐธ๊ณ ]

https://github.com/tiangolo/fastapi

https://dasima.co.kr/125/fastapi๋Š”-๋ฌด์—‡์ธ๊ฐ€-fastapi-์‚ฌ์šฉ์„ค๋ช…์„œ-01/

https://wikidocs.net/book/8531

๋ฐ˜์‘ํ˜•