Files
yakcloud-starter/app.py

56 lines
2.1 KiB
Python

#!/usr/bin/env python3
"""프레임워크 중립 최소 스타터 — Python 표준 라이브러리만(의존성 0).
배포 계약만 보여준다:
· PORT 환경변수로 리슨(기본 8080)
· GET /healthz → 200 {"ok": true} (매니페스트 health 경로)
· GET / → 앱 정보 + 바인딩된 소스의 <PREFIX>_URL ''만(값은 노출 안 함)
새 프로젝트는 이 파일을 원하는 스택으로 교체하되, 위 3가지 계약만 지키면 된다.
"""
import http.server
import json
import os
import socketserver
PORT = int(os.environ.get("PORT", "8080"))
def bound_source_keys() -> list[str]:
"""바인딩된 데이터 소스가 주입한 <PREFIX>_URL 키만(값 미노출) — 무엇이 연결됐는지 확인용."""
return sorted(
k for k, v in os.environ.items()
if k.endswith("_URL") and isinstance(v, str) and "://" in v
)
class Handler(http.server.BaseHTTPRequestHandler):
def _send(self, code: int, obj: dict) -> None:
body = json.dumps(obj, ensure_ascii=False).encode()
self.send_response(code)
self.send_header("content-type", "application/json; charset=utf-8")
self.send_header("content-length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def do_GET(self) -> None: # noqa: N802
path = self.path.split("?", 1)[0].rstrip("/") or "/"
if path in ("/healthz", "/health"):
self._send(200, {"ok": True})
return
self._send(200, {
"app": os.environ.get("APP_NAME", "yakcloud-starter"),
"host": os.environ.get("HOSTNAME", "?"),
"bound_sources": bound_source_keys(), # 연결된 소스 <PREFIX>_URL 키(값 미노출)
"path": self.path,
})
def log_message(self, *_args) -> None: # 로그 조용히
return
if __name__ == "__main__":
socketserver.ThreadingTCPServer.allow_reuse_address = True
with socketserver.ThreadingTCPServer(("", PORT), Handler) as httpd:
print(f"yakcloud-starter listening on :{PORT}", flush=True)
httpd.serve_forever()