인공지능 개발자 수다(유튜브 바로가기) 자세히보기

Fastapi

[FastAPI] API의 Input (8)

Suda_777 2025. 1. 2. 01:25

목차

    반응형

     

    지금까지는, API를 만들 때 그때그때 필요한 값을 Input으로 만들었다.

    앞으로는 상황에 맞는 값들을 사용해 보자.

    1. Path parameter

    1.1.설명

    • 경로(Path)에 파라미터 지정하는 방법
    • Path Parameters는 클라이언트가 서버로 데이터를 전달하는 방법 중 하나
    • 일반적으로 str, int 를 처리한다.
    • 리소스 식별에 적합, (특정 리소스(데이터)를 고유하게 식별해야 하는 경우)
    • get, delete 에서 주로 사용

    1.2. 기본 사용법

    • URL에서 중괄호 {} 안에 정의
    • 함수의 파라미터에 input값, 타입힌트 정의
    • 주의사항
      • {} 안의 변수명과 함수 매개변수명이 일치
      • 기본값을 설정할 수 없음
    @app.get("/users/{user_id}")
    async def read_user(user_id: int):
        return {"user_id": user_id}

     

    1.3. Path() 사용법

    • Path() 설명
      • swagger에서 설명 표시
      • 데이터 검증
    • 주요 매개변수
      • default : 기본값, ... 인 경우 notnull
      • title : 파라미터의 이름에 대한 제목 (Swagger 문서에 표시됨)
      • description : 파라미터에 대한 설명 (Swagger 문서에 표시됨)
      • ge : greater than or equal to (>=)
      • gt : greater than (>)
      • le : less than or equal to (<=)
      • lt : less than (<)
      • regex : 정규식을 이용한 값 제한
      • alias: 변수 이름 대신 사용할 별칭을 지정, 클라이언트 요청에서 다른 이름으로 사용
    @app.get("/products/{product_id}")
    async def read_product(
        product_id: int = Path(..., title="The ID of the product", ge=1, le=1000)
    ):
        return {"product_id": product_id}

     

    alias 사용 예시

    from fastapi import Path
    
    @app.get("/users/{user_id}")
    async def get_user(uid: int = Path(..., alias="user_id")):
        return {"user_id": uid}

     


    2. Query parameter

    2.1. 설명

    • URL 요청 시 '?'를 넣고 key, value 형식으로 파라미터 전달
    • 파라미터는 &로 구분
    • 예시: /items/?q=search
    • 경로 매개변수와 달리 쿼리 파라미터는 필수값이 아니며, 기본값을 설정할 수 있다
    • 일반적으로 str, int 를 처리한다.
    • 필터링, 검색 조건, 정렬 순서, 페이지네이션 등 기능 구현에 적합 (데이터 자체보다는 데이터의 속성 또는 동작을 지정해야 할 때. )
    • get, delete 에서 주로 사용

    2.2. 기본 사용법

    함수 매개변수에 기본값을 설정하면 쿼리 파라미터로 처리

    @app.get("/items/")
    async def read_items(q: str = None):
        return {"q": q}

     

    2.3. Query() 사용법

    • 주요 매개변수
      • default : 기본값, ... 인 경우 notnull
      • title: 파라미터의 이름에 대한 제목 (Swagger 문서에 표시됨)
      • description: 파라미터에 대한 설명 (Swagger 문서에 표시됨)
      • min_length, max_length: 문자열 길이 제한
      • regex: 정규 표현식을 사용한 값 검증
    from fastapi import Query
    
    @app.get("/items/")
    async def read_items(
        q: Optional[str] = Query(
            None, 
            title="Search Query", 
            description="Search string for items", 
            min_length=3, 
            max_length=50
        )
    ):
        return {"q": q}

     

     

    path와 query 사용 시점 차이

     

    • Path는 "누구/무엇"을 식별할 때.
    • Query는 "어떻게/조건"을 지정할 때.

    path와 query 사용 공통점

     

    • get, delete 에서 주로 사용

    3. Request Body

    3.1. 설명

    • Request Body는 API 클라이언트가 서버로 데이터를 보낼 때 HTTP 요청의 본문(body)에 포함된 데이터를 의미
    • application/json 형태의 데이터 (Json 데이터)
    • 주로 POST, PUT, PATCH 메서드에서 사용, 입력 값이 복잡한 경우 사용
    • Pydantic 모델을 사용
    • Swagger 에서 JSON 입력란 제공

    3.2. 기본 사용

    • request body에서 전달할 값의 이름, 타입, 기본값을 Pydantic에서 정의한다.
    • 매개변수의 타입힌트에 Pydantic 클래스명을 넣어준다.
    class Item(BaseModel):
        name: str
        description: str
        price: float
        tax: float = 0.0  # 기본값 설정 가능
    
    @app.post("/items/")
    async def create_item(item: Item):
        return {"item": item}

     

    3.3. 필드(Field) 레벨 검증

    • Field() 를 이용
    • 매개변수 설명
      • default: 필드의 기본값
      • default_factory: 기본값을 함수로 생성
      • title: 필드의 제목을 지정 (Swagger UI에서 표시)
      • description: 필드에 대한 설명을 추가 (Swagger UI에서 표시)
      • gt / ge: 값이 초과(gt) 또는 이상(ge)
      • lt / le: 값이 미만(lt) 또는 이하(le)
      • min_length / max_length: 문자열의 최소/최대 길이
      • regex: 값이 정규 표현식에 부합
    from pydantic import BaseModel, Field
    
    class Item(BaseModel):
        name: str = Field(..., title="Name of the item", max_length=50)
        price: float = Field(..., gt=0, description="Price must be greater than zero")
        tax: float = Field(0.0, le=100.0, description="Tax must be 100 or less")
    
    @app.post("/items/")
    async def create_item(item: Item):
        return {"item": item}

     

    3.4. Body() 사용법

    • 설명
      • Body는 단일 값 또는 기본 데이터를 처리할 때 사용함 (문자열, 숫자 등)
    • 매개변수
      • default
      • embed : True인 경우 request Body 데이터를 키 없이 전달
      • title
      • description
      • example
      • examples
      • gt, ge, lt, le
      • regex
    from fastapi import Body
    
    @app.post("/multi-fields/")
    async def multi_fields(
        name: str = Body(..., description="The name of the item"),
        price: float = Body(..., description="The price of the item")
    ):
        return {"name": name, "price": price}

     


    4. Form 데이터

    4.1. 기본 설명

    텍스트 형태의 데이터와 파일을 함께 전송할 수 있는 형식

    multipart/form-data 형태의 데이터

    파일 업로드에 특화된 형식이므로, 파일이 없을 경우 Form 데이터를 사용하지 않는 것이 좋음

    클라이언트 제한으로 인해 JSON을 사용할 수 없는 경우 사용

    Pydantic를 사용할 수 없기 때문에 데이터를 하나하나 받아야 한다.

     

    4.2. 기본 사용법

    Query, Body와 마찬가지로 단순히 타입힌트만 지정해도 사용은 할 수 있다.

    @app.post("/optional-login/")
    async def optional_login(
        username: str
        password: str
    ):
        return {"username": username, "password": password}

     

    그렇지만 FastAPI는 매개변수의 타입과 위치를 명시적으로 지정하지 않으면, 다음과 같은 우선순위에 따라 데이터를 처리한다.

    1. Query Parameters (쿼리 매개변수)

    2. Request Body (JSON)

    3. Form Data

    그러므로 가능하면 명확하게 지정해 주는 것이 좋겠다.

     

    4.3. Form() 사용하기

    from fastapi import FastAPI, Form
    
    app = FastAPI()
    
    @app.post("/login/")
    async def login(
        username: str = Form(...),
        password: str = Form(...)
    ):
        return {"username": username, "password": password}

     


    5. 파일(File) 데이터

    5.1. 기본 설명

    파일 데이터도 input 값이 될 수 있다.

    txt, xlsx, ppt, pdf, mp4, mp3, png 등 모든 유형의 파일이 가능

     

    기본 도구

    • File
      • 설명
        • 파일 데이터를 필수값/선택값으로 설정하거나 검증할 때 사용
      • 매개변수
        • default: 기본값
        • media_type: 파일의 MIME 유형(Content-Type)
        • title
        • description
        • alias
        • example
        • deprecated: 파일 입력값을 더 이상 사용하지 않을 경우 이를 표시
        •  
    • UploadFile
      • 설명
        • 파일 객체를 처리
        • 비동기 스트리밍을 지원
      • 주요 속성/메서드
        • file: 파일의 비동기 스트리밍 객체 (SpooledTemporaryFile)
        • filename: 업로드된 파일 이름
        • content_type: 업로드된 파일의 MIME 유형
        • read(): 파일 데이터를 읽음
        • write(data): 파일 데이터를 작성
        • close(): 파일 객체를 닫음

    5.2. 예시 코드

    파일 읽기

    from fastapi import FastAPI, File, UploadFile
    
    @app.post("/read-file/")
    async def read_file(file: UploadFile = File(...)):
        content = await file.read()  # 파일 내용을 읽음
        return {"filename": file.filename, "content": content.decode("utf-8")}

     

    파일 저장

    @app.post("/save-file/")
    async def save_file(file: UploadFile = File(...)):
        file_path = f"./uploads/{file.filename}"
        with open(file_path, "wb") as f:
            f.write(await file.read())  # 파일 저장
        return {"message": f"File saved to {file_path}"}

     

    필드 상세 정의

    @app.post("/upload/")
    async def upload_file(
        file: UploadFile = File(
            ..., 
            media_type="image/png", 
            description="Upload a PNG file", 
            alias="image_file", 
            title="Image Upload", 
            example="example.png", 
            deprecated=False
        )
    ):
        return {
            "filename": file.filename,
            "content_type": file.content_type
        }

     

    폼(Form)과 파일(File) 함께 사용

    from fastapi import FastAPI, File, UploadFile, Form
    
    app = FastAPI()
    
    @app.post("/upload/")
    async def upload_file_with_form(
        file: UploadFile = File(...),
        description: str = Form(...)
    ):
        return {"filename": file.filename, "description": description}

     


    6. Headers

    6.1. 기본 설명

    • Header 란?
      • 헤더는 요청이나 응답의 본문과는 별도로 전송되며, HTTP 메시지의 첫 부분에 위치
      • key: value 형식의 문자열로 구성
      • HTTP 요청이나 응답을 처리하기 위한 추가 정보를 제공
      • 예시
        • 클라이언트 정보 (e.g., User-Agent)
        • 인증 정보 (e.g., Authorization)
        • 데이터 형식 명시 (e.g., Content-Type)
    • 언제 Header(헤더)를 사용할까?
      • 제어 정보가 필요한 경우 (데이터 형식, 인코딩, 인증 정보 등을 제공)
        • 예: Authorization, Content-Type
      • 클라이언트/서버 간 상태 관리 (쿠키 설정, 캐싱 정책, 세션 유지 등)
        • 예: Set-Cookie, Cache-Control
      • 클라이언트-서버 간 데이터 협상(클라이언트가 수용 가능한 데이터 형식을 명시)
        • 예: Accept, Accept-Encoding
    • Header 종류
      • 요청(Request) 헤더 : 클라이언트가 서버에 요청할 때 포함하는 헤더
      • 응답(Response) 헤더 : 서버가 클라이언트에게 응답할 때 포함하는 헤더

    6.2. 기본 헤더 읽기

    Header() 를 사용한다

    from fastapi import FastAPI, Header
    
    app = FastAPI()
    
    @app.get("/items/")
    async def read_items(
        user_agent: str = Header(...),
        host: str = Header(...)
    ):
        return {"User-Agent": user_agent, "Host": host}

     

    request 모든 헤더 읽기 (Request 객체를 사용, 의존성 개입으로 자동으로 값이 들어감)

    from fastapi import FastAPI, Request
    
    @app.get("/all-headers/")
    async def read_all_headers(request: Request):
        return {"headers": dict(request.headers)}

     

    response 헤더 추가 (Response 객체를 사용, 의존성 개입으로 자동으로 값이 들어감)

    from fastapi import FastAPI, Response
    
    app = FastAPI()
    
    @app.get("/add-headers/")
    async def add_headers(response: Response):
        response.headers["X-Custom-Header"] = "My Value"
        response.headers["Cache-Control"] = "no-cache"
        return {"message": "Headers added"}

     

     

    반응형