2026년 7월 21일 화요일

초고속 파이썬 패키지 관리 도구인 uv를 사용하여 FastAPI 개발 환경을 구성하는 방법입니다. 아래 단계를 순서대로 실행하세요.



# uv

초고속 파이썬 패키지 관리 도구인 uv를 사용하여 FastAPI 개발 환경을 구성하는 방법입니다. 아래 단계를 순서대로 실행하세요.

---

### 1. uv 설치하기

먼저 터미널(또는 명령 프롬프트)을 열고 시스템 환경에 맞는 명령어를 입력해 uv 공식 툴을 설치합니다.

* Windows (PowerShell):

```bash
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

* macOS / Linux:

```bash
curl -LsSf https://astral.sh | sh
```

설치 후 터미널을 재시작하고 버전을 확인합니다.

```bash
uv --version
```

### 2. 프로젝트 초기화 및 Python 버전 지정

프로젝트를 진행할 디렉터리를 만들고 uv init으로 파이썬 프로젝트를 초기화합니다. 특정 파이썬 버전을 지정해 가상 환경을 함께 구성할 수 있습니다.

```bash
# 프로젝트 디렉터리 생성 및 이동
mkdir fastapi-app
cd fastapi-app

# 파이썬 3.12 기반으로 프로젝트 초기화 (가상환경 자동 구성 준비)
uv init --python 3.12
```

```bash
# reset
rm -rf .venv
uv sync --python 3.14
```

### 3. 패키지 추가 (fastapi 표준 팩)

fastapi dev 명령어를 사용하려면 fastapi 패키지 설치 시 관련 CLI 도구들이 함께 포함되어야 합니다. uv로 한 번에 설치합니다.

```bash
uv add fastapi --extra standard
```

```toml
#pyproject.toml
[project]
name = "my-api"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
  "fastapi[standard]>=0.138.0",
  "google-api-python-client>=2.197.0",
  "google-auth-httplib2>=0.4.0",
  "google-auth-oauthlib>=1.4.0",
  "httpx>=0.28.1",
  "jinja2>=3.1.6",
  "maturin>=1.14.1",
  "pydantic-settings>=2.14.2",
  "pyjwt>=2.13.0",
  "python-multipart>=0.0.32",
  "requests>=2.34.2",
  "sqlalchemy>=2.0.51",
  "uvicorn>=0.49.0",
]

[dependency-groups]
dev = [
    "djlint>=1.40.2",
    "poethepoet>=0.47.1",
    "pytest>=9.1.1",
    "pytest-asyncio>=1.4.0",
    "ruff>=0.15.18",
]

# 💡 실행 단축키(스크립트) 등록 구역
[project.scripts]
```

```bash
# jwt
uv add pyjwt
```

### 4. 웹 서버 코드 작성

프로젝트 루트 디렉터리에 main.py 파일을 생성하고 아래 코드를 입력합니다.

```python
# app/main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI with uv run!"}
```

### 5. uv run fastapi dev 서버 실행

가상환경 활성화 없이 아래 명령어를 터미널에 입력하면 즉시 개발 서버가 시작됩니다.

```bash
uv run fastapi dev app/main.py
uv run fastapi run app/main.py --host 0.0.0.0 --port 8000
```

* 자동 감지: 파일명을 생략하고 uv run fastapi dev만 입력해도 폴더 내 main.py를 자동으로 찾아 실행합니다.
* 핫 리로드: 코드를 수정하고 저장하면 서버가 자동으로 재시작됩니다.
* 접속 주소: 브라우저에서 [http://127.0.0.1:8000](http://127.0.0.1:8000) 으로 접속하여 결과를 확인합니다.
* API 문서: [http://127.0.0.1:8000/doc](http://127.0.0.1:8000/doc) 에서 대화형 API 테스트가 가능합니다.

---

## poe

파이썬 프로젝트에서 poe는 보통 복잡한 CLI 명령어를 npm run처럼 짧은 스크립트로 단축해 주는 작업 실행기(Task Runner)인 Poe the Poet을 의미합니다.
기존 uv run fastapi dev 명령어를 더 간결하게 자동화할 수 있도록 Poe the Poet 설정을 추가한 전체 가이드입니다.

---

### 1. Poe the Poet 패키지 설치

uv add 명령어로 개발용 의존성(--dev)에 poethepoet 패키지를 추가합니다.

```bash
uv add --dev poethepoet
```

### 2. pyproject.toml에 단축 명령어(Task) 등록

프로젝트 루트 폴더에 있는 pyproject.toml 파일을 열고, 맨 아래에 다음과 같이 [tool.poe.tasks]

```toml
# pyproject.toml 맨 아래에 추가

