feat: full-platform STT API (v2.3 consensus plan) #1

Open
lukehemmin wants to merge 21 commits from feat/full-platform into main
2 changed files with 43 additions and 13 deletions
Showing only changes of commit e34322cc73 - Show all commits
File diff suppressed because one or more lines are too long
+41 -11
View File
@@ -287,20 +287,47 @@ def cells() -> list[dict]:
" print('🌐 Cloudflare 터널 (외부 접속):', TUNNEL_URL)\n"
" print(' 대시보드 (API Docs):', TUNNEL_URL + '/docs')\n"
" print(' 상태 (health):', TUNNEL_URL + '/health')\n"
" # DNS 전파 지연 대비 재시도 (새 trycloudflare 호스트는 초반에 못 풀릴 수 있음)\n"
" # ── 외부 접속 검증 ──\n"
" # Colab VM의 DNS가 새 trycloudflare 호스트를 해석 못 하는 경우가 있다\n"
" # (실측: Name or service not known — 브라우저/폰에선 정상 접속).\n"
" # 순서: ① urllib(시스템 DNS) ② 실패 시 DoH(Cloudflare DNS)로 우회 검증\n"
" import socket\n"
" _host = TUNNEL_URL.split('//')[1].split('/')[0]\n"
" _dns_ip = None\n"
" try:\n"
" _dns_ip = socket.gethostbyname(_host)\n"
" except socket.gaierror as _de:\n"
" print(' (VM DNS 해석 실패:', _de, '— DoH로 우회 검증 시도)')\n"
"\n"
" ext_ok = False\n"
" _last_err = None\n"
" for _ in range(6):\n"
" try:\n"
" ext = urllib.request.urlopen(TUNNEL_URL + '/health', timeout=15)\n"
" print(' 외부 접속 검증 OK (HTTP', ext.status, ')')\n"
" ext_ok = True\n"
" break\n"
" except Exception as _e:\n"
" _last_err = _e\n"
" if _dns_ip:\n"
" for _ in range(6):\n"
" try:\n"
" ext = urllib.request.urlopen(TUNNEL_URL + '/health', timeout=15)\n"
" print(' 외부 접속 검증 OK (HTTP', ext.status, ')')\n"
" ext_ok = True\n"
" break\n"
" except Exception as _e:\n"
" _last_err = _e\n"
" time.sleep(2)\n"
" if not ext_ok and shutil.which('curl'):\n"
" # VM DNS 우회: Cloudflare DoH로 호스트 해석 → 터널 직접 접속 (외부와 동일 경로)\n"
" for _ in range(6):\n"
" _c = subprocess.run(\n"
" ['curl', '-sS', '-o', '/dev/null', '-w', '%{http_code}', '--max-time', '15',\n"
" '--doh-url', 'https://cloudflare-dns.com/dns-query', TUNNEL_URL + '/health'],\n"
" capture_output=True, text=True,\n"
" )\n"
" if _c.stdout.strip() == '200':\n"
" print(' 외부 접속 검증 OK (DoH 우회, HTTP 200)')\n"
" ext_ok = True\n"
" break\n"
" _last_err = _c.stdout.strip() or _c.stderr.strip() or _last_err\n"
" time.sleep(2)\n"
" if not ext_ok:\n"
" print(' 외부 접속 검증 실패 (DNS 전파 지연이거나 Cloudflare 브라우저 체크 — 브라우저에서 직접 확인하세요):', _last_err)\n"
" print(' 자동 검증 불가 — 브라우저에서 직접 열어보세요:', TUNNEL_URL + '/docs')\n"
" print(' (URL이 발급됐다는 건 Cloudflare edge↔서버 터널이 이미 연결된 상태입니다. 상세:', _last_err)\n"
" print(' ※ 임시 링크 — Colab 세션 종료 시 닫힘. API 호출에는 RAW_KEY(X-API-Key) 필요.')\n"
"else:\n"
" print('터널 URL 미감지 — 서버 로그:')\n"
@@ -455,7 +482,10 @@ def cells() -> list[dict]:
"- `/docs`(Swagger 대시보드)와 `/health`는 별도 키 없이 열리지만, **실제 API 호출은 `X-API-Key`(RAW_KEY)가 필요**합니다.\n"
"- cloudflared는 셀 3에서 설치됩니다. 다운로드 실패 시 터널 없이 로컬(8000)에서 계속 사용할 수 있습니다.\n"
"- 터널은 `http://localhost:8000`을 고정으로 바라봅니다. 다른 포트로 서버를 띄우면 터널이 연결되지 않습니다.\n"
"- trycloudflare는 **인증 없는 Quick Tunnel**이라 URL만 알면 누구나 접근 가능합니다. 민감 데이터는 올리지 마세요.\n\n"
"- trycloudflare는 **인증 없는 Quick Tunnel**이라 URL만 알면 누구나 접근 가능합니다. 민감 데이터는 올리지 마세요.\n"
"- **자동 검증이 실패해도 터널은 정상일 수 있습니다.** Colab VM의 DNS가 새 trycloudflare 호스트를\n"
" 해석하지 못하면 `Name or service not known`이 나지만, URL 발급 자체가 이미 edge↔서버 연결을 의미합니다.\n"
" 검증 셀은 Cloudflare DoH(`--doh-url`) 우회로 다시 시도하며, 안 되면 브라우저/폰에서 직접 확인하세요.\n\n"
"### `No module named 'luke_scribe'` (셀 12에서 import 실패)\n\n"
"Colab 커널은 실행 중에는 pip editable 설치가 만든 .pth를 읽지 못합니다\n"
"(인터프리터 시작 시에만 반영). 설치 셀 3이 커널 sys.path에 `src/`를 직접\n"