FastAPI 개발자 tiangolo는 FastAPI를 어떻게 사용할까 궁금해서 찾아본 프로젝트
https://github.com/tiangolo/full-stack-fastapi-postgresql
이번 게시글에서는 설정파일을 어떻게 구성하고 구조화하였는지 분석하려고 함
환경변수는 pydantic_settings를 기반으로 구성되어있으므로 pydantic_settings를 모른다면 pydantic_settings를 이용한 환경설정을 먼저 보고 오는 것을 권장함
소스 개요
config.py 파일 경로는 다음과 같음
```
app
└── core # 데이터베이스 마이그레이션을 관리하는 Alembic 설정 파일 및 스크립트가 저장된 디렉토리
└── config.py # 앱 전역 설정파일
```
import secrets
from typing import Any
from pydantic import (
AnyHttpUrl,
HttpUrl,
PostgresDsn,
ValidationInfo,
field_validator,
)
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
API_V1_STR: str = "/api/v1"
SECRET_KEY: str = secrets.token_urlsafe(32)
# 60 minutes * 24 hours * 8 days = 8 days
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8
SERVER_HOST: AnyHttpUrl
# BACKEND_CORS_ORIGINS is a JSON-formatted list of origins
# e.g: '["http://localhost", "http://localhost:4200", "http://localhost:3000", \
# "http://localhost:8080", "http://local.dockertoolbox.tiangolo.com"]'
BACKEND_CORS_ORIGINS: list[AnyHttpUrl] | str = []
@field_validator("BACKEND_CORS_ORIGINS", mode="before")
@classmethod
def assemble_cors_origins(cls, v: str | list[str]) -> list[str] | str:
if isinstance(v, str) and not v.startswith("["):
return [i.strip() for i in v.split(",")]
elif isinstance(v, list | str):
return v
raise ValueError(v)
PROJECT_NAME: str
SENTRY_DSN: HttpUrl | None = None
@field_validator("SENTRY_DSN", mode="before")
@classmethod
def sentry_dsn_can_be_blank(cls, v: str) -> str | None:
if not v:
return None
return v
POSTGRES_SERVER: str
POSTGRES_USER: str
POSTGRES_PASSWORD: str
POSTGRES_DB: str
SQLALCHEMY_DATABASE_URI: PostgresDsn | None = None
@field_validator("SQLALCHEMY_DATABASE_URI", mode="before")
def assemble_db_connection(cls, v: str | None, info: ValidationInfo) -> Any:
if isinstance(v, str):
return v
return PostgresDsn.build(
scheme="postgresql+psycopg",
username=info.data.get("POSTGRES_USER"),
password=info.data.get("POSTGRES_PASSWORD"),
host=info.data.get("POSTGRES_SERVER"),
path=f"{info.data.get('POSTGRES_DB') or ''}",
)
SMTP_TLS: bool = True
SMTP_PORT: int | None = None
SMTP_HOST: str | None = None
SMTP_USER: str | None = None
SMTP_PASSWORD: str | None = None
# TODO: update type to EmailStr when sqlmodel supports it
EMAILS_FROM_EMAIL: str | None = None
EMAILS_FROM_NAME: str | None = None
@field_validator("EMAILS_FROM_NAME")
def get_project_name(cls, v: str | None, info: ValidationInfo) -> str:
if not v:
return info.data["PROJECT_NAME"]
return v
EMAIL_RESET_TOKEN_EXPIRE_HOURS: int = 48
EMAIL_TEMPLATES_DIR: str = "/app/app/email-templates/build"
EMAILS_ENABLED: bool = False
@field_validator("EMAILS_ENABLED", mode="before")
def get_emails_enabled(cls, v: bool, info: ValidationInfo) -> bool:
return bool(
info.data.get("SMTP_HOST")
and info.data.get("SMTP_PORT")
and info.data.get("EMAILS_FROM_EMAIL")
)
# TODO: update type to EmailStr when sqlmodel supports it
EMAIL_TEST_USER: str = "test@example.com"
# TODO: update type to EmailStr when sqlmodel supports it
FIRST_SUPERUSER: str
FIRST_SUPERUSER_PASSWORD: str
USERS_OPEN_REGISTRATION: bool = False
model_config = SettingsConfigDict(case_sensitive=True)
settings = Settings()
주요 설정
- 일반 설정
- API_V1_STR: API 버전을 지정하는 문자열
- SECRET_KEY: 인증 토큰 및 세션 등을 위한 시크릿 키
- ACCESS_TOKEN_EXPIRE_MINUTES: 액세스 토큰 만료 시간(분 단위)
- PROJECT_NAME: 프로젝트의 이름
- EMAIL_RESET_TOKEN_EXPIRE_HOURS: 이메일 리셋 토큰의 만료 시간(시간 단위)
- EMAIL_TEMPLATES_DIR: 이메일 템플릿 디렉토리 경로
- EMAILS_ENABLED: 이메일 전송 기능 활성화 여부
- EMAIL_TEST_USER: 이메일 테스트 사용자
- FIRST_SUPERUSER: 최초 슈퍼 사용자 이름
- FIRST_SUPERUSER_PASSWORD: 최초 슈퍼 사용자 비밀번호
- USERS_OPEN_REGISTRATION: 사용자의 개방된 가입 여부
- CORS 관련 설정
- BACKEND_CORS_ORIGINS: 허용된 CORS 원본 목록.
- 데이터베이스 관련 설정
- POSTGRES_SERVER: PostgreSQL 서버 호스트
- POSTGRES_USER: PostgreSQL 사용자 이름
- POSTGRES_PASSWORD: PostgreSQL 비밀번호
- POSTGRES_DB: PostgreSQL 데이터베이스 이름
- SQLALCHEMY_DATABASE_URI: SQLAlchemy를 위한 PostgreSQL 데이터베이스 URI
- 이메일 관련 설정
- SMTP_TLS: SMTP TLS 활성화 여부
- SMTP_PORT: SMTP 포트
- SMTP_HOST: SMTP 호스트
- SMTP_USER: SMTP 사용자
- SMTP_PASSWORD: SMTP 비밀번호
- EMAILS_FROM_EMAIL: 이메일 발신자 이메일 주소
- EMAILS_FROM_NAME: 이메일 발신자 이름
- 서버 관련 설정
- SERVER_HOST: 서버 호스트 URL
- 로그 및 모니터링 관련 설정
- SENTRY_DSN: Sentry 프로젝트 DSN
소스 분석
Python에서 환경 설정을 다루는 데 사용되는 Pydantic 라이브러리를 사용하여 구조화함
Pydantic 및 pydantic_settings 라이브러리를 통해 설정 값을 관리하고 유효성을 검사하는 데 사용
Pydantic을 사용하면 설정을 타입 안정성이 있는 Python 객체로 정의할 수 있음
설정 파일에 있는 일부 필드들은 다른 필드의 값에 의존하는데, 이를 위하여 @field_validator 데코레이터와 ValidationInfo 객체를 이용
위의 코드를 보면 EMAILS_FROM_NAME 필드가 PROJECT_NAME 필드의 값을 기본값으로 사용하도록 설정되어 있음
이를 위해 ValidationInfo 객체를 사용하여 필요한 정보를 얻고, 필드 값을 조작하여 반환하고 있음
타입 힌트(from typing import Any) 및 Pydantic의 타입들(AnyHttpUrl, PostgresDsn, ValidationInfo)을 사용하여 데이터의 형식을 지정하고 유효성을 검사하는 데 사용
참고
Fastapi 설정 docs : https://fastapi.tiangolo.com/ru/advanced/settings/
FastAPI 개발자가 직접 개발한 FastAPI backend 프로젝트 구조
FastAPI 개발자가 직접 개발한 FastAPI backend alembic
FastAPI 개발자가 직접 개발한 FastAPI backend DB 초기화 방법
FastAPI 개발자가 직접 개발한 FastAPI backend pyproject.toml
FastAPI 개발자가 직접 개발한 FastAPI backend 설정파일 config.py
FastAPI 개발자가 직접 개발한 FastAPI backend 데이터모델 models.py
'Python > Web' 카테고리의 다른 글
prometheus_client 라이브러리를 이용한 애플리케이션 성능 지표 수집 (0) | 2024.06.05 |
---|---|
FastAPI 개발자가 직접 개발한 FastAPI backend DB 초기화 방법 (1) | 2024.03.25 |
FastAPI 개발자가 직접 개발한 FastAPI backend 데이터모델 models.py (0) | 2024.03.16 |
FastAPI 개발자가 직접 개발한 FastAPI backend alembic (1) | 2024.03.12 |
Flask-Migrate 테이블 초기 데이터 관리 (0) | 2024.03.10 |