python upload_tracker.py done
pending은 배치 목록을 읽고, 원장(ledger)을 읽어 '완료됨(done)'으로 표시되지 않은 항목만 출력합니다. status는 카운트를 제공합니다. 이것이 전체 인터페이스입니다. 이 파일은 사람이 읽기 쉬우며, 어떤 편집기로든 열 수 있고, grep 할 수 있으며, 텍스트 파일 하나를 복사하는 것만으로 백업할 수 있습니다. 1 vCPU, 2 GB RAM 서버에서 몇 천 줄짜리 텍스트 파일을 여고 스캔하는 것은 사실상 비용이 들지 않습니다. 데몬(daemon)도 없고, 잠금 파일(lock file)도 없고, 스키마 마이그레이션(schema migration)도 없습니다. 박스 자체가 작기 때문에, 실행하지 않는 모든 프로세스가 유지되는 메모리가 됩니다.
중요한 세부 사항 하나: 원장은 파일 이름을 제출된 그대로 기록하며, 제가 `make_metadata.py`로 만드는 메타데이터 CSV 역시 이 동일한 파일명을 사용합니다. Adobe의 업로드 CSV는 엄격하게 5개 열 헤더를 요구하고, Vecteezy는 4개 열을, Dreamstime은 15개 열을 원하며, 세 곳 모두 잘못된 헤더가 들어오면 즉시 거부됩니다. CSV 빌더와 트래커가 파일명에 대한 하나의 진실 공급원(source of truth)을 공유하기 때문에, 제가 '완료됨'으로 표시하는 것이 실제로 업로드된 것과 일치합니다.
## stdlib만 사용해야 했던 이유: 선호도가 아닌 필수 요건
제 네 개의 파이프라인 스크립트 중 두 개인 `make_metadata.py`와 `upload_tracker.py`는 표준 라이브러리(standard library)만을 사용합니다. 나머지 두 개는 커버용으로 Pillow를, PDF용으로 reportlab을 필요로 합니다. 이러한 분리는 의도적입니다. 제가 가장 자주 실행하는 스크립트들, 즉 모든 업로드 세션 전후에는 가상 환경(venv)이 없거나 패키지가 업그레이드로 인해 손상되어 실패해서는 안 됩니다. 작은 서버에서는 이 두 스크립트에 대해 venv를 완전히 생략한다는 것은 실패 모드를 하나 줄이고 환경 디스크 용량을 약 100 MB 절약한다는 의미입니다.
또한 이는 트래커가 Python 3.9 이상이 존재하는 어디서든 실행될 수 있다는 것을 의미합니다. 저는 이 스크립트를 서버에서, 노트북에서, 심지어 마감 기한 동안 친구의 컴퓨터에서 한 번 실행해 보았습니다. 설치 단계가 없다는 것은 무언가를 '완료됨'으로 표시하는 것을 건너뛸 변명이 없다는 뜻입니다.
## 실제로 더블 포스팅을 방지하는 습관
스크립트는 '마킹 완료(marking done)' 작업이 업로드 루프 자체의 일부일 때만 작동합니다. 별도의 청소 작업(chore)으로 분리되면 안 됩니다. 제 규칙은 간단합니다. 파일당 업로드 명령어와 `done` 명령어가 연속적으로, 즉각적으로 실행되어야 하며, 마지막에 일괄 처리되어서는 안 됩니다. 만약 제가 나중에 40개 파일을 완료로 마킹한다면, 저는 다시 제 기억을 믿는 것이고, 그 기억이 지난 3월에 실패했던 바로 그 부분입니다.
서버의 메모리 관리에도 동일한 원칙이 적용됩니다. 한 번에 하나의 프로세스만 처리하고, 각 에셋(asset) 처리 후 `gc.collect()`를 실행하며, 추측하는 대신 `resource.getrusage(RUSAGE_SELF).ru_maxrss`로 최대 RSS(Resident Set Size)를 측정해야 합니다. 평균 메모리 사용량은 천장치가 2GB인 상황에서는 아무것도 알려주지 못합니다. 하지만 그것은 파이프라인의 패키징 측면이고, 이 글은 레저(ledger)에 관한 것입니다.
## 6개월 후의 모습
39개의 제품과 856MB의 결과물을 만들어낸 전체 파이프라인은 다음과 같은 요소들로 구성됩니다. 세 플랫폼을 위한 메타데이터 빌더, Markdown-to-PDF 렌더러, 파일을 압축하고 1280×720 커버와 600×600 썸네일을 렌더링하는 패키저입니다. 부모 프로젝트에는 약 19,000줄의 파이프라인 코드가 있으며, GPU가 없는 하드웨어에서 검증되었습니다. 이 트래커(tracker)는 가장 작은 부분이며, 만약 모든 것을 잃더라도 제가 가장 먼저 재구축할 부분인데, 왜냐하면 다른 모든 부분이 이것이 존재한다고 가정하기 때문입니다.
저는 실제 스크립트와 함께 이 내용을 ai sticker factory playbook에 모두 정리했습니다. 이것은 이론 문서가 아니라, 이 작업으로 만들어진 도구입니다: 네 개의 스크립트, 폴더 레이아웃, 소형 서버를 위한 RAM 사용 가이드, 그리고 스크립트가 강제하는 플랫폼 규칙들입니다. 만약 여러분이 자체 배치 파이프라인을 조립하고 있다면, 이것은 제가 지난 3월에 갖고 싶었던 지름길입니다.
[Get ai sticker factory playbook](https://revanzart-shop.revanzart.workers.dev/go/ai-sticker-factory-playbook?src=devto)
_디지털 제품을 제작하시나요? [디지털 제품 판매자를 위한 무료 가이드 및 키트](https://revanzart-shop.revanzart.workers.dev/guides)._