본문 바로가기
IT 끄적이기

파이썬 디렉토리에 따른 실행 원리

by 미르아 2025. 1. 10.
728x90
파이썬 실행 시 명령어에 따라 실행 여부가 달라져서 정리
 

이 문제가 해결된 이유는 Python의 모듈 경로현재 작업 디렉토리에 따라 모듈을 찾는 방식이 다르기 때문입니다.

app 디렉토리 안에서 python -m uvicorn main:app --reload 명령어를 실행하니까 작동한 이유를 아래에서 설명하겠습니다.


1. python -m의 작동 원리

python -m 명령어는 모듈로 실행되도록 Python의 sys.path를 자동으로 설정합니다.

  • app 디렉토리 안에서 실행했기 때문에 main 모듈이 app 폴더 안에 있다고 인식됩니다.
  • 즉, main.py가 app 폴더 안에 있기 때문에 정상적으로 경로를 찾고 실행된 겁니다.

2. uvicorn과 python -m uvicorn의 차이

uvicorn 명령어는 현재 디렉토리를 기준으로 작동합니다.

  • uvicorn app.main:app 명령어는 루트 디렉토리에서 app/main.py를 찾습니다.
  • 그러나 현재 디렉토리가 app 내부가 아니었다면 경로 문제로 인해 ModuleNotFoundError가 발생합니다.

반대로 python -m uvicorn은 현재 디렉토리를 기준으로 모듈 경로를 설정하기 때문에, app 디렉토리에서 실행하면 문제가 해결됩니다.


3. 왜 app 폴더 안에서만 잘 동작할까?

FastAPI의 경로나 StaticFiles 설정이 상대 경로로 되어 있어서 현재 작업 디렉토리에 의존하기 때문입니다.

  • os.path.abspath()로 설정된 경로: 현재 디렉토리를 기준으로 절대 경로를 만듭니다.
  • uvicorn 명령 실행 위치: uploads/characters 같은 상대 경로를 찾을 때, 현재 디렉토리가 app이 아니라 back이면 경로를 찾지 못합니다.

4. 어떻게 고칠 수 있을까?

모든 상황에서 일관되게 동작하도록 설정하려면 루트 디렉토리를 기준으로 경로를 지정해야 합니다.

(1) 절대 경로로 수정

아래 코드를 사용하여 프로젝트 루트를 기준으로 모든 경로를 설정하세요:

 
import os

# 프로젝트 루트 경로를 기준으로 설정
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
UPLOAD_DIR = os.path.join(BASE_DIR, "app/uploads/characters")
os.makedirs(UPLOAD_DIR, exist_ok=True)

app.mount(
    "/images",
    StaticFiles(directory=UPLOAD_DIR),
    name="images"
)

(2) 루트 디렉토리에서 실행

이제 back 폴더에서 실행해도 문제가 없도록 수정된 경로를 적용했으니, 다음과 같은 명령어를 사용할 수 있습니다:  

cd /Volumes/Data HD/project3/novel_test1/back
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

5. app 폴더 안에서 실행을 계속 유지하려면

만약 경로 문제를 고치지 않고, app 폴더 안에서만 실행하고 싶다면 현재처럼 python -m uvicorn을 사용하는 방식으로 진행하면 됩니다:

 
cd /Volumes/Data HD/project3/novel_test1/back/app
python -m uvicorn main:app --reload
728x90