1 개요
여러 프로젝트에서 공통으로 사용하는 코드는 별도의 패키지로 분리하고, 각 프로젝트에서 의존성(dependency) 으로 관리하는 것이 유지보수와 협업에 유리하다. pip, Poetry 등으로 외부 Git 저장소의 패키지를 직접 설치할 수 있으나, 대상 repo가 Python 패키지 형식을 갖춰야만 가능하다.
1.1 이 글이 다루는 상황
외부 repo (archive 상태, pyproject.toml 없음)
↓ poetry add git+ssh://...
여러 문제 발생
↓
각 문제의 원인과 해결 방향 파악
1.2 왜 코드 복사 대신 의존성 관리인가
외부 패키지 코드를 현재 프로젝트에 복사해 사용하면 단기적으론 빠르지만 아래와 같은 문제가 생긴다:
| 방식 | 장점 | 단점 |
|---|---|---|
| 코드 복사 | 즉시 사용 가능 | 원본 업데이트 반영 불가, 중복 유지보수 |
| 의존성 관리 | 버전 추적, 업데이트 용이 | 패키지화 조건 충족 필요 |
여러 프로젝트에서 동일 코드를 사용하는 경우라면 의존성으로 관리하는 것이 원칙이다.
2 Python 의존성 관리와 빌드 시스템 기초
2.1 Python 패키지 설치 도구의 동작 원리
pip install 또는 poetry add가 외부 repo를 설치할 때 내부적으로 아래 순서로 동작한다:
1. 저장소 접근 (HTTPS 또는 SSH 인증)
↓
2. 패키지 인식 (pyproject.toml 또는 setup.py 탐색)
↓
3. 빌드 백엔드 결정 (build-backend 설정 읽기)
↓
4. 빌드 백엔드 호출하여 wheel/sdist 생성
↓
5. 생성된 패키지를 현재 환경에 설치
2단계에서 pyproject.toml이나 setup.py가 없으면 즉시 실패한다:
Source does not appear to be a Python project:
no pyproject.toml or setup.py
2.2 PEP 517/518 — 현대 Python 빌드 표준
PEP 517/518 이전에는 setuptools + setup.py가 사실상 유일한 빌드 방법이었다. PEP 517/518 이후 빌드 프론트엔드(pip, Poetry)와 빌드 백엔드(setuptools, Poetry, Hatch 등)가 분리되었다.
빌드 프론트엔드 (pip, poetry add)
↓ pyproject.toml의 [build-system] 읽기
빌드 백엔드 (setuptools, poetry.core.masonry.api, hatchling 등)
↓ wheel 또는 sdist 생성
설치 완료
pyproject.toml의 [build-system] 섹션이 핵심이다:
2.3 setuptools vs Poetry 빌드 시스템 비교
| 특징 | setuptools | Poetry |
|---|---|---|
| 설정 파일 | pyproject.toml / setup.py / setup.cfg |
pyproject.toml |
| 의존성 관리 | requirements.txt 별도 |
pyproject.toml 통합 |
| lock 파일 | 없음 (별도 도구 필요) | poetry.lock 자동 생성 |
| 환경 격리 | 별도 venv 필요 | 내장 |
| 적합한 상황 | 레거시 프로젝트, 범용성 | 신규 프로젝트, 엄격한 의존성 관리 |
| build-backend | setuptools.build_meta |
poetry.core.masonry.api |
PEP 517 덕분에 빌드 백엔드가 달라도 pip/Poetry는 [build-system]을 읽고 적절한 백엔드를 자동 호출한다. 즉, Poetry로 관리되는 프로젝트에서 setuptools 기반 외부 패키지도 설치 가능하다.
2.4 Private repo 인증 방식
외부 repo가 Private이면 인증이 필요하다. 두 가지 방식이 있다:
| 방식 | URL 형태 | 특징 |
|---|---|---|
| SSH 키 | git+ssh://git@github.com/org/repo.git |
키 파일로 인증, 안전 |
| HTTPS 토큰 | git+https://<token>@github.com/org/repo.git |
토큰 URL 노출 위험 |
실무에서는 SSH 방식을 권장한다. ~/.ssh/config에 Host alias를 설정하면 멀티 계정도 관리 가능하다.
3 실전 사례: 외부 Private repo 패키지 통합
Agent 프로젝트(Streamlit 기반 AI 에이전트)에서 데이터 표준화 로직이 담긴 외부
data_standardizationrepo를 의존성으로 추가해야 했다. 해당 repo는 archive 상태였고,pyproject.toml도 없었다.
3.1 배경
- Agent 프로젝트를 진행하던 중 데이터 표준화 Agent 개발이 필요했다
- 약어 생성 로직이 구현된 Tool이 별도 GitHub repo(
data_standardization)에 분리되어 있었다 - 여러 에이전트 프로젝트에서 공통으로 사용할 패키지였기 때문에 의존성으로 관리하는 것이 올바른 방향이었다
3.2 문제 1: 외부 repo가 archive 상태
GitHub에서 repository를 archive 처리하면 읽기 전용 상태가 된다:
| 가능한 것 | 불가능한 것 |
|---|---|
| clone, pull, fork | push, PR 생성 |
| read-only 접근 | 코드 수정 반영 |
→ repo 관리자에게 unarchive 요청 또는 PR 권한 요청이 필요하다.
3.3 문제 2: pyproject.toml 없음
외부 repo의 디렉토리 구조:
data_standardization/
├── source/ ← 실제 Python 코드 (패키지 본체)
│ ├── __init__.py
│ ├── abbreviation_manager.py
│ ├── token_processor.py
│ └── ...
├── data/
├── output/
└── README.md ← pyproject.toml 없음
pyproject.toml이 없으니 Poetry는 이것을 Python 패키지로 인식하지 못했다:
Source does not appear to be a Python project:
no pyproject.toml or setup.py
3.4 문제 3: 빌드 시스템 불일치
Agent 프로젝트는 Poetry로 관리되지만, data_standardization은 pyproject.toml 자체가 없어 setuptools 기반으로 새로 작성해야 했다. PEP 517 덕분에 빌드 백엔드가 달라도 설치가 가능하다.
4 해결 방향
| 문제 | 해결 방법 |
|---|---|
| archive 상태 | 관리자에게 unarchive 요청 → PR로 pyproject.toml 추가 |
| pyproject.toml 없음 | setuptools 기반 pyproject.toml 직접 작성 |
| 빌드 시스템 불일치 | PEP 517 표준으로 자동 해결 (백엔드 자동 선택) |
| Private repo 인증 | SSH 키 + ~/.ssh/config alias 설정 |
전체 흐름:
1. 외부 repo (data_standardization) unarchive 요청
↓
2. SSH 인증 설정 확인 및 git dependency URL 구성
↓
3. pyproject.toml 작성 → PR로 반영 (승인 전 local path로 임시 설치)
↓
4. Poetry 프로젝트 (Agent)에 poetry add로 설치
↓
5. import data_standardization 동작 확인
각 단계의 세부 내용은 이어지는 블로그(12~16번)에서 순서대로 다룬다.
5 관련 포스트
- Python 빌드 시스템과 pyproject.toml 이해 — PEP 517/518 개념, sdist vs wheel, setuptools vs Poetry 비교 상세
- Poetry git dependency — URL, 위치, PEP 508 — git URL 구성과 Poetry 2.x 위치 문제
- SSH 다계정 인증과 ~/.ssh/config alias — Private repo SSH 인증 전략