One Prompt Engine, 39 Products: 스톡, 스티커, 템플릿을 패키징하는 스크립트들
요약
본 글은 스톡 에셋을 여러 플랫폼에 업로드할 때 발생하는 메타데이터 형식 불일치와 중복 게시 문제를 해결하는 파이썬 스크립트들을 소개합니다. `make_metadata.py`는 각 플랫폼별 요구 헤더를 맞춰 CSV 파일을 생성하며, `upload_tracker.py`는 배치 업로드를 위한 원장 역할을 수행하여 계정 위험을 방지합니다. 또한 Markdown 문서를 제품처럼 보이게 PDF로 변환하는 스크립트도 포함됩니다.
핵심 포인트
- 플랫폼별 메타데이터 요구사항(열 개수)이 상이하므로 전용 스크립트를 작성해야 합니다.
- `make_metadata.py`는 표준 라이브러리만 사용해 다양한 플랫폼의 CSV 헤더를 생성합니다.
- 중복 게시 방지를 위해 업로드 진행 상황을 추적하는 원장(`upload_tracker.py`)이 필수입니다.
- `md2pdf.py` 스크립트를 활용하여 문서를 스타일화된 PDF 제품으로 변환할 수 있습니다.
제가 거의 포기할 뻔했던 순간은 Adobe Stock의 업로드 화면 앞에서 맞이한 화요일 밤이었습니다. 저는 58개의 에셋을 준비했고, 이를 만드는 데 몇 주를 보냈지만, CSV 파일은 약 4초 만에 거부되었습니다. 헤더가 잘못된 것이 문제였습니다. Adobe는 5개 열 형식을 원하고, Vecteezy는 4개 열을 원하며, Dreamstime은 15개 열을 요구합니다. 저는 하나의 CSV 파일을 작성하고 모든 스톡 사이트가 동일할 것이라고 가정했습니다. 하지만 그렇지 않았습니다. '수정'하기 위해 배치 업로드를 다시 실행했고, 그 결과 폴더의 절반을 중복으로 게시하게 되었는데, 이는 계정이 플래그 지정되는 전형적인 경우였습니다. 그날 밤 저는 예술 작품 제작을 일주일 동안 멈추고 대신 스크립트를 작성했습니다.
여기에 제가 배운 것들을 수치와 함께 정리합니다.
메타데이터 문제는 창의성의 문제가 아니라 형식(formatting) 문제입니다
초기에 받았던 모든 거절은 헤더 문제였습니다. Adobe의 일괄 업로드 기능은 고정된 순서로 정확히 5개의 열을 기대합니다. Vecteezy는 4개를, Dreamstime은 15개를 기대합니다. 하나라도 잘못되면 아무도 작품을 보기 전에 파일이 거부됩니다.
그래서 저는 make_metadata.py를 작성했습니다. 이 스크립트는 폴더의 파일과 플랫폼 플래그를 입력받아 해당 플랫폼이 요구하는 헤더만, 그리고 오직 그것만을 작성합니다. 세 개의 명령어만 실행하면 됩니다:
python make_metadata.py ./my-assets --platform adobe --out metadata.csv
python make_metadata.py ./my-assets --platform vecteezy --out vecteezy.csv
python make_metadata.py ./my-assets --platform dreamstime --out dreamstime.csv
이 스크립트는 Python 표준 라이브러리만을 사용하며, pip install 과정이 필요 없습니다. 만약 실제 제목과 키워드가 있다면 titles.json 파일을 전달할 수 있으며, 그렇게 하는 것이 좋습니다. 왜냐하면 기본값은 파일명을 대문자로 처리(title-cases)하는데, 이는 첫 시도에는 괜찮지만 제출용으로는 적절하지 않기 때문입니다. 검토자들은 부실한 제목을 감지하고 그에 맞춰 행동합니다.
중복 게시(Double-posting)는 계정을 잃는 가장 빠른 방법입니다
이것은 아무도 경고해주지 않는 부분입니다. 파일을 40개 업로드했는데, 31번째 파일에서 문제가 생겨서 그것을 수정하고 배치 업로드를 다시 실행했다고 가정해 봅시다. 이제 30개의 파일이 두 번 존재하게 됩니다. 플랫폼들은 이를 스팸 행위로 간주합니다. 저도 한 번 그랬고 운 좋게 넘어갔습니다. 저는 절대 다시는 그렇게 하지 않겠다고 결심했습니다.
upload_tracker.py는 작은 원장(ledger) 역할을 합니다:
python upload_tracker.py pending items.txt
python upload_tracker.py done "asset-001.jpg"
python upload_tracker.py status
배치 작업을 시작하기 전에 pending을 실행하고 표시되는 항목만 업로드합니다. 또한 표준 라이브러리만을 사용합니다. 이 세트에서 가장 흥미롭지 않은 스크립트이자 저에게 가장 많은 문제를 해결해 준 것입니다.
문서는 제품처럼 보일 때까지는 제품이 아니다
저는 실제 콘텐츠를 Markdown 파일에 넣어두었습니다. 아무도 원본 .md 파일을 구매하지 않습니다. md2pdf.py는 하나의 Markdown 파일을 제목, 표, 목록 및 작동하는 링크가 포함된 스타일화된 PDF로 단일 명령으로 변환합니다:
python md2pdf.py content.md product.pdf "My Product Title"
이 스크립트는 전체 키트에서 유일한 두 개의 서드파티 패키지 중 하나인 reportlab을 사용합니다. 다른 하나는 Pillow입니다. 나머지 모든 것은 표준 라이브러리인데, 이는 모든 종속성이 새벽 2시에 작은 서버에서 고장 날 수 있기 때문입니다.
패키징이야말로 실제 판매가 시작되는 곳이다
저의 첫 판매는 $0.99였으며 실제 표지(cover)가 있는 제품에서 나왔습니다. 그전까지는 단순한 zip 파일들이 팔리지 않고 있었습니다. 차이점은 콘텐츠 자체가 아니라 프레젠테이션이었습니다.
pack_product.py는 다음 명령으로 제품을 번들링합니다:
python pack_product.py my-product "My Product" "A short subtitle" 9
이 스크립트는 zip 파일, 1280x720 크기의 표지, 그리고 600x600의 썸네일을 만듭니다. 표지는 목록(listings)에 사용되고, 썸네일은 그리드에 사용되며, 마켓플레이스가 공격적으로 자르고 크기를 조정하기 때문에 두 크기 모두 중요합니다. 출력물은 기본적으로 _system 폴더에 저장되며, --dir 또는 PACK_ROOT 환경 변수를 사용하여 리디렉션할 수 있어 스크립트를 수정할 필요가 없습니다.
전체 과정은 1 vCPU와 2GB의 RAM으로 실행된다
저는 GPU가 없는 작은 서버에서 이것을 실행하며, 이는 하드웨어 때문이 아니라 습관 덕분에 작동합니다:
- 한 번에 하나의 프로세스만 처리해야 한다. 단일 코어에서 병렬 이미지 작업은 단순히 자원을 낭비(thrash)하게 만든다.
- 배치 전체에 걸쳐 메모리가 축적되지 않도록 각 에셋 처리 후
gc.collect()를 실행한다. - 평균이 아닌
resource.getrusage(RUSAGE_SELF).ru_maxrss로 최대 RSS(Resident Set Size)를 측정해야 한다. 최고점이 가장 치명적이다. - 무거운 렌더링의 경우 서브프로세스(subprocess)당 하나의 파일을 사용해야 운영체제(OS)가 실제로 메모리를 회수할 수 있다.
- 필요한 해상도로 렌더링하라. 300dpi 대신 60dpi에서 미리보기를 검사하는 것만으로도 메모리를 대부분 절약할 수 있다.
카탈로그가 잡동사니 상자(junk drawer)가 되는 것을 막는 폴더 구조
project/
assets/ 원시 출력물 (raw output)
output/ 제출 준비 파일 + metadata.csv
...
어렵게 배운 규칙 하나: 절대 research/ 폴더를 삭제하지 마라. 나의 스크랩 로그와 메모는 미래 제품을 위한 원자재이다. 예전에 이 폴더를 '정리'하려고 비웠다가 몇 주간의 자료를 잃었다. 이런 일은 두 번 다시 일어나지 않을 것이다.
현재 상황
그 파이프라인(pipeline)을 통해 약 1,700개의 에셋이 생산되었고, 그중 58개가 Adobe Stock에 라이브되었으며, 첫 판매액은 $0.99였다. 이 금액은 나에게 첫 달러가 액수와 상관없이 가장 중요하다는 것을 상기시켜주는 역할을 한다. 스크립트들은 39개의 제품을 패키징했고, 약 856MB의 결과물을 만들었으며, 이 규칙들 뒤에는 대략 19,000줄의 파이프라인 코드와 300페이지 이상의 연구가 담겨 있다.
내가 제시하는 수치가 실제보다 크다고 꾸미지는 않겠다. 내가 할 수 있는 말은 스크립트 속 모든 규칙이 실제로 거절당했거나, 두 번 게시되었다거나, 또는 메모리 부족으로 인해 충돌했던 경험에서 비롯되었으며, 이 파이프라인은 거의 비용이 들지 않는 하드웨어 위에서 무인 상태로 실행된다는 것이다.
나는 네 가지 스크립트, 폴더 구조, 그리고 RAM 관련 노트를 '디지털 에셋 팩토리(digital asset factory)'라는 하나의 키트로 모았다. 이것은 내가 그 화요일 밤에 가졌으면 좋았을 패키징 계층이며, 더 큰 파이프라인으로 확장하고 싶다면 무료 스택에 플러그인 할 수 있다. 만약 이 것이 거절된 CSV 파일 하나를 절약해 준다면, 이미 제 역할을 다한 것이다.
디지털 제품을 만들고 계신가요? 디지털 상품 판매자를 위한 무료 가이드 및 키트.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기