Python 프로그래밍 — 일반 접근법
이 문서는 마스터 Python 참조 스킬입니다. 이 프로젝트의 모든 Python 코드에 걸쳐 적용되는 비협상 가능한 기본값과 '함수형-라이트' 철학을 담고 있습니다. 이 문서를 먼저 읽고, 더 깊은 지침이 필요하면 연결된 도메인 스킬을 참조하세요.
핵심 스택
| 영역 | 선택 |
|---|---|
| 패키지 관리자 및 태스크 러너 | uv |
| 패키징 매니페스트 | pyproject.toml만 사용 |
| 린터 / 포맷터 | ruff |
| 타입 체커 | ty |
| 데이터 처리 라이브러리 | polars (pandas 아님) |
| 백엔드 프레임워크 | FastAPI |
| 데이터베이스 | PostgreSQL |
| ORM | SQLAlchemy (비동기) |
| 마이그레이션 | Alembic |
| 런타임 모델 | asyncio — 항상 비동기 |
| 프로그래밍 스타일 | 함수형-라이트 |
패키지 관리 — 항상 uv
절대 pip, pip-tools, poetry 또는 pipenv를 직접 사용하지 마십시오.
모든 설치, 실행 및 스크립팅은 uv와 그 기본 명령어를 사용합니다.
# 의존성 설치
uv sync
# 의존성 추가
uv add <package>
# 개발 의존성 추가
uv add --dev <package>
# 스크립트 또는 모듈 실행
uv run python script.py
uv run alembic upgrade head
uv run pytest
# 의존성 업그레이드
uv lock --upgrade
재현 가능한 빌드를 위해 모든 프로덕션 의존성은 ==로 고정하십시오.
의존성 관리를 위해 requirements.txt, requirements-dev.txt 또는 requirements 디렉토리를 사용하지 마십시오. 모든 패키지 메타데이터와 의존성 구성은 pyproject.toml에 속합니다.
패키지, 도구 또는 빌드와 관련된 모든 작업에는 uv를 사용하십시오. 이 프로젝트에서 pip, pip install, python -m pip, poetry 또는 pipenv를 직접 실행하지 마십시오.
전체 업그레이드 워크플로는 upgrade-dependencies 스킬을 참조하세요:
.github/skills/upgrade-dependencies/SKILL.md
라이브러리별 지침은 .github/skills/python-library-creation/SKILL.md를 참조하세요.
린팅 및 포맷팅 — Astral 스택 필수
이 저장소의 Python 프로젝트에는 Astral 스택이 필수입니다. ruff는 표준 린터이자 포맷터입니다.
ruff를 개발 의존성으로 추가:uv add --dev ruffuv run ruff format을 사용하여 코드를 포맷합니다.uv run ruff check --fix를 사용하여 린팅을 실행하고 가능한 경우 문제를 자동으로 수정합니다.- 프로젝트 스크립트나 README에 이러한 명령어를 문서화하십시오.
ruff는 코드, 테스트 및 구성 전반에 걸친 포맷팅 및 스타일 일관성의 단일 진실 공급원입니다.
타입 체킹 — ty 선호
타입 어노테이션은 필수입니다. ty는 이 저장소의 선호 타입 체커입니다.
ty를 개발 의존성으로 추가:uv add --dev tyuv run ty check로 타입 체크를 실행합니다.uv run --with ty ty check를 사용하여 동작을 비교하려는 경우 툴체인을 검증합니다.
저장소는 mypy나 pyrefly와 같은 다른 체커를 실험할 수도 있지만, ty가 선호되는 기본 체커이며 CI에서 적용되어야 합니다.
데이터 처리 — Polars vs DuckDB
이 저장소는 프로세스 내 데이터 엔지니어링에는 polars를, SQL 우선 분석 및 대용량 파일 쿼리에는 DuckDB를 선호합니다.
-
Polars 사용 시기 (에이전트가 Speedster 역할을 할 때):
- Rust 기반, 단일 머신에서 멀티스레드 DataFrame 처리.
- 복잡한 파이프라인 체이닝, 특징 엔지니어링, 조인, 윈도우 함수 및 프로그래매틱 변환에 최적.
- 처리량과 계산 속도를 우선시하며, 더 엄격한 스키마 및 타입 안전성을 제공.
- 모델 전처리 및 Python ML 도구와의 통합에 탁월.
-
DuckDB 사용 시기 (에이전트가 Librarian 역할을 할 때):
- 분석적 OLAP 쿼리에 최적화된 프로세스 내 SQL 데이터베이스.
- SQL 우선 접근 방식이 자연어를 코드로 변환하는 데 더 안정적.
- 메모리 제약이 있는 워크로드에 더 적합: DuckDB는 엄격한 메모리 제한을 적용하고 매우 큰 데이터셋을 안전하게 쿼리 가능.
- S3 또는 Google Cloud의 원격 파일을 URL을 통해 직접 쿼리하는 제로 ETL 클라우드 쿼리에 이상적.
결정 휴리스틱
작업이 다음과 같은 경우:
- 새 파일이나 클라우드 스토리지 탐색 → DuckDB
- 직접 파일 스캔 및 SQL 탐색에 최적.
- 대규모 데이터셋 필터링 또는 정렬 → Polars
- 단일 노드에서 원시 필터링 및 로딩 속도에서 종종 우세.
- 협업 또는 핸드오프 → DuckDB
- SQL은 사람과 에이전트 모두가 유지 관리하고 디버그하기 더 쉬움.
- 모델 전처리 → Polars
- Python ML 도구 및 스키마 안전 파이프라인과의 통합이 더 우수.
백엔드 — FastAPI
FastAPI는 유일하게 지원되는 백엔드 프레임워크입니다. 주요 규칙:
- 항상
async def를 라우트 핸들러와 의존성에 사용하십시오. - 모든 요청/응답 형태에 Pydantic v2 모델을 사용하십시오.
Depends()를 사용하여 의존성을 선언하십시오 — 핸들러 내부에서 전역 상태에 접근하지 마십시오.- 타입이 지정된 응답 모델을 반환하십시오. 라우트 핸들러에서 원시 딕셔너리를 절대 반환하지 마십시오.
- 라우터는 자체 모듈에 있습니다.
main.py는 라우터를 마운트하고 미들웨어를 구성만 합니다.
# ✅ 올바른 패턴
@router.get("/items/{item_id}", response_model=ItemResponse)
async def get_item(item_id: int, db: AsyncSession = Depends(get_db)) -> ItemResponse:
return await item_service.get(db, item_id)
구조화, 테스트, 보안 및 OpenAPI 문서화에 대해서는 FastAPI 도메인 스킬을 참조하세요:
.github/skills/python-fastapi-project-structuring/SKILL.md.github/skills/python-fastapi-routing-validation/SKILL.md.github/skills/python-fastapi-dependency-injection/SKILL.md.github/skills/python-fastapi-response-error-handling/SKILL.md.github/skills/python-fastapi-security-authentication/SKILL.md.github/skills/python-fastapi-security-attack-resistance/SKILL.md.github/skills/python-fastapi-api-testing/SKILL.md.github/skills/python-fastapi-openapi-documentation/SKILL.md
데이터베이스 — PostgreSQL + SQLAlchemy (비동기)
PostgreSQL은 유일하게 지원되는 데이터베이스입니다. SQLAlchemy가 ORM입니다.
- 항상 비동기 엔진과 세션을 사용하십시오 (
AsyncEngine,AsyncSession). - 비동기 코드에서 동기 SQLAlchemy API를 호출하지 마십시오.
sqlalchemy에서select(),insert(),update(),delete()를 사용하십시오 — 원시 SQL 문자열을 사용하지 마십시오.async with AsyncSession(engine) as session으로 세션 수명 주기를 관리하십시오.DeclarativeBase로 모델을 정의하고,Mapped[T]타입 컬럼 어노테이션을 사용하십시오 (SQLAlchemy 2.x 스타일).
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
engine = create_async_engine("postgresql+asyncpg://...", echo=False)
class Base(DeclarativeBase):
pass
class Item(Base):
__tablename__ = "items"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
데이터베이스 마이그레이션 — Alembic
Alembic은 모든 스키마 변경을 관리합니다. 데이터베이스 스키마를 수동으로 변경하지 마십시오.
주요 규칙:
- 마이그레이션은 로컬이 아닌 환경에 한 번 적용되면 변경 불가능합니다.
- 가능한 경우 모든 마이그레이션은 **멱등성(idempotent)**을 가져야 합니다.
- 모든 Alembic 명령어에는
uv run alembic을 사용하십시오.
uv run alembic revision --autogenerate -m "add_items_table"
uv run alembic upgrade head
uv run alembic history
uv run alembic current
전체 마이그레이션 작성 규칙 및 RLS 적용에 대해서는 다음을 참조하세요:
.github/skills/python-alembic-migrations/SKILL.md
로컬 전용 마이그레이션 브랜치 리베이스에 대해서는 다음을 참조하세요:
.github/skills/python-alembic-migration-rebase/SKILL.md
비동기 — 항상
모든 I/O 작업은 반드시 비동기여야 합니다. 요청 경로에 블로킹 호출이 있어서는 안 됩니다.
- 동시 독립 코루틴에는
asyncio.gather()를 사용하십시오. - 구조적 동시성과 오류 전파가 중요할 때는
asyncio.TaskGroup(Python 3.11+)을 사용하십시오. - 백프레셔 및 속도 제한에는
asyncio.Queue또는asyncio.Semaphore를 사용하십시오. time.sleep()을 호출하지 마십시오 —await asyncio.sleep()을 사용하십시오.requests를 사용하지 마십시오 —httpx.AsyncClient또는aiohttp를 사용하십시오.
더 깊은 지침:
.github/skills/python-asyncio/asyncio-concurrent-web-requests/SKILL.md.github/skills/python-concurrent-processing/SKILL.md(CPU 바인딩 작업 →ProcessPoolExecutor+ asyncio 통합).github/skills/python-asyncio/asyncio-synchronization/SKILL.md
함수형-라이트 스타일
코드베이스는 '함수형-라이트' 접근 방식을 사용합니다: 함수형 기법을 복잡성을 줄이고 명확성을 향상시키는 경우에 적용하되, 이론적 순수성을 위해 강제하지는 않습니다.
우리가 하는 것
| 기법 | 사용 시기 |
|---|---|
| 순수 함수 | 비즈니스 로직의 기본값. 필요하지 않으면 부작용 없음. |
| 불변 데이터 | 값 객체에는 frozen dataclass / Pydantic 모델을 사용. |
| 고차 함수 | 데이터 파이프라인에서는 명령형 루프보다 map, filter, functools.reduce 선호. |
| 제너레이터 / 지연 시퀀스 | 대용량 또는 스트리밍 데이터셋 — 메모리에 전체 리스트를 구축하지 않음. |
functools 유틸리티 | lru_cache, cache, partial, wraps — 자유롭게 사용. |
| 함수 합성 | 데이터 변환 파이프라인에서 작고 집중된 함수를 체이닝. |
| 설명적 데코레이터 | 횡단 관심사(인증, 캐싱, 재시도)를 데코레이터로 표현. |
우리가 강제하지 않는 것
| 기법 | 명확한 이점이 없는 한 피해야 하는 이유 |
|---|---|
모나드 (Maybe, Either, Result) | 인지 오버헤드 증가; 예외 + 타입 반환을 대신 사용. |
| 포인트-프리 스타일 | 대부분의 팀원에게 가독성 저하. |
| 모든 곳에 엄격한 불변성 | SQLAlchemy 모델과 비동기 상태는 본질적으로 가변적임 — 필요한 곳에서만 싸울 것. |
pymonad / returns 라이브러리 | 옵트인만 허용; 팀 동의 없이 공유 코드에 강제하지 않음. |
# ✅ 함수형-라이트: 집중된 순수 함수의 파이프라인
from functools import reduce
def parse_items(raw: list[dict]) -> list[Item]:
return [Item(**r) for r in raw if r.get("active")]
def enrich(item: Item, overrides: dict) -> Item:
return item.model_copy(update=overrides.get(item.id, {}))
def process(raw: list[dict], overrides: dict) -> list[Item]:
return [enrich(item, overrides) for item in parse_items(raw)]
더 깊은 지침 — 통합 및 특화 함수형 스킬:
.github/skills/python-higher-order-functools/SKILL.md(map, filter, max/min, @cache, partial, reduce, @singledispatch).github/skills/python-lazy-evaluation-pipelines/SKILL.md(yield, yield from, generator pipelines, map/filter/reduce).github/skills/python-immutable-data-design/SKILL.md(NamedTuple, frozen dataclass, pyrsistent, context managers).github/skills/python-functional-programming/python-decorator-design/SKILL.md.github/skills/python-functional-programming/python-functional-web-services/SKILL.md(FastAPI functional handlers).github/skills/python-functional-programming/python-toolz-composition/SKILL.md.github/skills/python-functional-programming/python-itertools-combinatorics/SKILL.md.github/skills/python-functional-programming/python-recursion-tco/SKILL.md.github/skills/python-functional-programming/python-pymonad-strict-evaluation/SKILL.md← opt-in only
일반 코드 규칙
- Python 3.11+ 최소. 최신 문법 사용:
match,TypeAlias,Self등. - 모든 것에 타입 어노테이션 — 함수 시그니처, 변수, 반환 타입.
- 타입이 지정되지 않은 타사 경계와 통합하지 않는 한
Any사용 금지. - 값 객체에는
dataclass(frozen=True)또는 PydanticBaseModel선호. - 함수를 작고 단일 목적으로 유지. 함수가 무엇을 하는지(이유가 아니라) 설명하는 주석이 필요하면 분할.
- 전역 가변 상태를 피하십시오. 의존성을 명시적으로 전달(생성자 또는
Depends()). logging사용 —print아님. 앱 시작 시 구성; 라이브러리 코드 내에서basicConfig()호출 금지. 전체 로깅, 추적 및 구성 지침은.github/skills/python-configuration-observability/SKILL.md참조.
스킬 지도
python/SKILL.md ← 현재 위치 (마스터 참조)
│
├── 백엔드 프레임워크
│ ├── python-fastapi-project-structuring/SKILL.md
│ ├── python-fastapi-routing-validation/SKILL.md
│ ├── python-fastapi-dependency-injection/SKILL.md
│ ├── python-fastapi-response-error-handling/SKILL.md
│ ├── python-fastapi-security-authentication/SKILL.md
│ ├── python-fastapi-security-attack-resistance/SKILL.md
│ ├── python-fastapi-api-testing/SKILL.md
│ └── python-fastapi-openapi-documentation/SKILL.md
│
├── 데이터베이스 및 마이그레이션
│ ├── python-alembic-migrations/SKILL.md
│ └── python-alembic-migration-rebase/SKILL.md
│
├── 비동기 패턴
│ ├── python-asyncio/asyncio-concurrent-web-requests/SKILL.md
│ └── python-asyncio/asyncio-synchronization/SKILL.md
│
├── 통합 핵심 스킬
│ ├── python-configuration-observability/SKILL.md (구성 + 로깅 + 추적)
│ ├── python-data-structures-type-system/SKILL.md (컬렉션 + 타입 + Pydantic)
│ ├── python-lazy-evaluation-pipelines/SKILL.md (제너레이터 + map/filter/reduce)
│ ├── python-higher-order-functools/SKILL.md (HOF + cache + partial + singledispatch)
│ ├── python-immutable-data-design/SKILL.md (NamedTuple + frozen DC + context mgrs)
│ └── python-concurrent-processing/SKILL.md (ProcessPool + asyncio 통합)
│
├── 함수형 프로그래밍 (전문화)
│ ├── python-functional-programming/python-decorator-design/SKILL.md
│ ├── python-functional-programming/python-functional-web-services/SKILL.md
│ ├── python-functional-programming/python-toolz-composition/SKILL.md
│ ├── python-functional-programming/python-itertools-combinatorics/SKILL.md
│ ├── python-functional-programming/python-recursion-tco/SKILL.md
│ └── python-functional-programming/python-pymonad-strict-evaluation/SKILL.md ← 옵트인
│
├── 라이브러리 생성
│ ├── python-library-creation/SKILL.md
│ └── python-project-setup/SKILL.md
│
├── Polars
│ ├── python-polars-dataframe-refactoring/SKILL.md
│ ├── python-polars-join-aggregate-window/SKILL.md
│ ├── python-polars-expression-api/SKILL.md
│ ├── python-polars-performance-tuning/SKILL.md
│ ├── python-polars-lazyframe-optimization/SKILL.md
│ ├── python-polars-streaming-queries/SKILL.md
│ └── python-polars-integration-ml/SKILL.md
│
├── DuckDB
│ ├── python-duckdb-sql-analytics/SKILL.md
│ ├── python-duckdb-parquet-query/SKILL.md
│ ├── python-duckdb-memory-optimization/SKILL.md
│ └── python-duckdb-etl-pipeline/SKILL.md
│
├── 테스트
│ ├── python-testing-pytest/SKILL.md
│ ├── python-testing-mocking/SKILL.md
│ ├── python-testing-property-based/SKILL.md
│ └── python-testing-integration/SKILL.md
│
├── DevOps & 인프라
│ ├── python-ci-cd-setup/SKILL.md
│ ├── python-containerization-docker/SKILL.md
│ └── python-observability-monitoring/SKILL.md
│
└── 보안
├── python-security-best-practices/SKILL.md
└── python-secrets-management/SKILL.md