Merry99 commited on
Commit
26524df
Β·
1 Parent(s): 3c70e7c

rm oracle DB loggic

Browse files
Files changed (4) hide show
  1. app.py +2 -98
  2. requirements.txt +0 -1
  3. start.py +16 -89
  4. start_server.sh +2 -2
app.py CHANGED
@@ -1,9 +1,7 @@
1
  import os
2
- import json
3
  from typing import List, Optional
4
  from fastapi import FastAPI, HTTPException
5
- from pydantic import BaseModel, Field, ConfigDict
6
- import oracledb
7
  from dotenv import load_dotenv
8
  import pandas as pd
9
  from datetime import datetime
@@ -12,46 +10,13 @@ from datasets import Dataset, DatasetDict, load_dataset
12
  # 둜컬 개발: .env 파일 λ‘œλ“œ (있으면)
13
  load_dotenv()
14
 
15
- # ----- ν™˜κ²½ λ³€μˆ˜ -----
16
- DB_USER = os.environ["DB_USER"]
17
- DB_PASSWORD = os.environ["DB_PASSWORD"]
18
- WALLET_DIR = os.environ["WALLET_DIR"]
19
- WALLET_PASSWORD = os.environ["WALLET_PASSWORD"]
20
-
21
- # tnsnames.ora μ•ˆμ˜ alias 확인 (보톡 *_high)
22
- TNS_ALIAS = os.environ["DB_TNS_ALIAS"]
23
-
24
  # Hugging Face μ„€μ •
25
  HF_DATA_REPO_ID = os.getenv("HF_DATA_REPO_ID")
26
  HF_DATA_TOKEN = os.getenv("HF_DATA_TOKEN")
27
 
28
- # ----- μ—°κ²° ν’€: Thin + mTLS (μ§€κ°‘) -----
29
- # μ ˆλŒ€ ν˜ΈμΆœν•˜μ§€ λ§ˆμ„Έμš”: oracledb.init_oracle_client() # (Thick둜 λΉ μ Έμ„œ μ‹€νŒ¨ κ°€λŠ₯)
30
- pool: oracledb.ConnectionPool = oracledb.create_pool(
31
- user=DB_USER,
32
- password=DB_PASSWORD,
33
- dsn=TNS_ALIAS, # Wallet tnsnames.ora의 alias
34
- config_dir=WALLET_DIR,
35
- wallet_location=WALLET_DIR,
36
- wallet_password=WALLET_PASSWORD,
37
- min=1, max=4, increment=1,
38
- homogeneous=True,
39
- timeout=60,
40
- retry_count=6, retry_delay=2
41
- )
42
-
43
- app = FastAPI(title="MuscleCare Hybrid Server (mTLS)")
44
 
45
  # ----- λͺ¨λΈ -----
46
- class StatePayload(BaseModel):
47
- model_config = ConfigDict(protected_namespaces=())
48
-
49
- user_id: str
50
- rms_base: Optional[float] = None
51
- freq_base: Optional[float] = None
52
- user_emb: Optional[List[float]] = Field(default=None, description="length=12")
53
- model_version: Optional[str] = None
54
-
55
  class LogUploadPayload(BaseModel):
56
  user_id: str
57
  session_id: str
@@ -84,10 +49,6 @@ class BatchLogsPayload(BaseModel):
84
  batch_data: List[BatchLogItem]
85
 
86
 
87
- # ----- μœ ν‹Έ -----
88
- def clob_json(obj) -> str:
89
- return json.dumps(obj, separators=(",", ":"), ensure_ascii=False)
90
-
91
  # ----- μ—”λ“œν¬μΈνŠΈ -----
92
  @app.get("/")
93
  def root():
@@ -98,9 +59,7 @@ def root():
98
  "version": "1.0.0",
99
  "endpoints": {
100
  "health": "/health (λΉ λ₯Έ 체크)",
101
- "health_db": "/health/db (DB μ—°κ²° 체크)",
102
  "docs": "/docs",
103
- "upload_state": "/upload_state",
104
  "upload_logs": "/upload_logs (κ°œλ³„ 둜그 데이터)",
105
  "user_dataset": "/user_dataset/{user_id}"
106
  }
