집에 NAS가 있다면 유튜브 쇼츠 자동화 시스템을 직접 구축할 수 있다. 이 글은 UGREEN DXP4800PLUS NAS 위에서 실제로 운영 중인 쇼츠 자동화 파이프라인 구축 과정을 기록한 실전 후기다. 현재 운영 현황 (2026년 6월 기준) 수집 영상: 676개 저장 스냅샷: 38,134개 성장률 계산 성공률: 95.1% 트렌드 클러스터: 10종 (IT_DEVICE, AI/자동화, 연예/엔터 등) 자동 영상 생성: Video Factory v2 개발 중 단순 성공 사례가 아니다. FastAPI 404 오류, 분류기 정확도 문제, 영상 생성 실패까지 실제 겪은 삽질과 해결 과정을 함께 담았다. 전체 파이프라인 구조 YouTube API 수집 (30분마다) ↓ PostgreSQL 저장 ↓ 성장률 계산 ↓ content_cluster 분류 (10종) ↓ format_type 분류 (6종) ↓ 트렌드 대시보드 ↓ AI 대본 자동 생성 ↓ Edge-TTS 음성 생성 ↓ FFmpeg 영상 합성 ↓ drafts 폴더 저장 처음에는 간단한 스크립트 몇 개면 끝날 줄 알았다. 실전은 달랐다. FastAPI app.mount("/") 사용 시 API 404 오류 해결 방법 FastAPI에서 정적 파일을 서빙할 때 이런 코드를 썼다. # 오류 코드 - API가 전부 404 app . mount ( "/" , StaticFiles ( directory = "static" , html = True ) , name = "static" ) @app . get ( "/api/trends" ) async def get_trends ( ) : . . . API 호출마다 404가 났다. 원인은 라우팅 우선순위였다. app.mount("/") 가 상단에 있으면 뒤에 선언된 모든 엔드포인트가 무시된다. # 해결 코드 - 항상 moun...
처음에는 단순히 API 몇 개 호출하면 끝날 줄 알았다. UGREEN DXP4800PLUS NAS 위에서 유튜브 쇼츠 자동화 시스템을 구축하면서 YouTube Data API를 쓰기 시작했는데, 실제로 운영해보니 쿼터 관리가 더 큰 문제였다. YouTube Data API를 사용해 쇼츠 수집기나 트렌드 분석 시스템을 만들다 보면 쿼터(Quota) 부족 오류를 한 번쯤 겪게 된다. 하루 10,000유닛이면 사실상 무제한이라고 생각했는데, 글로벌 AI 키워드를 몇 개 추가하고 나서 하루도 지나지 않아 쿼터 부족 오류가 발생했다. 로그를 확인해보니 범인은 search.list 였다. 같은 API라도 videos.list 는 1유닛인데 search.list 는 100유닛이다. 이 차이를 이해하기 전까지는 쿼터가 왜 사라지는지 전혀 감이 오지 않았다. 약 700개 영상, 4만 개 이상의 스냅샷을 수집하는 과정에서 부딪힌 쿼터 제한과 해결 방법을 정리한다. YouTube Data API 기본 제한 사항 YouTube Data API v3는 무료로 제공되지만 일일 쿼터(Quota)가 존재한다. 기본 할당량: 하루 10,000 유닛 주요 API별 소비 유닛: videos.list : 1 유닛 search.list : 100 유닛 channels.list : 1 유닛 search.list 가 videos.list 보다 100배 비싸다. 처음에 이걸 몰라서 쿼터를 빠르게 소진했다. 실제로 겪은 문제들 문제 1: search.list 남용으로 쿼터 소진 초기 수집기는 이런 구조였다. # 초기 구조 - 쿼터 낭비 search_results = search . list ( q = "쇼츠" , type = "video" ) # 100 유닛 for video in search_results : detail = videos . list ( id = video . id ) # 1 유닛씩 s...
필자는 UGREEN DXP4800PLUS NAS 환경에서 Docker 기반 유튜브 쇼츠 자동화 시스템을 운영하고 있다. FastAPI와 PostgreSQL로 트렌드 수집 대시보드를 구축하던 중 모든 API 엔드포인트가 404를 반환하는 문제를 겪었다. 처음에는 PostgreSQL 연결 문제라고 생각했다. API가 전부 404를 반환하니 DB 연결이 끊어진 줄 알았다. docker compose logs로 컨테이너 로그를 뒤졌고, curl로 직접 호출해보니 FastAPI까지 요청이 들어오지도 않았다. 결국 원인은 app.mount("/") 한 줄이었다. 수정하고 나서 허탈했다. 30분을 날렸다. app.mount("/") 선언 위치 하나 때문이었다. 수정 후 즉시 정상 동작했다. 이 글에서는 해당 오류의 원인과 해결 방법, 그리고 FastAPI 내부 동작 원리까지 정리한다. 문제 상황 아래와 같이 코드를 작성했을 때 /api/trends 엔드포인트가 404를 반환한다. from fastapi import FastAPI from fastapi . staticfiles import StaticFiles app = FastAPI ( ) # 정적 파일 마운트 app . mount ( "/" , StaticFiles ( directory = "static" , html = True ) , name = "static" ) # API 엔드포인트 선언 @app . get ( "/api/trends" ) async def get_trends ( ) : return { "status" : "success" } 코드 자체는 문법적으로 문제가 없다. 하지만 실행하면 /api/trends 호출 시 404가 반환된다. 원인 분석 FastAPI는 라우팅 처리 시 선언 순서대로 매칭 을 시도한다....
댓글
댓글 쓰기