Skip to content
Published on

Python 완전 가이드 — FastAPI·AsyncIO·Pydantic·uv·Polars·AI 엔지니어링 (Season 2 Ep 5, 2025)

Authors

들어가며 — 2025년의 Python은 2015년의 Python이 아니다

Python을 10년 전 배우고 지금 돌아온 사람이 가장 놀랄 변화들:

  • uv (2024): pip·poetry·pyenv·pip-tools를 모두 대체하는 Rust 작성 통합 도구. 10~100배 빠름
  • Pydantic v2 (2023): 검증 엔진을 Rust로 재작성. 5~50배 빠름
  • FastAPI: 타입 힌트 기반 API 프레임워크의 사실상 표준
  • Polars (2024~): Pandas 대체. Rust 기반, 10~100배 빠름, 메모리 효율
  • Python 3.13 (2024/10): Free-threading(No-GIL) 실험, JIT 컴파일러, 개선된 인터랙티브 쉘
  • LangChain·LangGraph·Pydantic AI (2024~): AI 에이전트 스택
  • Ruff + mypy / pyright: Lint·Format·타입체크 모두 빠른 도구로 교체

Python은 "AI 엔지니어링의 공용어"로 확고히 자리잡았고, 도구 체인 전체가 Rust로 재작성되며 속도 문제도 해결되고 있다.


1부 — Python 3.13: 언어의 미래

1.1 Free-threading (No-GIL) — PEP 703

30년 된 GIL(Global Interpreter Lock)을 제거하는 Experimental Build 등장 (2024/10):

python3.13t # free-threaded build
  • GIL: 한 번에 1개 스레드만 Python 바이트코드 실행
  • No-GIL: 진정한 멀티코어 병렬성

한계: 현재 실험적, 단일 스레드 성능 10% 하락, C 확장 호환성 이슈. 20262027년 안정화 예상.

1.2 JIT Compiler — PEP 744

Copy-and-Patch JIT 추가 (실험):

python --enable-experimental-jit

초기 벤치마크는 미미(~5%)지만 장기적으로 PyPy 수준의 성능 가능성.

1.3 개선된 REPL

3.13의 표준 REPL이 드디어 사용 가능:

  • 멀티라인 편집
  • 구문 하이라이팅
  • 페이스트 모드
  • 블록 히스토리

PyPy·ipython에 의존했던 것들이 기본으로.

1.4 Type System 개선 (3.12~3.13)

# PEP 695: Generic Syntax
def first[T](items: list[T]) -> T:
    return items[0]

class Stack[T]:
    def __init__(self) -> None:
        self.items: list[T] = []

# PEP 696: Type Parameter Defaults
def process[T = str](x: T) -> T: ...

# PEP 742: TypeIs
from typing import TypeIs
def is_str(x: object) -> TypeIs[str]:
    return isinstance(x, str)

2부 — uv: 패키지 매니저 혁명

2.1 왜 uv가 게임 체인저인가

Astral이 만든 Rust 기반 통합 도구 (Ruff 제작사). 대체 대상:

  • pip → 설치
  • pip-tools → 해시 pinned requirements
  • pyenv → 파이썬 버전 관리
  • virtualenv/venv → 가상환경
  • poetry → 프로젝트 관리
  • pipx → CLI 도구 설치

속도: pip install이 10초 걸리는 프로젝트가 uv로는 0.1초.

2.2 기본 사용법

# 설치
curl -LsSf https://astral.sh/uv/install.sh | sh

# 프로젝트 초기화
uv init my-app
cd my-app

# 의존성 추가 (pyproject.toml 자동 업데이트)
uv add fastapi uvicorn
uv add --dev pytest ruff mypy

# 실행
uv run python main.py
uv run pytest

# Python 버전 관리
uv python install 3.13
uv python pin 3.13

# Lock 파일 (uv.lock)
uv lock
uv sync

2.3 uv script (단일 파일 Python)

# /// script
# requires-python = ">=3.12"
# dependencies = [
#     "httpx",
#     "rich",
# ]
# ///

import httpx
from rich import print

print(httpx.get("https://api.github.com").json())
uv run script.py
# 의존성 자동 다운로드 후 실행

2025년 새 프로젝트는 uv로 시작하는 것이 표준.


3부 — Pydantic v2: 타입 기반 검증

3.1 v2의 혁명

  • Rust로 재작성된 pydantic-core
  • 5~50배 빠름
  • Annotated 기반 강력한 제약
  • Serialization API 분리

3.2 기본 사용

from pydantic import BaseModel, EmailStr, Field
from typing import Annotated
from datetime import datetime

class User(BaseModel):
    id: int
    email: EmailStr
    name: Annotated[str, Field(min_length=1, max_length=100)]
    age: Annotated[int, Field(ge=0, le=150)]
    created_at: datetime