@@ -119,61 +78,6 @@ def health():
119
  except Exception as e:
120
  return {"ok": False, "error": str(e)}
121
 
122
- @app.get("/health/db")
123
- def health_db():
124
- """DB 연결을 ν¬ν•¨ν•œ 상세 health 체크"""
125
- try:
126
- with pool.acquire() as conn:
127
- with conn.cursor() as cur:
128
- cur.execute("SELECT 1 FROM DUAL")
129
- v = cur.fetchone()[0]
130
- return {"ok": True, "db": v, "server": "running"}
131
- except Exception as e:
132
- return {"ok": False, "db": "error", "error": str(e)}
133
-
134
- @app.post("/upload_state")
135
- def upload_state(p: StatePayload):
136
- # MERGE INTO MuscleCare.user_state
137
- try:
138
- emb_json = None
139
- if p.user_emb is not None:
140
- if len(p.user_emb) != 12:
141
- raise HTTPException(400, "user_emb must have length=12")
142
- emb_json = clob_json(p.user_emb)
143
-
144
- with pool.acquire() as conn:
145
- with conn.cursor() as cur:
146
- cur.execute("""
147
- MERGE INTO user_state t
148
- USING (
149
- SELECT :user_id AS user_id FROM dual
150
- ) s
151
- ON (t.user_id = s.user_id)
152
- WHEN MATCHED THEN UPDATE SET
153
- rms_base = :rms_base,
154
- freq_base = :freq_base,
155
- user_emb = :user_emb,
156
- model_version = :model_version,
157
- last_sync = CURRENT_TIMESTAMP
158
- WHEN NOT MATCHED THEN INSERT
159
- (user_id, rms_base, freq_base, user_emb, model_version, last_sync)
160
- VALUES
161
- (:user_id, :rms_base, :freq_base, :user_emb, :model_version, CURRENT_TIMESTAMP)
162
- """, dict(
163
- user_id=p.user_id,
164
- rms_base=p.rms_base,
165
- freq_base=p.freq_base,
166
- user_emb=emb_json,
167
- model_version=p.model_version
168
- ))
169
- conn.commit()
170
- return {"ok": True}
171
- except HTTPException:
172
- raise
173
- except Exception as e:
174
- raise HTTPException(500, f"upload_state failed: {e}")
175
-
176
-
177
  @app.post("/upload_logs")
178
  async def upload_logs(payload: LogUploadPayload):
179
  """κ°œλ³„ 둜그 데이터λ₯Ό Hugging Face Hub둜 ν‘Έμ‹œ"""
 
1
  import os
 
2
  from typing import List, Optional
3
  from fastapi import FastAPI, HTTPException
4
+ from pydantic import BaseModel, Field
 
5
  from dotenv import load_dotenv
6
  import pandas as pd
7
  from datetime import datetime
 
10
  # 둜컬 개발: .env 파일 λ‘œλ“œ (있으면)
11
  load_dotenv()
12
 
 
 
 
 
 
 
 
 
 
13
  # Hugging Face μ„€μ •
14
  HF_DATA_REPO_ID = os.getenv("HF_DATA_REPO_ID")
15
  HF_DATA_TOKEN = os.getenv("HF_DATA_TOKEN")
16
 
17
+ app = FastAPI(title="MuscleCare FastAPI Server")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  # ----- λͺ¨λΈ -----
 
 
 
 
 
 
 
 
 
20
  class LogUploadPayload(BaseModel):
21
  user_id: str
22
  session_id: str
 
49
  batch_data: List[BatchLogItem]
50
 
51
 
 
 
 
 
52
  # ----- μ—”λ“œν¬μΈνŠΈ -----
53
  @app.get("/")
54
  def root():
 
59
  "version": "1.0.0",
60
  "endpoints": {
61
  "health": "/health (λΉ λ₯Έ 체크)",
 
62
  "docs": "/docs",
 
63
  "upload_logs": "/upload_logs (κ°œλ³„ 둜그 데이터)",
64
  "user_dataset": "/user_dataset/{user_id}"
65
  }
 
78
  except Exception as e:
