aiteamutils 0.2.32__py3-none-any.whl → 0.2.33__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
aiteamutils/config.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """설정 모듈."""
2
2
  from typing import Union
3
3
  from .database import init_database_service
4
+ from .exceptions import CustomException, ErrorCode
4
5
 
5
6
  class Settings:
6
7
  """기본 설정 클래스"""
@@ -74,8 +75,12 @@ def get_settings() -> Settings:
74
75
  Settings: 설정 객체
75
76
 
76
77
  Raises:
77
- RuntimeError: 설정이 초기화되지 않은 경우
78
+ CustomException: 설정이 초기화되지 않은 경우
78
79
  """
79
80
  if _settings is None:
80
- raise RuntimeError("Settings not initialized. Call init_settings first.")
81
+ raise CustomException(
82
+ ErrorCode.INTERNAL_ERROR,
83
+ detail="settings",
84
+ source_function="get_settings"
85
+ )
81
86
  return _settings
aiteamutils/database.py CHANGED
@@ -26,10 +26,14 @@ def get_database_service() -> 'DatabaseService':
26
26
  DatabaseService: DatabaseService 인스턴스
27
27
 
28
28
  Raises:
29
- RuntimeError: DatabaseService가 초기화되지 않은 경우
29
+ CustomException: DatabaseService가 초기화되지 않은 경우
30
30
  """
31
31
  if _database_service is None:
32
- raise RuntimeError("DatabaseService not initialized. Call init_settings with db_url first.")
32
+ raise CustomException(
33
+ ErrorCode.DB_CONNECTION_ERROR,
34
+ detail="database_service",
35
+ source_function="get_database_service"
36
+ )
33
37
  return _database_service
34
38
 
35
39
  async def get_db() -> AsyncGenerator[AsyncSession, None]:
@@ -100,13 +104,21 @@ class DatabaseService:
100
104
  )
101
105
  self.db = session
102
106
  else:
103
- raise ValueError("Either db_url or session must be provided")
107
+ raise CustomException(
108
+ ErrorCode.DB_CONNECTION_ERROR,
109
+ detail="db_url|session",
110
+ source_function="DatabaseService.__init__"
111
+ )
104
112
 
105
113
  @asynccontextmanager
106
114
  async def get_session(self) -> AsyncGenerator[AsyncSession, None]:
107
115
  """데이터베이스 세션을 생성하고 반환하는 비동기 컨텍스트 매니저."""
108
116
  if self.session_factory is None:
109
- raise RuntimeError("Session factory not initialized")
117
+ raise CustomException(
118
+ ErrorCode.DB_CONNECTION_ERROR,
119
+ detail="session_factory",
120
+ source_function="DatabaseService.get_session"
121
+ )
110
122
 
111
123
  async with self.session_factory() as session:
112
124
  try:
@@ -26,10 +26,14 @@ class ServiceRegistry:
26
26
  service_class (Type): Service 클래스
27
27
 
28
28
  Raises:
29
- ValueError: 이미 등록된 서비스인 경우
29
+ CustomException: 이미 등록된 서비스인 경우
30
30
  """
31
31
  if name in self._services:
32
- raise ValueError(f"Service '{name}' is already registered.")
32
+ raise CustomException(
33
+ ErrorCode.INTERNAL_ERROR,
34
+ detail=f"service|{name}",
35
+ source_function="ServiceRegistry.register"
36
+ )
33
37
  self._services[name] = (repository_class, service_class)
34
38
 
35
39
  def get(self, name: str) -> Tuple[Type, Type]:
@@ -42,10 +46,14 @@ class ServiceRegistry:
42
46
  Tuple[Type, Type]: (Repository 클래스, Service 클래스) 튜플
43
47
 
44
48
  Raises:
45
- ValueError: 등록되지 않은 서비스인 경우
49
+ CustomException: 등록되지 않은 서비스인 경우
46
50
  """
47
51
  if name not in self._services:
48
- raise ValueError(f"Service '{name}' is not registered.")
52
+ raise CustomException(
53
+ ErrorCode.NOT_FOUND,
54
+ detail=f"service|{name}",
55
+ source_function="ServiceRegistry.get"
56
+ )
49
57
  return self._services[name]
50
58
 
51
59
  # ServiceRegistry 초기화
aiteamutils/security.py CHANGED
@@ -157,8 +157,19 @@ def verify_password(plain_password: str, hashed_password: str) -> bool:
157
157
 
158
158
  Returns:
159
159
  bool: 비밀번호 일치 여부