[tool.poe.tasks]
# 1. 🛠️ 로컬 개발 및 테스트용 (질문하신 현재 설정)
dev = "fastapi dev app/main.py --host 0.0.0.0 --port 8000"

# 2. 🚀 실제 프로덕션 운영 서버 배포용
# 'run'이나 'prod' 명령을 실행하면 리로드가 꺼지고 보안이 강화된 Production 모드로 돕니다.
prod = "fastapi run app/main.py --host 0.0.0.0 --port 8000"
```

### 3. 단축 명령어로 서버 구동하기

이제 길게 입력할 필요 없이 uv run poe <명령어> 형태로 간단하게 서버를 켤 수 있습니다.

* 개발 서버 실행 (fastapi dev 자동 호출):

```bash
uv run poe dev
```

* 프로덕션 서버 실행 (fastapi run 자동 호출):

```bash
uv run poe prod
```

---

## vscode

```bash
#
uv add --dev djlint ruff
```

```toml
# pyproject.toml 맨 아래 또는 적절한 위치에 추가
[tool.ruff]
# 👇 줄이 너무 길다는 에러 경고(E501)를 완전히 무시하도록 설정 추가
ignore = ["E501"]
line-length = 120  # 💡 파이썬 코드가 가로로 너무 길어지면 자동으로 엔터 쳐서 정렬해라

# 🔥 Ruff 0.15.x 엔진에게 무조건 2칸 공백으로 줄을 맞추라고 지시
indent-width = 2

# 저장 시 자동으로 import 순서 정렬 및 미사용 import 제거
fix = true

