feat: full-platform STT API (v2.3 consensus plan) #1
@@ -140,7 +140,7 @@
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": "# 10) 서버 기동 (in-proc 큐, 백그라운드 — nohup)\n# 이전 실행에서 남은 서버가 포트 8000을 점유하면 새 키를 모른 채 401이 난다.\n# → 먼저 기존 서버를 모두 종료하고, 키 파일 경로를 명시해 재시작한다.\nimport subprocess, os, time, urllib.request, urllib.error\n\nassert 'RAW_KEY' in globals(), '셀 9(키 생성)를 먼저 실행하세요'\n\nsubprocess.run(['pkill', '-f', 'luke-scribe serve'], capture_output=True)\ntime.sleep(2)\n\n# 서버가 읽을 키 파일/큐를 명시 (cwd 의존 제거)\nos.environ['LUKESCRIBE_API_KEY_FILE'] = '/content/api_keys.json'\nos.environ['LUKESCRIBE_QUEUE_BACKEND'] = 'inproc'\n# in-proc 서버가 자체 워커 스레드로 큐를 소비 (업로드 → 완료까지 API 단독 처리)\nos.environ['LUKESCRIBE_AUTO_WORKER'] = 'true'\n# Cloudflare Quick Tunnel — 외부 접속 링크 발급 (cloudflared는 셀 3에서 설치)\nos.environ['LUKESCRIBE_TUNNEL'] = 'cloudflare'\n\n!mkdir -p /content/logs\n!nohup luke-scribe serve --port 8000 > /content/logs/server.log 2>&1 &\n\nok = False\nfor _ in range(40):\n try:\n urllib.request.urlopen('http://localhost:8000/health', timeout=1)\n ok = True\n break\n except Exception:\n time.sleep(1)\nif not ok:\n print('서버 기동 실패 — 로그:')\n print(open('/content/logs/server.log').read()[-1500:])\n raise SystemExit('서버 기동 실패')\n\n# 키 인증 검증 — RAW_KEY로 /v1/jobs 호출 → 200이어야 함 (401이면 종료)\nreq = urllib.request.Request('http://localhost:8000/v1/jobs', headers={'X-API-Key': RAW_KEY})\ntry:\n resp = urllib.request.urlopen(req, timeout=5)\n print('서버 기동 OK + 키 인증 OK (HTTP', resp.status, ')')\nexcept urllib.error.HTTPError as e:\n print('키 인증 실패 (HTTP', e.code, ') — 서버 로그:')\n print(open('/content/logs/server.log').read()[-1500:])\n raise SystemExit('키 인증 실패 — RAW_KEY 캡처/키 파일 확인')\n\n# ── Cloudflare 터널 URL 캡처 + 외부 접속 검증 (서버 로그의 trycloudflare URL) ──\nimport re\nTUNNEL_URL = None\nfor _ in range(60):\n log = open('/content/logs/server.log', encoding='utf-8', errors='replace').read()\n m = re.search(r'https://[a-z0-9-]+\\.trycloudflare\\.com', log)\n if m:\n TUNNEL_URL = m.group(0)\n break\n time.sleep(2)\n\nif TUNNEL_URL:\n print('🌐 Cloudflare 터널 (외부 접속):', TUNNEL_URL)\n print(' 대시보드 (API Docs):', TUNNEL_URL + '/docs')\n print(' 상태 (health):', TUNNEL_URL + '/health')\n try:\n ext = urllib.request.urlopen(TUNNEL_URL + '/health', timeout=15)\n print(' 외부 접속 검증 OK (HTTP', ext.status, ')')\n except Exception as exc:\n print(' 외부 접속 검증 실패:', exc)\n print(' ※ 임시 링크 — Colab 세션 종료 시 닫힘. API 호출에는 RAW_KEY(X-API-Key) 필요.')\nelse:\n print('터널 URL 미감지 (cloudflared 미설치/연결 실패) — 서버 로그:')\n print(open('/content/logs/server.log').read()[-1200:])\n print('로컬(8000)에서 계속 사용할 수 있습니다.')\n"
|
||||
"source": "# 10) 서버 기동 (in-proc 큐, 백그라운드 — nohup)\n# 이전 실행에서 남은 서버가 포트 8000을 점유하면 새 키를 모른 채 401이 난다.\n# → 먼저 기존 서버를 모두 종료하고, 키 파일 경로를 명시해 재시작한다.\nimport subprocess, os, re, shutil, time, urllib.request, urllib.error\n\nassert 'RAW_KEY' in globals(), '셀 9(키 생성)를 먼저 실행하세요'\n\nsubprocess.run(['pkill', '-f', 'luke-scribe serve'], capture_output=True)\ntime.sleep(2)\n\n# 서버가 읽을 키 파일/큐를 명시 (cwd 의존 제거)\nos.environ['LUKESCRIBE_API_KEY_FILE'] = '/content/api_keys.json'\nos.environ['LUKESCRIBE_QUEUE_BACKEND'] = 'inproc'\n# in-proc 서버가 자체 워커 스레드로 큐를 소비 (업로드 → 완료까지 API 단독 처리)\nos.environ['LUKESCRIBE_AUTO_WORKER'] = 'true'\n# Cloudflare Quick Tunnel — 외부 접속 링크 발급 (cloudflared는 셀 3에서 설치)\nos.environ['LUKESCRIBE_TUNNEL'] = 'cloudflare'\n\n!mkdir -p /content/logs\n!nohup luke-scribe serve --port 8000 > /content/logs/server.log 2>&1 &\n\nok = False\nfor _ in range(40):\n try:\n urllib.request.urlopen('http://localhost:8000/health', timeout=1)\n ok = True\n break\n except Exception:\n time.sleep(1)\nif not ok:\n print('서버 기동 실패 — 로그:')\n print(open('/content/logs/server.log').read()[-1500:])\n raise SystemExit('서버 기동 실패')\n\n# 키 인증 검증 — RAW_KEY로 /v1/jobs 호출 → 200이어야 함 (401이면 종료)\nreq = urllib.request.Request('http://localhost:8000/v1/jobs', headers={'X-API-Key': RAW_KEY})\ntry:\n resp = urllib.request.urlopen(req, timeout=5)\n print('서버 기동 OK + 키 인증 OK (HTTP', resp.status, ')')\nexcept urllib.error.HTTPError as e:\n print('키 인증 실패 (HTTP', e.code, ') — 서버 로그:')\n print(open('/content/logs/server.log').read()[-1500:])\n raise SystemExit('키 인증 실패 — RAW_KEY 캡처/키 파일 확인')\n\n# ── Cloudflare 터널 URL 캡처 + 외부 접속 검증 (서버 로그의 trycloudflare URL) ──\nTUNNEL_URL = None\nif shutil.which('cloudflared'):\n for _ in range(60):\n log = open('/content/logs/server.log', encoding='utf-8', errors='replace').read()\n m = re.search(r'https://[a-z0-9-]+\\.trycloudflare\\.com', log)\n if m:\n TUNNEL_URL = m.group(0)\n break\n time.sleep(2)\nelse:\n print('cloudflared 미설치 (셀 3 다운로드 실패) — 터널 생략, 로컬(8000) 계속 사용')\n\nif TUNNEL_URL:\n print('🌐 Cloudflare 터널 (외부 접속):', TUNNEL_URL)\n print(' 대시보드 (API Docs):', TUNNEL_URL + '/docs')\n print(' 상태 (health):', TUNNEL_URL + '/health')\n try:\n ext = urllib.request.urlopen(TUNNEL_URL + '/health', timeout=15)\n print(' 외부 접속 검증 OK (HTTP', ext.status, ')')\n except Exception as exc:\n print(' 외부 접속 검증 실패 (브라우저에선 열릴 수 있음):', exc)\n print(' ※ 임시 링크 — Colab 세션 종료 시 닫힘. API 호출에는 RAW_KEY(X-API-Key) 필요.')\nelse:\n print('터널 URL 미감지 — 서버 로그:')\n print(open('/content/logs/server.log').read()[-1200:])\n print('로컬(8000)에서 계속 사용할 수 있습니다.')\n"
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
|
||||
@@ -214,7 +214,7 @@ def cells() -> list[dict]:
|
||||
"# 10) 서버 기동 (in-proc 큐, 백그라운드 — nohup)\n"
|
||||
"# 이전 실행에서 남은 서버가 포트 8000을 점유하면 새 키를 모른 채 401이 난다.\n"
|
||||
"# → 먼저 기존 서버를 모두 종료하고, 키 파일 경로를 명시해 재시작한다.\n"
|
||||
"import subprocess, os, time, urllib.request, urllib.error\n"
|
||||
"import subprocess, os, re, shutil, time, urllib.request, urllib.error\n"
|
||||
"\n"
|
||||
"assert 'RAW_KEY' in globals(), '셀 9(키 생성)를 먼저 실행하세요'\n"
|
||||
"\n"
|
||||
@@ -256,8 +256,8 @@ def cells() -> list[dict]:
|
||||
" raise SystemExit('키 인증 실패 — RAW_KEY 캡처/키 파일 확인')\n"
|
||||
"\n"
|
||||
"# ── Cloudflare 터널 URL 캡처 + 외부 접속 검증 (서버 로그의 trycloudflare URL) ──\n"
|
||||
"import re\n"
|
||||
"TUNNEL_URL = None\n"
|
||||
"if shutil.which('cloudflared'):\n"
|
||||
" for _ in range(60):\n"
|
||||
" log = open('/content/logs/server.log', encoding='utf-8', errors='replace').read()\n"
|
||||
" m = re.search(r'https://[a-z0-9-]+\\.trycloudflare\\.com', log)\n"
|
||||
@@ -265,6 +265,8 @@ def cells() -> list[dict]:
|
||||
" TUNNEL_URL = m.group(0)\n"
|
||||
" break\n"
|
||||
" time.sleep(2)\n"
|
||||
"else:\n"
|
||||
" print('cloudflared 미설치 (셀 3 다운로드 실패) — 터널 생략, 로컬(8000) 계속 사용')\n"
|
||||
"\n"
|
||||
"if TUNNEL_URL:\n"
|
||||
" print('🌐 Cloudflare 터널 (외부 접속):', TUNNEL_URL)\n"
|
||||
@@ -274,10 +276,10 @@ def cells() -> list[dict]:
|
||||
" ext = urllib.request.urlopen(TUNNEL_URL + '/health', timeout=15)\n"
|
||||
" print(' 외부 접속 검증 OK (HTTP', ext.status, ')')\n"
|
||||
" except Exception as exc:\n"
|
||||
" print(' 외부 접속 검증 실패:', exc)\n"
|
||||
" print(' 외부 접속 검증 실패 (브라우저에선 열릴 수 있음):', exc)\n"
|
||||
" print(' ※ 임시 링크 — Colab 세션 종료 시 닫힘. API 호출에는 RAW_KEY(X-API-Key) 필요.')\n"
|
||||
"else:\n"
|
||||
" print('터널 URL 미감지 (cloudflared 미설치/연결 실패) — 서버 로그:')\n"
|
||||
" print('터널 URL 미감지 — 서버 로그:')\n"
|
||||
" print(open('/content/logs/server.log').read()[-1200:])\n"
|
||||
" print('로컬(8000)에서 계속 사용할 수 있습니다.')\n"
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user