160
+
161
+ Raises:
162
+ CustomException: 비밀번호 검증 실패 시
160
163
  """
161
- return pwd_context.verify(plain_password, hashed_password)
164
+ try:
165
+ return pwd_context.verify(plain_password, hashed_password)
166
+ except Exception as e:
167
+ raise CustomException(
168
+ ErrorCode.INVALID_PASSWORD,
169
+ detail=plain_password,
170
+ source_function="security.verify_password",
171
+ original_error=e
172
+ )
162
173
 
163
174
  def hash_password(password: str) -> str:
164
175
  """비밀번호를 해시화합니다.
@@ -168,8 +179,19 @@ def hash_password(password: str) -> str:
168
179
 
169
180
  Returns:
170
181
  str: 해시된 비밀번호
182
+
183
+ Raises:
184
+ CustomException: 비밀번호 해시화 실패 시
171
185
  """
172
- return pwd_context.hash(password)
186
+ try:
187
+ return pwd_context.hash(password)
188
+ except Exception as e:
189
+ raise CustomException(
190
+ ErrorCode.INTERNAL_ERROR,
191
+ detail=password,
192
+ source_function="security.hash_password",
193
+ original_error=e
194
+ )
173
195
 
174
196
  def rate_limit(
175
197
  max_requests: int,
@@ -288,10 +310,10 @@ async def create_jwt_token(
288
310
  required_fields = {"username", "ulid"}
289
311
  missing_fields = required_fields - set(user_data.keys())
290
312
  if missing_fields:
291
- raise TokenCreationError(
292
- detail=f"Missing required fields: {', '.join(missing_fields)}",
293
- source_function="create_jwt_token",
294
- token_type=token_type
313
+ raise CustomException(
314
+ ErrorCode.REQUIRED_FIELD_MISSING,
315
+ detail="|".join(missing_fields),
316
+ source_function="security.create_jwt_token"
295
317
  )
296
318
 
297
319
  if token_type == "access":
@@ -337,10 +359,10 @@ async def create_jwt_token(
337
359
  algorithm=settings.JWT_ALGORITHM
338
360
  )
339
361
  except Exception as e:
340
- raise TokenCreationError(
341
- detail="Failed to encode JWT token",
342
- source_function="create_jwt_token",
343
- token_type=token_type,
362
+ raise CustomException(
363
+ ErrorCode.INTERNAL_ERROR,
364
+ detail=f"token|{token_type}",
365
+ source_function="security.create_jwt_token",
344
366
  original_error=e
345
367
  )
346
368
 
@@ -362,13 +384,13 @@ async def create_jwt_token(
362
384
 
363
385
  return token
364
386
 
365
- except (TokenCreationError, SecurityError) as e:
387
+ except CustomException as e:
366
388
  raise e
367
389
  except Exception as e:
368
- raise SecurityError(
390
+ raise CustomException(
369
391
  ErrorCode.INTERNAL_ERROR,
370
392
  detail=str(e),
371
- source_function="create_jwt_token",
393
+ source_function="security.create_jwt_token",
372
394
  original_error=e
373
395
  )
374
396
 
@@ -376,7 +398,18 @@ async def verify_jwt_token(
376
398
  token: str,
377
399
  expected_type: Optional[Literal["access", "refresh"]] = None
378
400
  ) -> Dict[str, Any]:
379
- """JWT 토큰을 검증합니다."""
401
+ """JWT 토큰을 검증합니다.
402
+
403
+ Args:
404
+ token: 검증할 JWT 토큰
405
+ expected_type: 예상되는 토큰 타입
406
+
407
+ Returns:
408
+ Dict[str, Any]: 토큰 페이로드
409
+
410
+ Raises:
411
+ CustomException: 토큰 검증 실패 시
412
+ """
380
413
  try:
381
414
  settings = get_settings()
382
415
  # 토큰 디코딩
@@ -390,25 +423,27 @@ async def verify_jwt_token(
390
423
 
391
424
  # 토큰 타입 검증 (expected_type이 주어진 경우에만)
392
425
  if expected_type and payload.get("token_type") != expected_type:
393
- raise TokenError(
394
- detail=f"Expected {expected_type} token but got {payload.get('token_type')}",
395
- source_function="verify_jwt_token"
426
+ raise CustomException(
427
+ ErrorCode.INVALID_TOKEN,
428
+ detail=f"token|{expected_type}|{payload.get('token_type')}",
429
+ source_function="security.verify_jwt_token"
396
430
  )
397
431
 
398
432
  return payload
399
433
 
400
434
  except JWTError as e:
401
- raise TokenError(
402
- detail=str(e),
403
- source_function="verify_jwt_token",
435
+ raise CustomException(
436
+ ErrorCode.INVALID_TOKEN,
437
+ detail=token[:10] + "...",
438
+ source_function="security.verify_jwt_token",
404
439
  original_error=e
405
440
  )
406
- except (TokenError, SecurityError) as e:
441
+ except CustomException as e:
407
442
  raise e
408
443
  except Exception as e:
409
- raise SecurityError(
444
+ raise CustomException(
410
445
  ErrorCode.INTERNAL_ERROR,
411
446
  detail=str(e),
412
- source_function="verify_jwt_token",
447
+ source_function="security.verify_jwt_token",
413
448
  original_error=e
414
449
  )
aiteamutils/version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  """버전 정보"""
2
- __version__ = "0.2.32"
2
+ __version__ = "0.2.33"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aiteamutils
3
- Version: 0.2.32
3
+ Version: 0.2.33
4
4
  Summary: AI Team Utilities
5
5
  Project-URL: Homepage, https://github.com/yourusername/aiteamutils
6
6
  Project-URL: Issues, https://github.com/yourusername/aiteamutils/issues
@@ -3,14 +3,14 @@ aiteamutils/base_model.py,sha256=ODEnjvUVoxQ1RPCfq8-uZTfTADIA4c7Z3E6G4EVsSX0,270
3
3
  aiteamutils/base_repository.py,sha256=qdwQ7Sj2fUqxpDg6cWM48n_QbwPK_VUlG9zTSem8iCk,18968
4
4
  aiteamutils/base_service.py,sha256=E4dHGE0DvhmRyFplh46SwKJOSF_nUL7OAsCkf_ZJF_8,24733
5
5
  aiteamutils/cache.py,sha256=tr0Yn8VPYA9QHiKCUzciVlQ2J1RAwNo2K9lGMH4rY3s,1334
6
- aiteamutils/config.py,sha256=7pJHBml8RRXC9FpoRBx0emofFkvtxsyk9_Rcur2F9hI,2724
7
- aiteamutils/database.py,sha256=raYKRZjEfefM3SnoPYozPu7OUGm62XWOUqZzN4_cayw,33479
8
- aiteamutils/dependencies.py,sha256=t4bYFu_u6_rhSHZH65MRmQoN74GC_1IqVK-l-wDy3Hw,3984
6
+ aiteamutils/config.py,sha256=kFKMeIx1KcuEwwx4VjZdCgoTOHCkG3ySYVJ0G6cvMoA,2849
7
+ aiteamutils/database.py,sha256=CaH73g8PPNcmLCz4Xr0DBtNSrLcpRlyt0F1zO5Tigfo,33811
8
+ aiteamutils/dependencies.py,sha256=GgN8sFM7qGNmOfpLaFrhuHOgPlBVXWrEgxv29jxjEgI,4226
9
9
  aiteamutils/enums.py,sha256=ipZi6k_QD5-3QV7Yzv7bnL0MjDz-vqfO9I5L77biMKs,632
10
10
  aiteamutils/exceptions.py,sha256=YV-ISya4wQlHk4twvGo16I5r8h22-tXpn9wa-b3WwDM,15231
11
- aiteamutils/security.py,sha256=jxJsWSjJOMVlNaBFxroIXrAgseJYKl_vQ_kfmHblPIA,13498
11
+ aiteamutils/security.py,sha256=nqAyypyiZ26s-eKv7c6YPDTK6HcqimFnoCr12Wtg1DY,14449
12
12
  aiteamutils/validators.py,sha256=3N245cZFjgwtW_KzjESkizx5BBUDaJLbbxfNO4WOFZ0,7764
13
- aiteamutils/version.py,sha256=TS_f4LH3EJgdiSTWc718XoM6nVHoW3rx_v3DZlzWJyQ,42
14
- aiteamutils-0.2.32.dist-info/METADATA,sha256=giY2qyWUxWi5xCg_krbjwleHlrgmguEemTG6QNZ3a6E,1718
15
- aiteamutils-0.2.32.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
- aiteamutils-0.2.32.dist-info/RECORD,,
13
+ aiteamutils/version.py,sha256=0u62c8uMhBIqtJ4INrTiDbrTgFVL2CBQ_nfjWnhrldU,42
14
+ aiteamutils-0.2.33.dist-info/METADATA,sha256=DUbbkj6hQ_0C7ODwi8AuQJ1W1BYAMF8_45epV7wl27I,1718
15
+ aiteamutils-0.2.33.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ aiteamutils-0.2.33.dist-info/RECORD,,