# 검증 + 변환
user = User.model_validate({
    "id": 1,
    "email": "alice@example.com",
    "name": "Alice",
    "age": 30,
    "created_at": "2025-01-01T00:00:00Z"
})

# 직렬화
json_str = user.model_dump_json()
dict_data = user.model_dump()

3.3 고급 기능

from pydantic import field_validator, model_validator

class Post(BaseModel):
    title: str
    content: str
    tags: list[str] = []

    @field_validator('title')
    @classmethod
    def title_not_empty(cls, v: str) -> str:
        if not v.strip():
            raise ValueError('title cannot be empty')
        return v.strip()

    @model_validator(mode='after')
    def check_tags_limit(self) -> 'Post':
        if len(self.tags) > 10:
            raise ValueError('too many tags')
        return self

3.4 Pydantic Settings

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str
    api_key: str
    debug: bool = False

    class Config:
        env_file = ".env"

settings = Settings()

환경변수·config 관리의 표준.


4부 — FastAPI: 타입 안전 API 표준

4.1 기본 예제

from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel

app = FastAPI()

class UserCreate(BaseModel):
    email: str
    password: str

class UserResponse(BaseModel):
    id: int
    email: str

@app.post("/users", response_model=UserResponse)
async def create_user(user: UserCreate) -> UserResponse:
    # user는 이미 검증됨
    # 응답은 UserResponse로 자동 직렬화
    return UserResponse(id=1, email=user.email)
  • Pydantic 모델이 요청·응답 스키마
  • OpenAPI 자동 생성 (/docs)
  • Dependency Injection 내장

4.2 Dependency Injection

async def get_db() -> AsyncGenerator[AsyncSession, None]:
    async with async_session() as session:
        yield session

async def get_current_user(token: str = Header(...)) -> User:
    # 토큰 검증 로직
    return user

@app.get("/me")
async def me(user: User = Depends(get_current_user)) -> UserResponse:
    return user

4.3 2025년 FastAPI 스택

목적라이브러리
WebFastAPI
ORMSQLAlchemy 2.0 (async), SQLModel
DB 드라이버asyncpg (Postgres), motor (Mongo)
MigrationAlembic
Dramatiq, Celery 5.x, Taskiq
캐시Redis + aioredis
테스트pytest + httpx
관측성OpenTelemetry + Prometheus

5부 — AsyncIO 실전

5.1 기본 구조

import asyncio

async def fetch(url: str) -> str:
    # 시뮬레이션
    await asyncio.sleep(1)
    return f"data from {url}"

async def main() -> None:
    # 순차
    r1 = await fetch("a")
    r2 = await fetch("b")

    # 동시 (2배 빠름)
    r1, r2 = await asyncio.gather(fetch("a"), fetch("b"))

asyncio.run(main())

5.2 TaskGroup (Python 3.11+)

async def main():
    async with asyncio.TaskGroup() as tg:
        t1 = tg.create_task(fetch("a"))
        t2 = tg.create_task(fetch("b"))
        t3 = tg.create_task(fetch("c"))
    # 컨텍스트 나오면 모든 task 완료
    # 하나라도 예외면 나머지 취소 + ExceptionGroup
    print(t1.result(), t2.result(), t3.result())

TaskGroup이 asyncio.gather보다 낫다: 구조적 동시성, 자동 취소, 명확한 에러.

5.3 asyncio.timeout (Python 3.11+)

async def fetch_with_timeout():
    async with asyncio.timeout(5.0):
        return await slow_operation()

5.4 AsyncIO 함정 5가지

  1. 블로킹 코드 혼합: requests.get 대신 httpx.AsyncClient
  2. asyncio.run 중첩: 이벤트 루프 충돌. nest_asyncio는 아티 패턴
  3. task 참조 유지 실패: asyncio.create_task 결과를 어딘가 저장해야 GC 안됨
  4. CPU 바운드 작업: run_in_executor로 별도 스레드/프로세스
  5. async def 안에서 time.sleep: asyncio.sleep 써야

6부 — Polars: Pandas의 2025년 대체재

6.1 왜 Polars인가

항목PandasPolars
엔진NumPy (C)Rust + Arrow
속도기준5~100배 빠름
메모리많이 씀Pandas의 ~50%
병렬성거의 없음자동 다중 스레드
Lazy 실행✅ (옵티마이저)
대규모 데이터어려움스트리밍 가능

6.2 기본 사용

import polars as pl

df = pl.read_csv("data.csv")

result = (
    df
    .filter(pl.col("age") > 30)
    .group_by("country")
    .agg([
        pl.col("salary").mean().alias("avg_salary"),
        pl.col("id").count().alias("count"),
    ])
    .sort("avg_salary", descending=True)
)