79
  return {"ok": False, "error": str(e)}
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  @app.post("/upload_logs")
82
  async def upload_logs(payload: LogUploadPayload):
83
  """κ°œλ³„ 둜그 데이터λ₯Ό Hugging Face Hub둜 ν‘Έμ‹œ"""
requirements.txt CHANGED
@@ -1,7 +1,6 @@
1
  fastapi
2
  uvicorn
3
  python-multipart
4
- oracledb>=2.3
5
  pydantic
6
  python-dotenv
7
  datasets
 
1
  fastapi
2
  uvicorn
3
  python-multipart
 
4
  pydantic
5
  python-dotenv
6
  datasets
start.py CHANGED
@@ -1,5 +1,6 @@
1
- import os, base64, zipfile, io, sys, tempfile, subprocess
2
- from pathlib import Path
 
3
  from dotenv import load_dotenv
4
 
5
  # .env 파일 λ‘œλ“œ (둜컬 개발용)
@@ -12,88 +13,21 @@ def setup_environment():
12
  - Hugging Face Space: ν™˜κ²½λ³€μˆ˜μ—μ„œ μžλ™ μ„€μ •
13
  """
14
  print("πŸ”§ ν™˜κ²½λ³€μˆ˜ μ„€μ • 쀑...")
15
-
16
- # Hugging Face Dataset μ„€μ • (κΈ°λ³Έκ°’ μ„€μ •)
17
- if not os.getenv("HF_DATA_REPO_ID"):
18
- os.environ["HF_DATA_REPO_ID"] = os.getenv("HF_DATA_REPO_ID")
19
- print("πŸ“ HF_DATA_REPO_ID κΈ°λ³Έκ°’ μ„€μ •")
20
-
21
- if not os.getenv("HF_DATA_TOKEN"):
22
- os.environ["HF_DATA_TOKEN"] = os.getenv("HF_DATA_TOKEN")
23
- print("πŸ“ HF_DATA_TOKEN κΈ°λ³Έκ°’ μ„€μ •")
24
-
25
- # Oracle DB μ„€μ • 확인
26
- required_vars = ["DB_USER", "DB_PASSWORD", "WALLET_DIR", "WALLET_PASSWORD"]
27
- missing_vars = []
28
-
29
- for var in required_vars:
30
- if not os.getenv(var):
31
- missing_vars.append(var)
32
-
33
- if missing_vars:
34
- print(f"⚠️ λˆ„λ½λœ ν™˜κ²½λ³€μˆ˜: {', '.join(missing_vars)}")
35
- print("πŸ’‘ .env νŒŒμΌμ„ ν™•μΈν•˜κ±°λ‚˜ ν™˜κ²½λ³€μˆ˜λ₯Ό μ„€μ •ν•΄μ£Όμ„Έμš”.")
36
-
37
- # 둜컬 κ°œλ°œμ„ μœ„ν•œ κΈ°λ³Έκ°’ μ„€μ • (경고와 ν•¨κ»˜)
38
- if not os.getenv("DB_USER"):
39
- os.environ["DB_USER"] = "ADMIN"
40
- print("πŸ“ DB_USER κΈ°λ³Έκ°’ μ„€μ •: ADMIN")
41
- if not os.getenv("DB_PASSWORD"):
42
- os.environ["DB_PASSWORD"] = "YourDBPassword123!"
43
- print("πŸ“ DB_PASSWORD κΈ°λ³Έκ°’ μ„€μ •: YourDBPassword123!")
44
- if not os.getenv("WALLET_PASSWORD"):
45
- os.environ["WALLET_PASSWORD"] = "YourWalletPassword123!"
46
- print("πŸ“ WALLET_PASSWORD κΈ°λ³Έκ°’ μ„€μ •: YourWalletPassword123!")
47
  else:
48
- print("βœ… λͺ¨λ“  ν•„μˆ˜ ν™˜κ²½λ³€μˆ˜κ°€ μ„€μ •λ˜μ—ˆμŠ΅λ‹ˆλ‹€")
49
-
50
- print("πŸ”§ ν™˜κ²½λ³€μˆ˜ μ„€μ • μ™„λ£Œ")
51
 
52
- def prepare_wallet_dir():
53
- """
54
- Wallet μ€€λΉ„:
55
- - 배포 ν™˜κ²½: WALLET_ZIP_B64μ—μ„œ λ””μ½”λ”©
56
- - 둜컬 ν™˜κ²½: WALLET_DIR 경둜 μ‚¬μš©
57
- """
58
- # 둜컬 개발: WALLET_DIR이 이미 μ„€μ •λ˜μ–΄ μžˆλŠ” 경우
59
- if "WALLET_DIR" in os.environ:
60
- wallet_dir = os.environ["WALLET_DIR"]
61
- if Path(wallet_dir).exists():
62
- print(f"πŸ“ 둜컬 Wallet μ‚¬μš©: {wallet_dir}")
63
- return wallet_dir
64
-
65
- # 배포 ν™˜κ²½: WALLET_ZIP_B64μ—μ„œ λ””μ½”λ”©
66
- if "WALLET_ZIP_B64" not in os.environ:
67
- raise RuntimeError(
68
- "❌ WALLET_ZIP_B64 λ˜λŠ” WALLET_DIR ν™˜κ²½ λ³€μˆ˜κ°€ ν•„μš”ν•©λ‹ˆλ‹€.\n"
69
- " 둜컬: .env νŒŒμΌμ— WALLET_DIR μ„€μ •\n"
70
- " 배포: Hugging Face Secrets에 WALLET_ZIP_B64 μ„€μ •"
71
- )
72
-
73
- print("πŸ” Wallet Base64 λ””μ½”λ”© μ‹œμž‘...")
74
- b64 = os.environ["WALLET_ZIP_B64"]
75
- wallet_password = os.environ["WALLET_PASSWORD"]
76
-
77
- # wallet을 λ©”λͺ¨λ¦¬->μž„μ‹œλ””λ ‰ν† λ¦¬λ‘œ 볡원
78
- wallet_dir = tempfile.mkdtemp(prefix="wallet_")
79
- print(f"πŸ“ μž„μ‹œ 디렉토리: {wallet_dir}")
80
-
81
- zip_bytes = base64.b64decode(b64)
82
- with zipfile.ZipFile(io.BytesIO(zip_bytes)) as z:
83
- z.extractall(wallet_dir)
84
-
85
- # μ•ˆμ „μ„ μœ„ν•΄ κΆŒν•œ μΆ•μ†Œ
86
- for root, _, files in os.walk(wallet_dir):
87
- for f in files:
88
- os.chmod(os.path.join(root, f), 0o600)
89
-
90
- print("βœ… Wallet μ••μΆ• ν•΄μ œ μ™„λ£Œ")
91
-
92
- # μ§€κ°‘ λΉ„λ°€λ²ˆν˜ΈλŠ” oracledbμ—μ„œ μ‚¬μš©
93
- os.environ["WALLET_DIR"] = wallet_dir
94
- os.environ["WALLET_PASSWORD"] = wallet_password
95
-
96
- return wallet_dir
97
 
98
  if __name__ == "__main__":
99
  print("=" * 60)
@@ -103,13 +37,6 @@ if __name__ == "__main__":
103
  # ν™˜κ²½λ³€μˆ˜ μžλ™ μ„€μ •
104
  setup_environment()
105
 
106
- # Wallet μ€€λΉ„
107
- try:
108
- prepare_wallet_dir()
109
- except Exception as e:
110
- print(f"❌ Wallet μ€€λΉ„ μ‹€νŒ¨: {e}")
111
- sys.exit(1)
112
-
113
  # Uvicorn 기동
114
  print("\n🌐 FastAPI μ„œλ²„ μ‹€ν–‰...")
115
  print("=" * 60)
 
1
+ import os
2
+ import sys
3
+ import subprocess
4
  from dotenv import load_dotenv
5
 
6
  # .env 파일 λ‘œλ“œ (둜컬 개발용)
 
13
  - Hugging Face Space: ν™˜κ²½λ³€μˆ˜μ—μ„œ μžλ™ μ„€μ •
14
  """
