# ============ Part 1 / 3 : app.py (Flask base) ============ # Flask 서버: 정적 파일/템플릿 서빙 + Bitget API 프록시 엔드포인트 # - 다음 단계(Part 2, Part 3)에서 index.html / main.js를 추가해도 그대로 동작합니다. from flask import Flask, send_from_directory, render_template, jsonify, request import requests import os app = Flask( __name__, static_folder="static", # Part 3에서 main.js 등 들어갈 폴더 template_folder="templates" # Part 2에서 index.html이 들어갈 폴더 ) BITGET_API = "https://api.bitget.com" def _proxy_get(path: str, params: dict | None = None): """Bitget 공용 API 프록시: 브라우저 CORS/레이트이슈 대비""" url = f"{BITGET_API}{path}" try: r = requests.get(url, params=params or {}, timeout=10) r.raise_for_status() # Bitget 응답을 그대로 반환 (필요시 캐싱/정규화 로직을 여기에 추가) return r.json(), 200 except requests.HTTPError as e: status = e.response.status_code if e.response else 502 return {"error": f"HTTP {status}", "detail": str(e)}, status except requests.RequestException as e: return {"error": "Bad Gateway", "detail": str(e)}, 502 # -------------------------- # 기본 라우트 # -------------------------- @app.route("/") def index(): # Part 2에서 templates/index.html이 준비되면 해당 파일을 렌더합니다. # (지금은 없더라도 안내 HTML을 임시로 반환) if os.path.exists(os.path.join(app.template_folder, "index.html")): return render_template("index.html") return """ withgot · Flask Base Ready

Flask base is running

Next: add templates/index.html (Part 2) and static/main.js (Part 3).

""" # -------------------------- # 정적 파일 (JS/CSS/자산) # -------------------------- @app.route("/static/") def static_files(filename): return send_from_directory(app.static_folder, filename) # -------------------------- # Bitget 프록시 엔드포인트 (브라우저에서 이 주소만 호출) # -------------------------- # Spot 티커 (원본: /api/v2/spot/market/tickers) @app.get("/api/bitget/spot_tickers") def api_spot_tickers(): return _proxy_get("/api/v2/spot/market/tickers") # Futures 티커 (원본: /api/v2/mix/market/tickers?productType=USDT-FUTURES) @app.get("/api/bitget/futures_tickers") def api_futures_tickers(): product_type = request.args.get("productType", "USDT-FUTURES") return _proxy_get("/api/v2/mix/market/tickers", {"productType": product_type}) # (선택) 캔들/히스토리 등 필요 시 추가 # 예: /api/v2/mix/market/history-candles @app.get("/api/bitget/mix/history_candles") def api_mix_history_candles(): # 프런트에서 symbol, granularity, limit, endTime 등을 그대로 전달 params = { "symbol": request.args.get("symbol", ""), "granularity": request.args.get("granularity", ""), "productType": request.args.get("productType", "USDT-FUTURES"), "limit": request.args.get("limit", "200"), } # endTime이 있으면 포함 end_time = request.args.get("endTime") if end_time: params["endTime"] = end_time return _proxy_get("/api/v2/mix/market/history-candles", params) # (선택) CORS 간단 허용이 필요하면 아래 주석 해제 후 사용 # from flask_cors import CORS # CORS(app, resources={r"/api/*": {"origins": "*"}}) if __name__ == "__main__": # 개발모드로 실행 (배포 시에는 WSGI/ASGI 서버 사용 권장) app.run(host="0.0.0.0", port=5000, debug=True) # ========== / Part 1 / 3 ==========