6.3 Lazy Evaluation

lazy_df = pl.scan_csv("huge.csv")  # 실제 읽지 않음

result = (
    lazy_df
    .filter(pl.col("year") == 2024)
    .group_by("category")
    .agg(pl.col("amount").sum())
    .collect()  # 이제 실행 (옵티마이저가 계획 수립)
)

쿼리 옵티마이저가 SQL DBMS처럼 실행 계획을 최적화.

6.4 2025년 전환 가이드

  • 새 프로젝트: Polars 기본값
  • 기존 Pandas 프로젝트: 점진 전환 (df.to_pandas() 브릿지)
  • 시각화는 여전히 Pandas가 편할 수 있음 (matplotlib/seaborn)
  • ML 라이브러리 호환은 아직 Pandas 우세 (개선 중)

7부 — AI 엔지니어링 스택 2025

7.1 LangChain의 현재

LangChain은 2023년 폭발, 2024년 성장통, 2025년 LangGraph 중심으로 재편.

  • LangChain Core: 기본 추상화 (Runnable)
  • LangGraph: 상태 기반 에이전트 그래프 (2025년 표준)
  • LangSmith: 관측성·평가

7.2 LangGraph 예제

from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI

class State(TypedDict):
    messages: Annotated[list, operator.add]

def agent(state: State):
    response = llm.invoke(state["messages"])
    return {"messages": [response]}

def should_continue(state: State) -> str:
    last = state["messages"][-1]
    if last.tool_calls:
        return "tools"
    return END

workflow = StateGraph(State)
workflow.add_node("agent", agent)
workflow.add_node("tools", tool_node)
workflow.set_entry_point("agent")
workflow.add_conditional_edges("agent", should_continue)
workflow.add_edge("tools", "agent")

app = workflow.compile()

Directed Graph + 상태 머신 모델. 복잡한 에이전트 흐름에 이상적.

7.3 Pydantic AI (2024~)

Pydantic 팀이 만든 타입 안전 에이전트 프레임워크. 경량·직관적.

from pydantic_ai import Agent
from pydantic import BaseModel

class WeatherResponse(BaseModel):
    city: str
    temp_c: float
    condition: str

agent = Agent(
    'openai:gpt-4o',
    result_type=WeatherResponse,
    system_prompt='You are a weather assistant.',
)

result = await agent.run('Weather in Seoul?')
print(result.data)  # WeatherResponse 타입

7.4 2025년 AI 스택 추천

상황추천
복잡한 멀티스텝 에이전트LangGraph
간단한 타입 안전 에이전트Pydantic AI
RAG 특화LlamaIndex
프로덕션 최소 의존성OpenAI SDK 직접
TS 팀과 협업Vercel AI SDK (TS) 매치

8부 — Modern Python 개발 환경

8.1 도구 체인 (2025 표준)

# pyproject.toml
[project]
name = "my-app"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "fastapi>=0.115",
    "pydantic>=2.9",
    "uvicorn>=0.30",
]

[dependency-groups]
dev = [
    "pytest>=8",
    "ruff>=0.7",
    "mypy>=1.13",
]

[tool.ruff]
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP", "B", "S", "C4", "PL"]

[tool.mypy]
strict = true

8.2 Ruff — 10~100배 빠른 린터/포매터

  • Flake8, Black, isort, pyupgrade, pylint 대체
  • Rust 작성
  • 800+ 규칙 내장

8.3 타입 체커 선택

도구특징
mypy가장 오래됨, 느림, 보수적
pyrightMS 제작, 빠름, 엄격
pyreMeta 제작, 서버 모드
tyAstral 제작 (2025), Rust 기반 (개발 중)

2025년 추천: 신규는 pyright, 기존은 mypy 유지. ty 출시 기다리는 중.

8.4 테스트

# pytest + httpx for FastAPI
import pytest
from httpx import AsyncClient, ASGITransport
from myapp.main import app

@pytest.mark.asyncio
async def test_create_user():
    async with AsyncClient(
        transport=ASGITransport(app=app), base_url="http://test"
    ) as ac:
        r = await ac.post("/users", json={"email": "a@b.com", "password": "pw"})
        assert r.status_code == 200

9부 — Python이 빛나는 분야 vs 빛나지 않는 분야

9.1 빛남

  • AI/ML: PyTorch, JAX, scikit-learn, Hugging Face
  • 데이터 엔지니어링: Airflow, dbt, Dagster
  • API 서버: FastAPI의 생산성
  • 과학 컴퓨팅: NumPy, SciPy
  • 스크립팅/자동화: 글루 언어
  • 교육: 학습 곡선 낮음

9.2 빛나지 않음

  • CPU 바운드 고성능: Rust/Go/C++
  • 모바일 앱: Swift/Kotlin
  • 임베디드: C/Rust
  • 게임 엔진: C++
  • 브라우저: JS/TS (Pyodide는 특수 용도)