# 검사할 규칙 (E: 에러, F: 파이썬 오류, I: 임포트 정렬)
select = ["E", "F", "I"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

[tool.ruff.lint.per-file-ignores]
# 💡 main.py 파일에 한해서는 안 쓰는 import가 있어도 ruff가 강제로 지우지 못하게 막습니다.
#from app.core.utils import logger  # noqa: F401
"app/main.py" = ["F401", "E402"]

# pyproject.toml 예시
[tool.djlint]
profile = "jinja"  # 진자 문법 기준으로 검사
ignore = "H023,H017,H014"  # 보기 싫은 경고 코드들 제외

# 🔥 핵심: 빈 줄이나 복잡한 구문에서도 들여쓰기 줄(인덴트)을 강제로 맞춰주는 옵션
#skip-magic-trailing-comma = false

```

> error check

```bash
uv run ruff check
```

---

## rust python

Rust로 고성능 로직을 작성하고 이를 파이썬에서 패키지처럼 불러와 사용하는 방법입니다.파이썬의 C 확장 모듈을 쉽고 안전하게 만들 수 있는 툴킷인 PyO3와, uv 및 pyproject.toml 생태계와 완벽하게 호환되는 빌드 툴인 maturin을 사용하여 빌드 환경을 구축합니다.

---

### 1. maturin 개발 패키지 추가

uv 환경에서 Rust 바인딩 모듈을 컴파일하고 관리하기 위해 개발 의존성에 maturin을 추가합니다.

```bash
uv add maturin requests

# 파이썬 비동기 테스트를 위해 httpx 또는 asyncio 설치 (asyncio는 내장)
```

### 2. Rust 설치하기

```bash
curl https://sh.rustup.rs -sSf | sh -s
```


### 3. Cargo (Rust) 프로젝트 초기화 및 설정

파이썬 프로젝트 루트 디렉터리 내부에 Rust 라이브러리를 생성합니다. 여기서는 모듈 이름을 my_rust_module로 지정하겠습니다.

```bash
# Rust 라이브러리 프로젝트 생성
cargo init --lib rust_curl
```

그 다음, 생성된 my_rust_module/Cargo.toml 파일을 열어 PyO3 의존성과 라이브러리 타입(cdylib)을 지정해 줍니다.

```toml
# Cargo.toml
[package]
name = "rust_curl"
version = "0.1.0"
edition = "2021"

[lib]
name = "rust_curl"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.29", features = ["extension-module","experimental-inspect"] }
pyo3-async-runtimes = { version = "0.29", features = ["tokio-runtime"] }
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json"] }
```

### 4. Rust 코드 작성

my_rust_module/src/lib.rs 파일을 열고 파이썬에서 호출할 연산 함수와 모듈 정의 코드를 작성합니다.

```rust
// src/lib.rs
use pyo3::prelude::*;

/// Rust에서 실행되는 고성능 더하기 함수
#[pyfunction]
fn add_in_rust(a: i64, b: i64) -> PyResult {
    Ok(a + b)
}

/// 파이썬 모듈 구조 정의 (함수 등록)
#[pymodule]
fn my_rust_module(m: &Bound<'_, PyModule>) -> PyResult<()> {
    m.add_function(wrap_pyfunction!(add_in_rust, m)?)?;
    Ok(())
}
```

### 5. pyproject.toml에 maturin 빌드 설정 연동

기존 파이썬 프로젝트 루트의 pyproject.toml에 Maturin을 빌드 백엔드로 인식시키고, Rust 프로젝트의 위치를 명시합니다.

```toml
# pyproject.toml 맨 아래 또는 적절한 위치에 추가

[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"
```

```bash
#.bashrc
export UV_LINK_MODE=copy

uv run maturin develop
uv run maturin develop --generate-stubs
```

### 6. poe 단축 명령어로 Rust 빌드 자동화

코드가 수정될 때마다 편리하게 Rust를 컴파일하고 가상환경에 설치할 수 있도록, 이전 단계에서 설정한 Poe the Poet에 빌드 명령어를 등록합니다.

```toml
# pyproject.toml 의 [tool.poe.tasks] 섹션에 추가

[tool.poe.tasks]
# 1. 러스트 개발 빌드 (Maturin develop)
build = "maturin develop"

# 2. 러스트 빌드 + 타입 스텁 자동 생성 (빨간줄 제거용)
# 파이썬 경로 인식을 위해 명시적으로 가상환경 내 maturin을 지정합니다.
stubs = "maturin develop --generate-stubs"

# 3. 파이썬 메인 스크립트 실행
run = "python main.py"

# 4. 일체형 명령어 (빌드하고 바로 실행하기)
# 빌드(build) 태스크를 먼저 실행한 뒤 run 태스크를 이어 달립니다.
start = ["build", "run"]
```

터미널에 다음 명령어를 입력하면 Rust 코드가 빌드되어 파이썬 환경에 연동됩니다.

```bash
uv run poe build
```

### 7. FastAPI (main.py)에서 불러와 사용하기

이제 파이썬 코드에서 일반 모듈을 가져오듯 import하여 사용할 수 있습니다.

```python
# main.py
from fastapi import FastAPI
# 빌드된 Rust 모듈 임포트
import rust_curl

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello, FastAPI with uv run!"}

@app.get("/rust-add")
def rust_add(a: int = 10, b: int = 20):
    # Rust 내부 함수 호출 및 연산 실행
    result = my_rust_module.add_in_rust(a, b)
    return {
        "engine": "Rust (PyO3)",
        "result": result
    }
```

---

## pytest

```bash
uv add --dev pytest pytest-asyncio
uv add httpx
```

> pytest가 test_main.py를 자동으로 찾아내어 가상의 웹 서버를 띄우고, 엔드포인트를 때린 뒤, 내부에서 러스트 비동기 코드가 구글 시트나 외부 API를 긁어오는 전 과정을 단 1초 만에 검증하고 종료합니다.
> 💡 FastAPI 테스트 꿀팁
> 진짜 서버를 띄우지 않음: ASGITransport(app=app) 방식은 네트워크 포트(예: 8000번)를 실제로 열지 않고, 메모리 내부에서 FastAPI의 라우팅 유닛을 직접 호출하기 때문에 테스트 속도가 무지막지하게 빠릅니다.
> pytest 기능 분리: 만약 파일이 많아지면 pytest -v test_main.py 처럼 특정 파일만 지정해서 테스트할 수도 있습니다.

```toml
# pyproject.toml 맨 아래에 추가
[tool.poe.tasks]
# 테스트 실행 전 항상 러스트를 최신으로 빌드하도록 설정
test = "pytest -v"
```

---

```toml
# pyproject.toml
[project]
name = "my-api"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
  "fastapi[standard]>=0.138.0",
  "google-api-python-client>=2.197.0",
  "google-auth-httplib2>=0.4.0",
  "google-auth-oauthlib>=1.4.0",
  "httpx>=0.28.1",
  "jinja2>=3.1.6",
  "maturin>=1.14.1",
  "pydantic-settings>=2.14.2",
  "pyjwt>=2.13.0",
  "python-multipart>=0.0.32",
  "requests>=2.34.2",
  "sqlalchemy>=2.0.51",
  "uvicorn>=0.49.0",
]

[dependency-groups]
dev = [
    "djlint>=1.40.2",
    "poethepoet>=0.47.1",
    "pytest>=9.1.1",
    "pytest-asyncio>=1.4.0",
    "ruff>=0.15.18",
]

# 💡 실행 단축키(스크립트) 등록 구역
[project.scripts]

[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"

[tool.ruff]
# 👇 줄이 너무 길다는 에러 경고(E501)를 완전히 무시하도록 설정 추가
ignore = ["E501"]
line-length = 120  # 💡 파이썬 코드가 가로로 너무 길어지면 자동으로 엔터 쳐서 정렬해라

# 🔥 Ruff 0.15.x 엔진에게 무조건 2칸 공백으로 줄을 맞추라고 지시
indent-width = 2

# 저장 시 자동으로 import 순서 정렬 및 미사용 import 제거
fix = true

# 검사할 규칙 (E: 에러, F: 파이썬 오류, I: 임포트 정렬)
select = ["E", "F", "I"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

[tool.ruff.lint.per-file-ignores]
# 💡 main.py 파일에 한해서는 안 쓰는 import가 있어도 ruff가 강제로 지우지 못하게 막습니다.
#from app.core.utils import logger  # noqa: F401
"app/main.py" = ["F401", "E402"]

# pyproject.toml 예시
[tool.djlint]
profile = "jinja"  # 진자 문법 기준으로 검사
ignore = "H023,H017,H014"  # 보기 싫은 경고 코드들 제외

# 🔥 핵심: 빈 줄이나 복잡한 구문에서도 들여쓰기 줄(인덴트)을 강제로 맞춰주는 옵션
#skip-magic-trailing-comma = false

[tool.poe.tasks]
# 1. 🛠️ 로컬 개발 및 테스트용 (질문하신 현재 설정)
dev = "fastapi dev app/main.py --host 0.0.0.0 --port 8000"

# 2. 🚀 실제 프로덕션 운영 서버 배포용
# 'run'이나 'prod' 명령을 실행하면 리로드가 꺼지고 보안이 강화된 Production 모드로 돕니다.
prod = "fastapi run app/main.py --host 0.0.0.0 --port 8000"

# 테스트 실행 전 항상 러스트를 최신으로 빌드하도록 설정
test = ["stubs", { cmd = "pytest -v" }]

# 1. 러스트 개발 빌드 (Maturin develop)
# 환경변수를 앞에 붙여 하드링크 경고를 원천 차단합니다.
build = "maturin develop"

# 2. 러스트 빌드 + 타입 스텁 자동 생성 (빨간줄 제거용)
# 파이썬 경로 인식을 위해 명시적으로 가상환경 내 maturin을 지정합니다.
stubs = "maturin develop --generate-stubs"

# 3. 파이썬 메인 스크립트 실행
run = "python main.py"

# 4. 일체형 명령어 (빌드하고 바로 실행하기)
# 빌드(build) 태스크를 먼저 실행한 뒤 run 태스크를 이어 달립니다.
start = ["build", "run"]

```


database.py

import os from contextlib import contextmanager # contextmanager 임포트 from typing import Generator from dotenv...