asefasdfcv commited on
Commit
3e28ecb
ยท
verified ยท
1 Parent(s): aab7742

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +80 -94
main.py CHANGED
@@ -5,6 +5,8 @@ import os
5
  import sys
6
  import logging
7
  import tempfile
 
 
8
  from fastapi import FastAPI, Request, HTTPException, Query, Body
9
  from fastapi.middleware.cors import CORSMiddleware
10
  from fastapi.responses import JSONResponse
@@ -13,9 +15,6 @@ import json
13
  import base64
14
  from io import BytesIO
15
  from PIL import Image
16
- import time
17
- import traceback
18
- from db_connector import fetch_found_items, count_found_items
19
 
20
  # ์บ์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์„ค์ • ๋ฐ ์ตœ์ ํ™”
21
  CACHE_DIRS = {
@@ -25,8 +24,17 @@ CACHE_DIRS = {
25
  'UPLOADS_DIR': '/tmp/uploads'
26
  }
27
 
28
- # ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ (๊ธฐ๋ณธ๊ฐ’ ์„ค์ •)
 
 
 
 
 
 
 
29
 
 
 
30
  os.environ.setdefault('DB_HOST', 'localhost')
31
  os.environ.setdefault('DB_PORT', '3306')
32
  os.environ.setdefault('DB_USER', 'username') # ์‹ค์ œ ์‚ฌ์šฉ์‹œ ๋ณ€๊ฒฝ ํ•„์š”
@@ -36,48 +44,6 @@ os.environ.setdefault('DB_NAME', 'foundlost')
36
  # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ™˜๊ฒฝ ์„ค์ • (development, production, test)
37
  os.environ.setdefault('APP_ENV', 'development')
38
 
39
- # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์ด๋ฒคํŠธ ์ˆ˜์ •
40
- @app.on_event("startup")
41
- async def startup_event():
42
- """
43
- ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ์‹คํ–‰๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
44
- """
45
- logger.info("์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์ค‘...")
46
- try:
47
- # ๋ชจ๋ธ ์‚ฌ์ „ ๋‹ค์šด๋กœ๋“œ (๋น„๋™๊ธฐ์ ์œผ๋กœ)
48
- from models.clip_model import preload_clip_model
49
- preload_clip_model()
50
- logger.info("๋ชจ๋ธ ์‚ฌ์ „ ๋‹ค์šด๋กœ๋“œ ์™„๋ฃŒ")
51
-
52
- # ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ
53
- if os.getenv('APP_ENV') != 'test':
54
- try:
55
- from db_connector import get_db_connection
56
- with get_db_connection() as connection:
57
- with connection.cursor() as cursor:
58
- cursor.execute("SELECT 1")
59
- result = cursor.fetchone()
60
- if result:
61
- logger.info("โœ… ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ์„ฑ๊ณต")
62
- else:
63
- logger.warning("โš ๏ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ์—†์Œ")
64
- except Exception as db_error:
65
- logger.error(f"โŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ์‹คํŒจ: {str(db_error)}")
66
- logger.error(traceback.format_exc())
67
-
68
- except Exception as e:
69
- logger.error(f"์‹œ์ž‘ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
70
- logger.error(traceback.format_exc())
71
-
72
- # ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •
73
- for key, path in CACHE_DIRS.items():
74
- os.environ[key] = path
75
- os.makedirs(path, exist_ok=True)
76
-
77
- # ์ถ”๊ฐ€ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ตœ์ ํ™”
78
- os.environ['HF_HUB_DISABLE_TELEMETRY'] = '1'
79
- os.environ['TRANSFORMERS_VERBOSITY'] = 'error'
80
-
81
  # ๋กœ๊น… ์„ค์ • ๊ฐœ์„ 
82
  logging.basicConfig(
83
  level=logging.INFO,
@@ -166,53 +132,6 @@ def get_clip_model(force_reload=False):
166
  # ์‹คํŒจ ์‹œ None ๋ฐ˜ํ™˜
167
  return None
168
  return clip_model
169
-
170
- # FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ
171
- app = FastAPI(
172
- title="์Šต๋“๋ฌผ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰ API",
173
- description="ํ•œ๊ตญ์–ด CLIP ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ๊ฒŒ์‹œ๊ธ€๊ณผ ์Šต๋“๋ฌผ ๊ฐ„์˜ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” API",
174
- version="1.0.0"
175
- )
176
-
177
- # CORS ๋ฏธ๋“ค์›จ์–ด ์„ค์ •
178
- app.add_middleware(
179
- CORSMiddleware,
180
- allow_origins=["*"],
181
- allow_credentials=True,
182
- allow_methods=["*"],
183
- allow_headers=["*"],
184
- )
185
-
186
- # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์ด๋ฒคํŠธ
187
- @app.on_event("startup")
188
- async def startup_event():
189
- """
190
- ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ์‹คํ–‰๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
191
- """
192
- logger.info("์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์ค‘...")
193
- try:
194
- # ๋ชจ๋ธ ์‚ฌ์ „ ๋‹ค์šด๋กœ๋“œ (๋น„๋™๊ธฐ์ ์œผ๋กœ)
195
- from models.clip_model import preload_clip_model
196
- preload_clip_model()
197
- logger.info("๋ชจ๋ธ ์‚ฌ์ „ ๋‹ค์šด๋กœ๋“œ ์™„๋ฃŒ")
198
- except Exception as e:
199
- logger.error(f"์‹œ์ž‘ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
200
- logger.error(traceback.format_exc())
201
-
202
- # ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
203
- @app.exception_handler(Exception)
204
- async def global_exception_handler(request: Request, exc: Exception):
205
- """
206
- ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ
207
- """
208
- logger.error(f"์š”์ฒญ ์ฒ˜๋ฆฌ ์ค‘ ์˜ˆ์™ธ ๋ฐœ์ƒ: {str(exc)}")
209
- return JSONResponse(
210
- status_code=500,
211
- content={"success": False, "message": f"์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(exc)}"}
212
- )
213
-
214
- # ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ชจ๋“ˆ ์ž„ํฌํŠธ
215
- from utils.similarity import calculate_similarity, find_similar_items, CATEGORY_WEIGHT, ITEM_NAME_WEIGHT, COLOR_WEIGHT, CONTENT_WEIGHT
216
 
217
  # ๋‚ด๋ถ€์ ์œผ๋กœ ์Šต๋“๋ฌผ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜
218
  async def fetch_found_items(limit=100, offset=0):
@@ -272,6 +191,73 @@ async def fetch_found_items(limit=100, offset=0):
272
 
273
  # ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ๋นˆ ๋ชฉ๋ก ๋ฐ˜ํ™˜
274
  return []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
275
 
276
  # API ์—”๋“œํฌ์ธํŠธ ์ •์˜ - Spring Boot์— ๋งž๊ฒŒ ์ˆ˜์ •
277
  @app.post("/api/matching/find-similar", response_model=MatchingResponse)
@@ -463,7 +449,7 @@ async def find_similar_items_api(
463
  }
464
 
465
  return JSONResponse(status_code=500, content=error_response)
466
-
467
  @app.get("/api/matching/test")
468
  async def test_endpoint():
469
  """
 
5
  import sys
6
  import logging
7
  import tempfile
8
+ import traceback
9
+ import time
10
  from fastapi import FastAPI, Request, HTTPException, Query, Body
11
  from fastapi.middleware.cors import CORSMiddleware
12
  from fastapi.responses import JSONResponse
 
15
  import base64
16
  from io import BytesIO
17
  from PIL import Image
 
 
 
18
 
19
  # ์บ์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์„ค์ • ๋ฐ ์ตœ์ ํ™”
20
  CACHE_DIRS = {
 
24
  'UPLOADS_DIR': '/tmp/uploads'
25
  }
26
 
27
+ # ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์„ค์ •
28
+ for key, path in CACHE_DIRS.items():
29
+ os.environ[key] = path
30
+ os.makedirs(path, exist_ok=True)
31
+
32
+ # ์ถ”๊ฐ€ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ตœ์ ํ™”
33
+ os.environ['HF_HUB_DISABLE_TELEMETRY'] = '1'
34
+ os.environ['TRANSFORMERS_VERBOSITY'] = 'error'
35
 
36
+ # ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ จ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ (๊ธฐ๋ณธ๊ฐ’ ์„ค์ •)
37
+ # ์‹ค์ œ ํ™˜๊ฒฝ์—์„œ๋Š” .env ํŒŒ์ผ์ด๋‚˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ •ํ•ด์•ผ ํ•จ
38
  os.environ.setdefault('DB_HOST', 'localhost')
39
  os.environ.setdefault('DB_PORT', '3306')
40
  os.environ.setdefault('DB_USER', 'username') # ์‹ค์ œ ์‚ฌ์šฉ์‹œ ๋ณ€๊ฒฝ ํ•„์š”
 
44
  # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ™˜๊ฒฝ ์„ค์ • (development, production, test)
45
  os.environ.setdefault('APP_ENV', 'development')
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  # ๋กœ๊น… ์„ค์ • ๊ฐœ์„ 
48
  logging.basicConfig(
49
  level=logging.INFO,
 
132
  # ์‹คํŒจ ์‹œ None ๋ฐ˜ํ™˜
133
  return None
134
  return clip_model
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
  # ๋‚ด๋ถ€์ ์œผ๋กœ ์Šต๋“๋ฌผ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๋Š” ํ•จ์ˆ˜
137
  async def fetch_found_items(limit=100, offset=0):
 
191
 
192
  # ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ๋นˆ ๋ชฉ๋ก ๋ฐ˜ํ™˜
193
  return []
194
+
195
+ # FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ƒ์„ฑ
196
+ app = FastAPI(
197
+ title="์Šต๋“๋ฌผ ์œ ์‚ฌ๋„ ๊ฒ€์ƒ‰ API",
198
+ description="ํ•œ๊ตญ์–ด CLIP ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ๊ฒŒ์‹œ๊ธ€๊ณผ ์Šต๋“๋ฌผ ๊ฐ„์˜ ์œ ์‚ฌ๋„๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” API",
199
+ version="1.0.0"
200
+ )
201
+
202
+ # CORS ๋ฏธ๋“ค์›จ์–ด ์„ค์ •
203
+ app.add_middleware(
204
+ CORSMiddleware,
205
+ allow_origins=["*"],
206
+ allow_credentials=True,
207
+ allow_methods=["*"],
208
+ allow_headers=["*"],
209
+ )
210
+
211
+ # ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์ด๋ฒคํŠธ
212
+ @app.on_event("startup")
213
+ async def startup_event():
214
+ """
215
+ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ์‹คํ–‰๋˜๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
216
+ """
217
+ logger.info("์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์ค‘...")
218
+ try:
219
+ # ๋ชจ๋ธ ์‚ฌ์ „ ๋‹ค์šด๋กœ๋“œ (๋น„๋™๊ธฐ์ ์œผ๋กœ)
220
+ from models.clip_model import preload_clip_model
221
+ preload_clip_model()
222
+ logger.info("๋ชจ๋ธ ์‚ฌ์ „ ๋‹ค์šด๋กœ๋“œ ์™„๋ฃŒ")
223
+
224
+ # ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ
225
+ if os.getenv('APP_ENV') != 'test':
226
+ try:
227
+ from db_connector import get_db_connection
228
+ with get_db_connection() as connection:
229
+ with connection.cursor() as cursor:
230
+ cursor.execute("SELECT 1")
231
+ result = cursor.fetchone()
232
+ if result:
233
+ logger.info("โœ… ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ์„ฑ๊ณต")
234
+ else:
235
+ logger.warning("โš ๏ธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ์—†์Œ")
236
+ except Exception as db_error:
237
+ logger.error(f"โŒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ์‹คํŒจ: {str(db_error)}")
238
+ logger.error(traceback.format_exc())
239
+
240
+ except Exception as e:
241
+ logger.error(f"์‹œ์ž‘ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
242
+ logger.error(traceback.format_exc())
243
+
244
+ # ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ
245
+ @app.exception_handler(Exception)
246
+ async def global_exception_handler(request: Request, exc: Exception):
247
+ """
248
+ ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ
249
+ """
250
+ logger.error(f"์š”์ฒญ ์ฒ˜๋ฆฌ ์ค‘ ์˜ˆ์™ธ ๋ฐœ์ƒ: {str(exc)}")
251
+ return JSONResponse(
252
+ status_code=500,
253
+ content={"success": False, "message": f"์„œ๋ฒ„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค: {str(exc)}"}
254
+ )
255
+
256
+ # ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ชจ๋“ˆ ์ž„ํฌํŠธ
257
+ from utils.similarity import calculate_similarity, find_similar_items, CATEGORY_WEIGHT, ITEM_NAME_WEIGHT, COLOR_WEIGHT, CONTENT_WEIGHT
258
+
259
+ # ์ด ๋ฐ์ดํ„ฐ ๊ฐœ์ˆ˜ ์กฐํšŒ ํ•จ์ˆ˜ ์ž„ํฌํŠธ
260
+ from db_connector import count_found_items
261
 
262
  # API ์—”๋“œํฌ์ธํŠธ ์ •์˜ - Spring Boot์— ๋งž๊ฒŒ ์ˆ˜์ •
263
  @app.post("/api/matching/find-similar", response_model=MatchingResponse)
 
449
  }
450
 
451
  return JSONResponse(status_code=500, content=error_response)
452
+
453
  @app.get("/api/matching/test")
454
  async def test_endpoint():
455
  """