2025년 현실: Python은 "AI·데이터·API"의 표준이지만, "모든 것을 위한" 언어는 아니다.


10부 — Python 마스터 로드맵 6개월

Month 1: 3.13 기본기

  • 타입 힌트 완전 이해 (PEP 695, Union, Literal, Protocol)
  • uv로 프로젝트 관리
  • Ruff + mypy/pyright 설정

Month 2: Pydantic + FastAPI

  • Pydantic v2 심화 (Annotated, Validators)
  • FastAPI 실전 API 만들기
  • Dependency Injection 패턴

Month 3: AsyncIO

  • TaskGroup, asyncio.timeout
  • httpx·asyncpg 비동기 DB
  • 동시성 제한 (Semaphore)

Month 4: 데이터 처리

  • Polars 마스터
  • SQL + SQLAlchemy 2.0 async
  • DuckDB + Parquet

Month 5: AI 엔지니어링

  • OpenAI/Anthropic SDK
  • LangGraph 또는 Pydantic AI
  • Vector DB (Qdrant, Pinecone, pgvector)
  • RAG 파이프라인 구축

Month 6: 운영

  • Docker + Kubernetes 배포
  • 관측성 (OpenTelemetry, Prometheus)
  • CI/CD (GitHub Actions)
  • 프로파일링 (py-spy, scalene)

11부 — Python 체크리스트 12

  1. uv의 4가지 대체 도구(pip/poetry/pyenv/pip-tools)를 안다
  2. Pydantic v1 vs v2 주요 변화를 안다
  3. FastAPI Dependency Injection 사용법을 안다
  4. TaskGroup vs asyncio.gather 차이를 안다
  5. Polars Lazy Evaluation의 장점을 안다
  6. 타입 힌트 Protocol, TypeIs 사용법을 안다
  7. SQLAlchemy 2.0 async 스타일을 안다
  8. GIL과 Free-threading의 의미를 안다
  9. LangGraph와 LangChain의 관계를 안다
  10. Ruff가 대체하는 도구들을 안다
  11. Pydantic Settings로 설정 관리를 할 수 있다
  12. pytest + httpx로 async API 테스트를 쓸 수 있다

12부 — Python 안티패턴 10

  1. pip install + requirements.txt만 사용: 재현성 취약. uv + uv.lock
  2. 타입 힌트 없이 Python 코드 작성: mypy/pyright로 잡힐 버그 방치
  3. from X import *: 네임스페이스 오염
  4. print()로 디버깅: logging 또는 rich
  5. except Exception: pass: 조용히 실패. 구체 예외 + 로깅
  6. 뮤터블 기본 인자: def f(x=[]): → 공유됨. x=Nonex or []
  7. Pandas에서 iterrows: 느림. 벡터 연산 또는 Polars
  8. Sync 라이브러리를 async 함수에서: 이벤트 루프 블록
  9. os.path 대신 pathlib를 안 씀: pathlib 훨씬 깔끔
  10. 도커 이미지에 pip install -r requirements.txt: layer caching 망침. uv sync --frozen

마치며 — Python은 AI 시대에 다시 태어났다

Python의 원래 강점은 "생산성과 학습 곡선"이었다. 단점은 "속도와 동시성"이었다.

2024~2025년:

  • 속도: uv·Pydantic·Polars·Ruff가 Rust 엔진으로 해결
  • 동시성: Free-threading 실험, AsyncIO 성숙
  • 타입: 3.12~3.13의 PEP들로 강력해짐
  • 생태계: AI 엔지니어링의 표준 언어

"Python이 느리다"는 2020년까지의 이야기였다. 2025년 Python은 **"AI 시대의 공용어이자, Rust 도구들로 빨라진 언어"**다.

시니어 엔지니어가 Python을 안 다룰 수 없는 이유는 명확하다. AI·데이터·API·스크립팅에서 Python은 여전히, 그리고 앞으로도 지배적이다.


다음 글 예고 — "LLM 완전 가이드: Transformer·Attention·RLHF·RAG·Agent·Evaluation"

Season 2 Ep 6은 2025년 엔지니어의 교양, LLM의 내부 구조. 다음 글은:

  • Transformer가 실제로 어떻게 동작하는가
  • Attention 메커니즘 수식까지
  • Pre-training → SFT → RLHF → DPO 흐름
  • RAG의 3세대 진화 (Naive → Advanced → Agentic)
  • Agent 설계 (ReAct, Plan-and-Execute, Multi-Agent)
  • LLM 평가의 진짜 어려움 (LM-as-a-Judge의 한계)

블랙박스를 뜯어보는 시간, 다음 글에서 이어진다.