15
  print("πŸ”§ ν™˜κ²½λ³€μˆ˜ μ„€μ • 쀑...")
16
+
17
+ hf_repo = os.getenv("HF_DATA_REPO_ID")
18
+ hf_token = os.getenv("HF_DATA_TOKEN")
19
+
20
+ if hf_repo:
21
+ print("βœ… HF_DATA_REPO_ID μ„€μ • μ™„λ£Œ")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  else:
23
+ print("ℹ️ HF_DATA_REPO_IDκ°€ μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. Hugging Face μ—…λ‘œλ“œ κΈ°λŠ₯이 μ œν•œλ  수 μžˆμŠ΅λ‹ˆλ‹€.")
 
 
24
 
25
+ if hf_token:
26
+ print("βœ… HF_DATA_TOKEN μ„€μ • μ™„λ£Œ")
27
+ else:
28
+ print("ℹ️ HF_DATA_TOKEN이 μ„€μ •λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. Hugging Face μ—…λ‘œλ“œ κΈ°λŠ₯이 μ œν•œλ  수 μžˆμŠ΅λ‹ˆλ‹€.")
29
+
30
+ print("πŸ”§ ν™˜κ²½λ³€μˆ˜ μ„€μ • μ™„λ£Œ")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  if __name__ == "__main__":
33
  print("=" * 60)
 
