uv add가 "No pyproject.toml found"로 죽을 때

Asher(애셔/오효준)·2026년 8월 31일

fastapi

목록 보기
1/4
post-thumbnail

FastAPI 튜토리얼을 따라 하다가 첫 줄에서 막혔다.

$ uv add "fastapi[standard]"
error: No `pyproject.toml` found in current directory or any parent directory

패키지 이름을 잘못 쓴 것도, uv가 안 깔린 것도 아니었다. 원인은 훨씬 단순했다.

uv에는 두 개의 세계가 있다

uv는 명령어가 두 갈래로 나뉜다.

명령하는 일
프로젝트 인터페이스
uv add, uv remove, uv run, uv sync
pyproject.toml을 읽고 고쳐 쓴다
pip 인터페이스
uv pip install, uv pip list
활성화된 환경에 그냥 설치한다

uv add는 후자가 아니라 전자다. 단순히 "패키지를 설치해줘"가 아니라 "이 프로젝트의 의존성 목록에 이 패키지를 추가하고, 잠금 파일을 갱신하고, 환경을 동기화해줘"라는 뜻이다.

그러니 의존성을 적어둘 pyproject.toml이 없으면 uv 입장에서는 할 말이 없다. 어디에 적으라는 건지 모르니까.

에러 메시지를 다시 읽어보면

No pyproject.toml found in current directory or any parent directory

뒷부분이 핵심이다. uv는 현재 디렉터리만 보고 포기하지 않는다. 루트에 닿을 때까지 상위 디렉터리를 거슬러 올라가며 pyproject.toml을 찾는다. 모노레포나 워크스페이스 하위에서 명령을 실행해도 동작하게 하기 위한 설계다.

/                          ← pyproject.toml 없음
└── Users/joon/            ← pyproject.toml 없음
    └── ADA_Challenge/     ← pyproject.toml 없음
        └── bamti-backend/ ← 여기서 시작, 없음

전부 훑고도 못 찾았다는 얘기다. 즉 "오타가 났다"가 아니라 "아직 프로젝트가 아니다"라는 신호다.

해결: 프로젝트부터 만든다

1. uv init

uv init --name bamti-backend --python 3.13
# Initialized project `bamti-backend`

2. uv add

uv add "fastapi[standard]"

이제는 조용히 잘 된다. fastapi, uvicorn, starlette, pydantic, typer, watchfiles까지 30여 개 패키지가 한 번에 들어온다. ([standard]는 개발 서버와 CLI에 필요한 것들을 묶어놓은 extras다.)

3. 실행

main.py를 만들고,

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

띄운다.

uv run fastapi dev main.py
⚡️ Starting FastAPI in development mode
🐍 Using import string: main:app
🌐 Server started at http://127.0.0.1:8000
   Documentation at http://127.0.0.1:8000/docs

curl http://127.0.0.1:8000/{"Hello":"World"}. 끝.

uv init이 만들어준 것들

파일역할
pyproject.toml의존성 목록. uv add가 고쳐 쓰는 대상
uv.lock정확한 버전 잠금. 커밋할 것
.python-version파이썬 버전 고정 (3.13)
.venv/가상환경. uv가 알아서 만들고 관리
.gitignore, README.md, src/기본 스캐폴딩
.git/git 저장소도 같이 초기화된다

시스템 파이썬은 3.14.7이었지만 --python 3.13으로 고정하자 uv가 3.13을 알아서 받아왔다. 이게 .python-version에 박혀서 협업자도 같은 버전을 쓰게 된다.

덤: source .venv/bin/activate는 필요 없다

uv run을 앞에 붙이면 uv가 알아서 프로젝트 환경에서 실행한다. 심지어 실행 직전에 uv.lock과 환경이 어긋났는지 확인하고 동기화까지 해준다.

uv run fastapi dev main.py    # activate 없이 바로
uv run python -c "import fastapi; print(fastapi.__version__)"

activate를 깜빡해서 전역 파이썬에 설치하는 사고가 구조적으로 사라진다.

덤 2: 정체불명의 빈 파일

정리하다 보니 디렉터리에 uv라는 이름의 0바이트 파일이 하나 있었다. 아마 uv 뭐시기를 치다가 리다이렉션 오타(>)를 냈던 것 같다. 눈에 안 띄는 쓰레기 파일이니 지우고 넘어갔다.

정리

uv addpyproject.toml을 못 찾겠다고 하면,

  • 잘못 친 게 아니라 아직 프로젝트가 없는 것이다 → uv init
  • 프로젝트를 만들기 싫고 그냥 설치만 하고 싶다면 → uv venvuv pip install
  • 파일 하나짜리 스크립트라면 → uv add --script script.py fastapi (PEP 723 인라인 메타데이터)
  • pyproject.toml만 딱 필요하다면 → uv init --bare

튜토리얼이 uv init으로 시작하는 데는 이유가 있었다.


환경: uv 0.12.7 / macOS(Apple Silicon) / Python 3.13 / FastAPI 0.141.1

profile
Asher입니다. 하지만 Joon이라고도 불리는

0개의 댓글