aiteamutils 0.2.41__py3-none-any.whl → 0.2.43__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/__init__.py +4 -2
- aiteamutils/cache.py +2 -1
- aiteamutils/config.py +3 -3
- aiteamutils/database.py +200 -99
- aiteamutils/dependencies.py +23 -61
- aiteamutils/version.py +1 -1
- {aiteamutils-0.2.41.dist-info → aiteamutils-0.2.43.dist-info}/METADATA +1 -1
- aiteamutils-0.2.43.dist-info/RECORD +16 -0
- aiteamutils-0.2.41.dist-info/RECORD +0 -16
- {aiteamutils-0.2.41.dist-info → aiteamutils-0.2.43.dist-info}/WHEEL +0 -0
aiteamutils/__init__.py
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
from .base_model import Base
|
2
2
|
from .database import (
|
3
3
|
DatabaseService,
|
4
|
+
DatabaseServiceManager,
|
4
5
|
get_db,
|
5
6
|
get_database_service,
|
6
|
-
|
7
|
+
lifespan
|
7
8
|
)
|
8
9
|
from .exceptions import (
|
9
10
|
CustomException,
|
@@ -35,9 +36,10 @@ __all__ = [
|
|
35
36
|
|
36
37
|
# Database
|
37
38
|
"DatabaseService",
|
39
|
+
"DatabaseServiceManager",
|
38
40
|
"get_db",
|
39
41
|
"get_database_service",
|
40
|
-
"
|
42
|
+
"lifespan",
|
41
43
|
|
42
44
|
# Exceptions
|
43
45
|
"CustomException",
|
aiteamutils/cache.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
from typing import Any, Optional
|
2
2
|
from redis.asyncio import Redis
|
3
|
-
from
|
3
|
+
from .config import get_settings
|
4
4
|
|
5
5
|
class Cache:
|
6
6
|
_instance = None
|
@@ -15,6 +15,7 @@ class Cache:
|
|
15
15
|
"""
|
16
16
|
if not cls._instance:
|
17
17
|
cls._instance = cls()
|
18
|
+
settings = get_settings()
|
18
19
|
cls._redis = Redis.from_url(settings.REDIS_URL, encoding="utf-8", decode_responses=True)
|
19
20
|
return cls._instance
|
20
21
|
|
aiteamutils/config.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"""설정 모듈."""
|
2
2
|
from typing import Union
|
3
|
-
from .database import
|
3
|
+
from .database import DatabaseServiceManager
|
4
4
|
from .exceptions import CustomException, ErrorCode
|
5
5
|
|
6
6
|
class Settings:
|
@@ -21,7 +21,7 @@ class Settings:
|
|
21
21
|
|
22
22
|
_settings: Union[Settings, None] = None
|
23
23
|
|
24
|
-
def init_settings(
|
24
|
+
async def init_settings(
|
25
25
|
jwt_secret: str,
|
26
26
|
jwt_algorithm: str = "HS256",
|
27
27
|
access_token_expire_minutes: int = 30,
|
@@ -59,7 +59,7 @@ def init_settings(
|
|
59
59
|
)
|
60
60
|
|
61
61
|
if db_url:
|
62
|
-
|
62
|
+
await DatabaseServiceManager.get_instance(
|
63
63
|
db_url=db_url,
|
64
64
|
db_echo=db_echo,
|
65
65
|
db_pool_size=db_pool_size,
|
aiteamutils/database.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import asyncio
|
2
|
+
import logging
|
1
3
|
from typing import Any, Dict, Optional, Type, AsyncGenerator, TypeVar, List, Union
|
2
4
|
from sqlalchemy import select, update, and_, Table
|
3
5
|
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, AsyncEngine
|
@@ -6,10 +8,9 @@ from sqlalchemy.exc import IntegrityError, SQLAlchemyError
|
|
6
8
|
from sqlalchemy.pool import QueuePool
|
7
9
|
from contextlib import asynccontextmanager
|
8
10
|
from sqlalchemy import or_
|
9
|
-
from fastapi import Request, Depends
|
11
|
+
from fastapi import Request, Depends, FastAPI
|
10
12
|
from ulid import ULID
|
11
13
|
from sqlalchemy.sql import Select
|
12
|
-
import logging
|
13
14
|
|
14
15
|
from .exceptions import ErrorCode, CustomException
|
15
16
|
from .base_model import Base, BaseColumn
|
@@ -17,60 +18,89 @@ from .enums import ActivityType
|
|
17
18
|
|
18
19
|
T = TypeVar("T", bound=BaseColumn)
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def get_database_service() -> 'DatabaseService':
|
24
|
-
"""DatabaseService 인스턴스를 반환하는 함수
|
21
|
+
class DatabaseServiceManager:
|
22
|
+
_instance: Optional['DatabaseService'] = None
|
23
|
+
_lock = asyncio.Lock()
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
return _database_service
|
25
|
+
@classmethod
|
26
|
+
async def get_instance(
|
27
|
+
cls,
|
28
|
+
db_url: str = None,
|
29
|
+
db_echo: bool = False,
|
30
|
+
db_pool_size: int = 5,
|
31
|
+
db_max_overflow: int = 10,
|
32
|
+
db_pool_timeout: int = 30,
|
33
|
+
db_pool_recycle: int = 1800,
|
34
|
+
**kwargs
|
35
|
+
) -> 'DatabaseService':
|
36
|
+
"""데이터베이스 서비스의 싱글톤 인스턴스를 반환합니다.
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
CustomException: 세션 생성 실패 시
|
48
|
-
"""
|
49
|
-
db_service = get_database_service()
|
50
|
-
try:
|
51
|
-
async with db_service.get_session() as session:
|
52
|
-
yield session
|
53
|
-
except Exception as e:
|
54
|
-
raise CustomException(
|
55
|
-
ErrorCode.DB_CONNECTION_ERROR,
|
56
|
-
detail=f"Failed to get database session: {str(e)}",
|
57
|
-
source_function="get_db",
|
58
|
-
original_error=e
|
59
|
-
)
|
60
|
-
finally:
|
61
|
-
if 'session' in locals():
|
62
|
-
await session.close()
|
38
|
+
Args:
|
39
|
+
db_url (str, optional): 데이터베이스 URL
|
40
|
+
db_echo (bool, optional): SQL 로깅 여부
|
41
|
+
db_pool_size (int, optional): DB 커넥션 풀 크기
|
42
|
+
db_max_overflow (int, optional): 최대 초과 커넥션 수
|
43
|
+
db_pool_timeout (int, optional): 커넥션 풀 타임아웃
|
44
|
+
db_pool_recycle (int, optional): 커넥션 재활용 시간
|
63
45
|
|
64
|
-
|
65
|
-
|
46
|
+
Returns:
|
47
|
+
DatabaseService: 데이터베이스 서비스 인스턴스
|
66
48
|
|
67
|
-
|
68
|
-
|
49
|
+
Raises:
|
50
|
+
CustomException: 데이터베이스 초기화 실패 시
|
51
|
+
"""
|
52
|
+
async with cls._lock:
|
53
|
+
if not cls._instance:
|
54
|
+
if not db_url:
|
55
|
+
raise CustomException(
|
56
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
57
|
+
detail="Database URL is required for initialization",
|
58
|
+
source_function="DatabaseServiceManager.get_instance"
|
59
|
+
)
|
60
|
+
try:
|
61
|
+
cls._instance = DatabaseService(
|
62
|
+
db_url=db_url,
|
63
|
+
db_echo=db_echo,
|
64
|
+
db_pool_size=db_pool_size,
|
65
|
+
db_max_overflow=db_max_overflow,
|
66
|
+
db_pool_timeout=db_pool_timeout,
|
67
|
+
db_pool_recycle=db_pool_recycle,
|
68
|
+
**kwargs
|
69
|
+
)
|
70
|
+
logging.info("Database service initialized successfully")
|
71
|
+
except Exception as e:
|
72
|
+
logging.error(f"Failed to initialize database service: {str(e)}")
|
73
|
+
raise CustomException(
|
74
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
75
|
+
detail=f"Failed to initialize database service: {str(e)}",
|
76
|
+
source_function="DatabaseServiceManager.get_instance",
|
77
|
+
original_error=e
|
78
|
+
)
|
79
|
+
return cls._instance
|
69
80
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
81
|
+
@classmethod
|
82
|
+
async def cleanup(cls) -> None:
|
83
|
+
"""데이터베이스 서비스 인스턴스를 정리합니다."""
|
84
|
+
async with cls._lock:
|
85
|
+
if cls._instance:
|
86
|
+
try:
|
87
|
+
if cls._instance.engine:
|
88
|
+
await cls._instance.engine.dispose()
|
89
|
+
cls._instance = None
|
90
|
+
logging.info("Database service cleaned up successfully")
|
91
|
+
except Exception as e:
|
92
|
+
logging.error(f"Error during database service cleanup: {str(e)}")
|
93
|
+
raise CustomException(
|
94
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
95
|
+
detail=f"Failed to cleanup database service: {str(e)}",
|
96
|
+
source_function="DatabaseServiceManager.cleanup",
|
97
|
+
original_error=e
|
98
|
+
)
|
99
|
+
|
100
|
+
@classmethod
|
101
|
+
async def is_initialized(cls) -> bool:
|
102
|
+
"""데이터베이스 서비스가 초기화되었는지 확인합니다."""
|
103
|
+
return cls._instance is not None
|
74
104
|
|
75
105
|
class DatabaseService:
|
76
106
|
def __init__(
|
@@ -122,10 +152,42 @@ class DatabaseService:
|
|
122
152
|
else:
|
123
153
|
raise CustomException(
|
124
154
|
ErrorCode.DB_CONNECTION_ERROR,
|
125
|
-
detail="db_url
|
155
|
+
detail="Either db_url or session must be provided",
|
126
156
|
source_function="DatabaseService.__init__"
|
127
157
|
)
|
128
158
|
|
159
|
+
async def is_connected(self) -> bool:
|
160
|
+
"""데이터베이스 연결 상태를 확인합니다."""
|
161
|
+
try:
|
162
|
+
if not self.engine:
|
163
|
+
return False
|
164
|
+
async with self.engine.connect() as conn:
|
165
|
+
await conn.execute(select(1))
|
166
|
+
return True
|
167
|
+
except Exception:
|
168
|
+
return False
|
169
|
+
|
170
|
+
async def retry_connection(self, retries: int = 3, delay: int = 2) -> bool:
|
171
|
+
"""데이터베이스 연결을 재시도합니다.
|
172
|
+
|
173
|
+
Args:
|
174
|
+
retries (int): 재시도 횟수
|
175
|
+
delay (int): 재시도 간 대기 시간(초)
|
176
|
+
|
177
|
+
Returns:
|
178
|
+
bool: 연결 성공 여부
|
179
|
+
"""
|
180
|
+
for attempt in range(retries):
|
181
|
+
try:
|
182
|
+
if await self.is_connected():
|
183
|
+
return True
|
184
|
+
await asyncio.sleep(delay)
|
185
|
+
except Exception as e:
|
186
|
+
logging.error(f"Connection retry attempt {attempt + 1} failed: {str(e)}")
|
187
|
+
if attempt == retries - 1:
|
188
|
+
return False
|
189
|
+
return False
|
190
|
+
|
129
191
|
@asynccontextmanager
|
130
192
|
async def get_session(self) -> AsyncGenerator[AsyncSession, None]:
|
131
193
|
"""데이터베이스 세션을 생성하고 반환하는 비동기 컨텍스트 매니저."""
|
@@ -934,60 +996,99 @@ class DatabaseService:
|
|
934
996
|
original_error=e
|
935
997
|
)
|
936
998
|
|
937
|
-
def
|
938
|
-
|
939
|
-
db_echo: bool = False,
|
940
|
-
db_pool_size: int = 5,
|
941
|
-
db_max_overflow: int = 10,
|
942
|
-
db_pool_timeout: int = 30,
|
943
|
-
db_pool_recycle: int = 1800
|
944
|
-
) -> DatabaseService:
|
945
|
-
"""데이터베이스 서비스를 초기화합니다.
|
999
|
+
async def get_db() -> AsyncGenerator[AsyncSession, None]:
|
1000
|
+
"""데이터베이스 세션을 생성하고 반환하는 비동기 제너레이터.
|
946
1001
|
|
947
|
-
|
948
|
-
|
949
|
-
db_echo (bool, optional): SQL 로깅 여부
|
950
|
-
db_pool_size (int, optional): DB 커넥션 풀 크기
|
951
|
-
db_max_overflow (int, optional): 최대 초과 커넥션 수
|
952
|
-
db_pool_timeout (int, optional): 커넥션 풀 타임아웃
|
953
|
-
db_pool_recycle (int, optional): 커넥션 재활용 시간
|
954
|
-
|
955
|
-
Returns:
|
956
|
-
DatabaseService: 초기화된 데이터베이스 서비스 인스턴스
|
1002
|
+
Yields:
|
1003
|
+
AsyncSession: 데이터베이스 세션
|
957
1004
|
|
958
1005
|
Raises:
|
959
|
-
CustomException:
|
1006
|
+
CustomException: 세션 생성 실패 시
|
960
1007
|
"""
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
logging.info(f"Initializing database service with URL: {db_url}")
|
968
|
-
_database_service = DatabaseService(
|
969
|
-
db_url=db_url,
|
970
|
-
db_echo=db_echo,
|
971
|
-
db_pool_size=db_pool_size,
|
972
|
-
db_max_overflow=db_max_overflow,
|
973
|
-
db_pool_timeout=db_pool_timeout,
|
974
|
-
db_pool_recycle=db_pool_recycle
|
1008
|
+
if not await DatabaseServiceManager.is_initialized():
|
1009
|
+
raise CustomException(
|
1010
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
1011
|
+
detail="Database service is not initialized",
|
1012
|
+
source_function="get_db"
|
975
1013
|
)
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
1014
|
+
|
1015
|
+
db_service = await DatabaseServiceManager.get_instance()
|
1016
|
+
if not db_service or not db_service.engine:
|
1017
|
+
raise CustomException(
|
1018
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
1019
|
+
detail="Database service or engine is not properly initialized",
|
1020
|
+
source_function="get_db"
|
1021
|
+
)
|
1022
|
+
|
1023
|
+
try:
|
1024
|
+
async with db_service.get_session() as session:
|
1025
|
+
if session is None:
|
1026
|
+
raise CustomException(
|
1027
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
1028
|
+
detail="Failed to create database session",
|
1029
|
+
source_function="get_db"
|
1030
|
+
)
|
983
1031
|
|
984
|
-
|
985
|
-
|
1032
|
+
# 세션이 유효한지 확인
|
1033
|
+
try:
|
1034
|
+
await session.execute(select(1))
|
1035
|
+
except Exception as e:
|
1036
|
+
raise CustomException(
|
1037
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
1038
|
+
detail="Database session is not valid",
|
1039
|
+
source_function="get_db",
|
1040
|
+
original_error=e
|
1041
|
+
)
|
1042
|
+
|
1043
|
+
yield session
|
986
1044
|
except Exception as e:
|
987
|
-
logging.error(f"Failed to initialize database service: {str(e)}")
|
988
1045
|
raise CustomException(
|
989
1046
|
ErrorCode.DB_CONNECTION_ERROR,
|
990
|
-
detail=f"Failed to
|
991
|
-
source_function="
|
1047
|
+
detail=f"Failed to get database session: {str(e)}",
|
1048
|
+
source_function="get_db",
|
992
1049
|
original_error=e
|
993
|
-
)
|
1050
|
+
)
|
1051
|
+
finally:
|
1052
|
+
if 'session' in locals() and session is not None:
|
1053
|
+
await session.close()
|
1054
|
+
|
1055
|
+
async def get_database_service() -> DatabaseService:
|
1056
|
+
"""DatabaseService 의존성
|
1057
|
+
|
1058
|
+
Returns:
|
1059
|
+
DatabaseService: DatabaseService 인스턴스
|
1060
|
+
|
1061
|
+
Raises:
|
1062
|
+
CustomException: 데이터베이스 서비스가 초기화되지 않은 경우
|
1063
|
+
"""
|
1064
|
+
if not await DatabaseServiceManager.is_initialized():
|
1065
|
+
raise CustomException(
|
1066
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
1067
|
+
detail="Database service is not initialized",
|
1068
|
+
source_function="get_database_service"
|
1069
|
+
)
|
1070
|
+
|
1071
|
+
return await DatabaseServiceManager.get_instance()
|
1072
|
+
|
1073
|
+
@asynccontextmanager
|
1074
|
+
async def lifespan(app: FastAPI):
|
1075
|
+
"""FastAPI 애플리케이션 라이프사이클 관리자.
|
1076
|
+
|
1077
|
+
Args:
|
1078
|
+
app (FastAPI): FastAPI 애플리케이션 인스턴스
|
1079
|
+
"""
|
1080
|
+
try:
|
1081
|
+
# 시작 시 초기화
|
1082
|
+
if not await DatabaseServiceManager.is_initialized():
|
1083
|
+
await DatabaseServiceManager.get_instance(
|
1084
|
+
db_url=app.state.settings.DATABASE_URL,
|
1085
|
+
db_echo=app.state.settings.DB_ECHO,
|
1086
|
+
db_pool_size=app.state.settings.DB_POOL_SIZE,
|
1087
|
+
db_max_overflow=app.state.settings.DB_MAX_OVERFLOW,
|
1088
|
+
db_pool_timeout=app.state.settings.DB_POOL_TIMEOUT,
|
1089
|
+
db_pool_recycle=app.state.settings.DB_POOL_RECYCLE
|
1090
|
+
)
|
1091
|
+
yield
|
1092
|
+
finally:
|
1093
|
+
# 종료 시 정리
|
1094
|
+
await DatabaseServiceManager.cleanup()
|
aiteamutils/dependencies.py
CHANGED
@@ -5,87 +5,49 @@ from jose import JWTError, jwt
|
|
5
5
|
from sqlalchemy.ext.asyncio import AsyncSession
|
6
6
|
import logging
|
7
7
|
|
8
|
-
from .database import
|
8
|
+
from .database import DatabaseServiceManager, get_db, get_database_service
|
9
9
|
from .exceptions import CustomException, ErrorCode
|
10
10
|
from .config import get_settings
|
11
11
|
|
12
12
|
class ServiceRegistry:
|
13
|
-
"""서비스
|
13
|
+
"""서비스 레지스트리 클래스"""
|
14
14
|
def __init__(self):
|
15
|
-
self._services: Dict[str, Tuple[Type, Type]] = {}
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
self._services.clear()
|
21
|
-
self._initialized = False
|
22
|
-
|
23
|
-
def register(self, name: str, repository_class: Type, service_class: Type):
|
24
|
-
"""서비스를 레지스트리에 등록
|
25
|
-
|
15
|
+
self._services: Dict[str, Tuple[Type[Any], Type[Any]]] = {}
|
16
|
+
|
17
|
+
def register(self, name: str, repository_class: Type[Any], service_class: Type[Any]) -> None:
|
18
|
+
"""서비스를 등록합니다.
|
19
|
+
|
26
20
|
Args:
|
27
21
|
name (str): 서비스 이름
|
28
|
-
repository_class (Type):
|
29
|
-
service_class (Type):
|
30
|
-
|
31
|
-
Raises:
|
32
|
-
CustomException: 이미 등록된 서비스인 경우
|
22
|
+
repository_class (Type[Any]): 레포지토리 클래스
|
23
|
+
service_class (Type[Any]): 서비스 클래스
|
33
24
|
"""
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
if not repository_class or not service_class:
|
40
|
-
raise CustomException(
|
41
|
-
ErrorCode.INTERNAL_ERROR,
|
42
|
-
detail=f"Invalid service classes for '{name}'",
|
43
|
-
source_function="ServiceRegistry.register"
|
44
|
-
)
|
45
|
-
|
46
|
-
self._services[name] = (repository_class, service_class)
|
47
|
-
logging.info(f"Service '{name}' registered successfully")
|
48
|
-
|
49
|
-
except Exception as e:
|
50
|
-
raise CustomException(
|
51
|
-
ErrorCode.INTERNAL_ERROR,
|
52
|
-
detail=f"Failed to register service '{name}': {str(e)}",
|
53
|
-
source_function="ServiceRegistry.register",
|
54
|
-
original_error=e
|
55
|
-
)
|
56
|
-
|
57
|
-
def get(self, name: str) -> Tuple[Type, Type]:
|
58
|
-
"""등록된 서비스를 조회
|
59
|
-
|
25
|
+
self._services[name] = (repository_class, service_class)
|
26
|
+
|
27
|
+
def get(self, name: str) -> Tuple[Type[Any], Type[Any]]:
|
28
|
+
"""등록된 서비스를 가져옵니다.
|
29
|
+
|
60
30
|
Args:
|
61
31
|
name (str): 서비스 이름
|
62
|
-
|
32
|
+
|
63
33
|
Returns:
|
64
|
-
Tuple[Type, Type]: (
|
65
|
-
|
34
|
+
Tuple[Type[Any], Type[Any]]: (레포지토리 클래스, 서비스 클래스)
|
35
|
+
|
66
36
|
Raises:
|
67
37
|
CustomException: 등록되지 않은 서비스인 경우
|
68
38
|
"""
|
69
39
|
if name not in self._services:
|
70
40
|
raise CustomException(
|
71
|
-
ErrorCode.
|
41
|
+
ErrorCode.NOT_FOUND,
|
72
42
|
detail=f"Service '{name}' is not registered",
|
73
43
|
source_function="ServiceRegistry.get"
|
74
44
|
)
|
75
45
|
return self._services[name]
|
76
|
-
|
77
|
-
def is_initialized(self) -> bool:
|
78
|
-
"""서비스 레지스트리 초기화 여부를 반환합니다."""
|
79
|
-
return self._initialized
|
80
|
-
|
81
|
-
def set_initialized(self):
|
82
|
-
"""서비스 레지스트리를 초기화 상태로 설정합니다."""
|
83
|
-
self._initialized = True
|
84
46
|
|
85
47
|
# ServiceRegistry 초기화
|
86
48
|
service_registry = ServiceRegistry()
|
87
49
|
|
88
|
-
def get_service(name: str):
|
50
|
+
async def get_service(name: str):
|
89
51
|
"""등록된 서비스를 가져오는 의존성 함수
|
90
52
|
|
91
53
|
Args:
|
@@ -97,11 +59,11 @@ def get_service(name: str):
|
|
97
59
|
Raises:
|
98
60
|
CustomException: 서비스 생성 실패 시
|
99
61
|
"""
|
100
|
-
def _get_service(db_service
|
62
|
+
async def _get_service(db_service = Depends(get_database_service)):
|
101
63
|
try:
|
102
64
|
repository_class, service_class = service_registry.get(name)
|
103
65
|
repository = repository_class(db_service)
|
104
|
-
return service_class(repository
|
66
|
+
return service_class(repository)
|
105
67
|
except CustomException as e:
|
106
68
|
raise e
|
107
69
|
except Exception as e:
|
@@ -116,13 +78,13 @@ def get_service(name: str):
|
|
116
78
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/users/token")
|
117
79
|
async def get_current_user(
|
118
80
|
token: str = Depends(oauth2_scheme),
|
119
|
-
db_service:
|
81
|
+
db_service: DatabaseServiceManager = Depends(get_database_service)
|
120
82
|
):
|
121
83
|
"""현재 사용자를 가져오는 의존성 함수
|
122
84
|
|
123
85
|
Args:
|
124
86
|
token (str): OAuth2 토큰
|
125
|
-
db_service (
|
87
|
+
db_service (DatabaseServiceManager): DatabaseServiceManager 객체
|
126
88
|
|
127
89
|
Returns:
|
128
90
|
User: 현재 사용자
|
aiteamutils/version.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
"""버전 정보"""
|
2
|
-
__version__ = "0.2.
|
2
|
+
__version__ = "0.2.43"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
aiteamutils/__init__.py,sha256=IAvWobxODQeMIgttFf3e1IGMO-DktLyUmnHeKqGDZWg,1346
|
2
|
+
aiteamutils/base_model.py,sha256=ODEnjvUVoxQ1RPCfq8-uZTfTADIA4c7Z3E6G4EVsSX0,2708
|
3
|
+
aiteamutils/base_repository.py,sha256=qdwQ7Sj2fUqxpDg6cWM48n_QbwPK_VUlG9zTSem8iCk,18968
|
4
|
+
aiteamutils/base_service.py,sha256=E4dHGE0DvhmRyFplh46SwKJOSF_nUL7OAsCkf_ZJF_8,24733
|
5
|
+
aiteamutils/cache.py,sha256=07xBGlgAwOTAdY5mnMOQJ5EBxVwe8glVD7DkGEkxCtw,1373
|
6
|
+
aiteamutils/config.py,sha256=OM_b7g8sqZ3zY_DSF9ry-zn5wn4dlXdx5OhjfTGr0TE,2876
|
7
|
+
aiteamutils/database.py,sha256=PZOggFB8KfkoCxzHhP5GGeBjee-FM6Hr_no8c7uhAMU,40129
|
8
|
+
aiteamutils/dependencies.py,sha256=nOWEgPYWP__67s3_XeFgPHStEcFea5C3IkDRqIPQ9Ps,4385
|
9
|
+
aiteamutils/enums.py,sha256=ipZi6k_QD5-3QV7Yzv7bnL0MjDz-vqfO9I5L77biMKs,632
|
10
|
+
aiteamutils/exceptions.py,sha256=_lKWXq_ujNj41xN6LDE149PwsecAP7lgYWbOBbLOntg,15368
|
11
|
+
aiteamutils/security.py,sha256=9gvEqDtE3RJaoCWqELPCjkg-IsSqZVrpMP6XPZaodWU,16024
|
12
|
+
aiteamutils/validators.py,sha256=3N245cZFjgwtW_KzjESkizx5BBUDaJLbbxfNO4WOFZ0,7764
|
13
|
+
aiteamutils/version.py,sha256=HOOAyObLDTs7wST-8eCcaBk-k-nHQiPz_ZzGsaV0y9A,42
|
14
|
+
aiteamutils-0.2.43.dist-info/METADATA,sha256=IRDl6mxwo2hBxaL3pLwfc6UHSyvUfenXoOeMOt0PEyU,1718
|
15
|
+
aiteamutils-0.2.43.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
16
|
+
aiteamutils-0.2.43.dist-info/RECORD,,
|
@@ -1,16 +0,0 @@
|
|
1
|
-
aiteamutils/__init__.py,sha256=cpQeEVultNyHYdnz0hympv8iA-8loE_4EbTHytxlp6s,1312
|
2
|
-
aiteamutils/base_model.py,sha256=ODEnjvUVoxQ1RPCfq8-uZTfTADIA4c7Z3E6G4EVsSX0,2708
|
3
|
-
aiteamutils/base_repository.py,sha256=qdwQ7Sj2fUqxpDg6cWM48n_QbwPK_VUlG9zTSem8iCk,18968
|
4
|
-
aiteamutils/base_service.py,sha256=E4dHGE0DvhmRyFplh46SwKJOSF_nUL7OAsCkf_ZJF_8,24733
|
5
|
-
aiteamutils/cache.py,sha256=tr0Yn8VPYA9QHiKCUzciVlQ2J1RAwNo2K9lGMH4rY3s,1334
|
6
|
-
aiteamutils/config.py,sha256=kFKMeIx1KcuEwwx4VjZdCgoTOHCkG3ySYVJ0G6cvMoA,2849
|
7
|
-
aiteamutils/database.py,sha256=l_ZykepKquKRdsBZwLAeLHEYxhM4Ac4bknWtYNHurOo,35928
|
8
|
-
aiteamutils/dependencies.py,sha256=hsJ-kc8ic4U6vKFtUIWjhBE1_Bm-sya5UqSb2zMH5oM,5731
|
9
|
-
aiteamutils/enums.py,sha256=ipZi6k_QD5-3QV7Yzv7bnL0MjDz-vqfO9I5L77biMKs,632
|
10
|
-
aiteamutils/exceptions.py,sha256=_lKWXq_ujNj41xN6LDE149PwsecAP7lgYWbOBbLOntg,15368
|
11
|
-
aiteamutils/security.py,sha256=9gvEqDtE3RJaoCWqELPCjkg-IsSqZVrpMP6XPZaodWU,16024
|
12
|
-
aiteamutils/validators.py,sha256=3N245cZFjgwtW_KzjESkizx5BBUDaJLbbxfNO4WOFZ0,7764
|
13
|
-
aiteamutils/version.py,sha256=DT95upAYup68_YP0gm-cFpVbBYlrV8Snq10ztLShyy4,42
|
14
|
-
aiteamutils-0.2.41.dist-info/METADATA,sha256=LiQlMTbzxNqm_cZSqVunU5siBxpF-G0jhI5UqP3RC7c,1718
|
15
|
-
aiteamutils-0.2.41.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
16
|
-
aiteamutils-0.2.41.dist-info/RECORD,,
|
File without changes
|