37
  # ν™˜κ²½λ³€μˆ˜ μžλ™ μ„€μ •
38
  setup_environment()
39
 
 
 
 
 
 
 
 
40
  # Uvicorn 기동
41
  print("\n🌐 FastAPI μ„œλ²„ μ‹€ν–‰...")
42
  print("=" * 60)
start_server.sh CHANGED
@@ -19,7 +19,7 @@ echo "πŸ”§ ν™˜κ²½λ³€μˆ˜λŠ” start.pyμ—μ„œ μžλ™μœΌλ‘œ μ„€μ •λ©λ‹ˆλ‹€."
19
 
20
  # Python μ˜μ‘΄μ„± 확인 및 μ„€μΉ˜
21
  echo "πŸ“¦ Python μ˜μ‘΄μ„± 확인 쀑..."
22
- if ! python3 -c "import fastapi, uvicorn, oracledb" 2>/dev/null; then
23
  echo "❌ ν•„μˆ˜ Python νŒ¨ν‚€μ§€κ°€ μ„€μΉ˜λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€."
24
  echo "πŸ”§ μžλ™ μ„€μΉ˜λ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€..."
25
 
@@ -38,7 +38,7 @@ if ! python3 -c "import fastapi, uvicorn, oracledb" 2>/dev/null; then
38
  fi
39
 
40
  # μ„€μΉ˜ ν›„ λ‹€μ‹œ 확인
41
- if ! python3 -c "import fastapi, uvicorn, oracledb" 2>/dev/null; then
42
  echo "❌ νŒ¨ν‚€μ§€ μ„€μΉ˜μ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€."
43
  echo "πŸ’‘ μˆ˜λ™μœΌλ‘œ μ„€μΉ˜ν•΄μ£Όμ„Έμš”:"
44
  echo " pip3 install -r requirements.txt"
 
19
 
20
  # Python μ˜μ‘΄μ„± 확인 및 μ„€μΉ˜
21
  echo "πŸ“¦ Python μ˜μ‘΄μ„± 확인 쀑..."
22
+ if ! python3 -c "import fastapi, uvicorn" 2>/dev/null; then
23
  echo "❌ ν•„μˆ˜ Python νŒ¨ν‚€μ§€κ°€ μ„€μΉ˜λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€."
24
  echo "πŸ”§ μžλ™ μ„€μΉ˜λ₯Ό μ‹œμž‘ν•©λ‹ˆλ‹€..."
25
 
 
38
  fi
39
 
40
  # μ„€μΉ˜ ν›„ λ‹€μ‹œ 확인
41
+ if ! python3 -c "import fastapi, uvicorn" 2>/dev/null; then
42
  echo "❌ νŒ¨ν‚€μ§€ μ„€μΉ˜μ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€."
43
  echo "πŸ’‘ μˆ˜λ™μœΌλ‘œ μ„€μΉ˜ν•΄μ£Όμ„Έμš”:"
44
  echo " pip3 install -r requirements.txt"