250925 [ Day 58 ] - Project (2)

TaeHyun·2025년 9월 25일

TIL

목록 보기
60/184

시작하며

오늘은 필요한 데이터를 수집하고 정리하는 데 주로 시간을 보냈다. 이후에 머신러닝을 해야 하다 보니 재활용 쓰레기를 학습시키기 위한 이미지 데이터가 상당히 많이 필요했다. 일단 간단하게 종이, 비닐, 캔, 플라스틱, 유리, 스티로폼 이렇게 6종으로만 분류해봤는데도 데이터가 거의 50GB 정도 되는 것 같다.
이번 프로젝트에서 최종적으로 웹/앱에서 이미지를 입력받아 학습시킨 AI 모델로 어떤 재활용 쓰레기인지 분류해주는 기획이기 때문에 API를 다뤄야 한다. 그래서 데이터 수집 및 정리가 끝나고 API에 대해서 조금 공부해보았다.

API

  • Application Programming Interface - 프로그램들이 서로 소통하는 규칙

웹 브라우저 → API 요청 → 서버 → 데이터베이스 → 서버 → API 응답 → 웹브라우저에서 결과 표시


REST API

  • REST (REpresentational State Transfer)
    • 웹에서 데이터를 주고받는 표준화된 방식
    • "이렇게 API를 만들면 모든 개발자가 이해하기 쉬워요"라는 약속
  • 기본 원칙
    1. 소문자 사용
    2. 하이픈 ( - ) 사용
    3. 마지막에 슬래시 ( / ) 사용 X
    4. 기능을 나타내는 동사 사용 X
    5. 자원에 대한 행위는 HTTP Method (POST / GET / PUT / DELETE) 사용
    6. 슬래시 ( / ) 를 사용해 계층 관계 표현

FastAPI

특징

  • 빠르다
  • 파이썬 표준 타입 기반
  • 비동기 지원 (async / await)

기본적인 사용법

from fastapi import FastAPI

app = FastAPI()

  • 데코레이터로 HTTP 메서드와 경로 지정
# GET 요청 처리
@app.get("/")
async def root():
    return {"message": "Hello World"}

# POST 요청 처리  
@app.post("/items")
async def create_item():
    return {"message": "Item created"}

# PUT, DELETE 등도 동일한 방식
@app.put("/items/{item_id}")
async def update_item(item_id: int):
    return {"message": f"Item {item_id} updated"}

  • 경로 매개변수 (타입 지정 중요)
# 문자열 타입 (기본값)
@app.get("/items/{item_id}")
async def get_item(item_id: str):
    return {"item_id": item_id, "type": "문자열"}

# 정수 타입
@app.get("/products/{product_id}")
async def get_product(product_id: int):
    return {"product_id": product_id, "type": "정수"}

  • 쿼리 매개변수
    • URL에서 ? 후에 나오고 &으로 구분되는 키-값 쌍의 집합
    • 페이지 나누기, 필터링, 정렬 등 다양한 용도로 사용
# 1. 게시글 목록 (페이징)
@app.get("/posts")
async def get_posts(page: int = 1, limit: int = 10, sort: str = "latest"):
    return {
        "page": page,
        "limit": limit,
        "sort": sort,
        "posts": [f"게시글 {i}" for i in range(1, limit + 1)]
    }

# 2. 상품 검색
@app.get("/shop/search")
async def search_products(
    keyword: str = None,        # 검색어
    category: str = None,       # 카테고리
    min_price: int = 0,         # 최소 가격
    max_price: int = 1000000,   # 최대 가격
    in_stock: bool = True       # 재고 여부
):
    return {
        "keyword": keyword,
        "category": category,
        "price_range": f"{min_price}원 ~ {max_price}원",
        "in_stock_only": in_stock,
        "results": "검색 결과..."
    }

의존성 주입

  • 함수가 필요한 것을 미리 만들어서 전달해주는 것
  • 코드의 중복 제거
def get_database():
    print("데이터베이스 연결 중...")
    return "데이터베이스 객체"

@app.get("/test")
async def test(db = Depends(get_database)):
    print(f"받은 db: {db}")
    return {"db": db}

Pydantic

  • 데이터의 형태를 미리 정의하는 도구
  • 타입을 자동으로 검증
  • 필수 항목을 자동으로 체크

사용법

  • 기본 정의
from pydantic import BaseModel

class User(BaseModel):
    name: str      # 이름 (문자열, 필수)
    age: int       # 나이 (정수, 필수)  
    email: str     # 이메일 (문자열, 필수)

  • Optional : 선택 항목
from typing import Optional

class User(BaseModel):
    name: str                    # 필수 항목
    age: int                     # 필수 항목
    email: str                   # 필수 항목
    phone: Optional[str] = None  # 선택 항목 (없어도 됨)
    bio: Optional[str] = None    # 선택 항목 (없어도 됨)

마치며

아직 안 다룬 내용들이 매우 많지만 내일 이어서 공부해봐야겠다. 조금이나마 FastAPI를 사용해서 웹과 연동해보고, 웹에서 이미지를 입력받아 미리 정해둔 내용이 출력되는 간단한 연동 연습을 해보았다. 내일은 정리해둔 데이터를 사용해서 간단하게 AI 테스트를 해볼 예정이다. 본격적으로 API를 다루기 전에 어느 정도 공부를 더 해봐야겠다.

profile
Hello I'm TaeHyunAn, Currently Studying Data Analysis

0개의 댓글