aiteamutils 0.2.48__tar.gz → 0.2.101__tar.gz
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-0.2.48 → aiteamutils-0.2.101}/.gitignore +1 -6
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/PKG-INFO +1 -1
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/aiteamutils/__init__.py +0 -14
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/aiteamutils/base_model.py +15 -4
- aiteamutils-0.2.101/aiteamutils/base_repository.py +150 -0
- aiteamutils-0.2.101/aiteamutils/base_service.py +301 -0
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/aiteamutils/config.py +23 -13
- aiteamutils-0.2.101/aiteamutils/database.py +599 -0
- aiteamutils-0.2.101/aiteamutils/enums.py +84 -0
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/aiteamutils/exceptions.py +9 -2
- aiteamutils-0.2.101/aiteamutils/security.py +328 -0
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/aiteamutils/validators.py +0 -1
- aiteamutils-0.2.101/aiteamutils/version.py +2 -0
- aiteamutils-0.2.48/aiteamutils/base_repository.py +0 -504
- aiteamutils-0.2.48/aiteamutils/base_service.py +0 -668
- aiteamutils-0.2.48/aiteamutils/database.py +0 -1096
- aiteamutils-0.2.48/aiteamutils/dependencies.py +0 -135
- aiteamutils-0.2.48/aiteamutils/enums.py +0 -23
- aiteamutils-0.2.48/aiteamutils/security.py +0 -479
- aiteamutils-0.2.48/aiteamutils/version.py +0 -2
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/.cursorrules +0 -0
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/README.md +0 -0
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/aiteamutils/cache.py +0 -0
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/pyproject.toml +0 -0
- {aiteamutils-0.2.48 → aiteamutils-0.2.101}/setup.py +0 -0
@@ -1,11 +1,4 @@
|
|
1
1
|
from .base_model import Base
|
2
|
-
from .database import (
|
3
|
-
DatabaseService,
|
4
|
-
DatabaseServiceManager,
|
5
|
-
get_db,
|
6
|
-
get_database_service,
|
7
|
-
lifespan
|
8
|
-
)
|
9
2
|
from .exceptions import (
|
10
3
|
CustomException,
|
11
4
|
ErrorCode,
|
@@ -34,13 +27,6 @@ __all__ = [
|
|
34
27
|
"BaseService",
|
35
28
|
"BaseRepository",
|
36
29
|
|
37
|
-
# Database
|
38
|
-
"DatabaseService",
|
39
|
-
"DatabaseServiceManager",
|
40
|
-
"get_db",
|
41
|
-
"get_database_service",
|
42
|
-
"lifespan",
|
43
|
-
|
44
30
|
# Exceptions
|
45
31
|
"CustomException",
|
46
32
|
"ErrorCode",
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from datetime import datetime, timezone
|
1
|
+
from datetime import datetime, timedelta, timezone
|
2
2
|
from typing import Any, Dict, TypeVar, Generic, Optional
|
3
3
|
from ulid import ULID
|
4
4
|
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
|
@@ -23,10 +23,21 @@ class BaseColumn(Base):
|
|
23
23
|
doc="ULID",
|
24
24
|
nullable=False
|
25
25
|
)
|
26
|
-
created_at: Mapped[datetime] = mapped_column(
|
26
|
+
created_at: Mapped[datetime] = mapped_column(
|
27
|
+
TIMESTAMP(timezone=True),
|
28
|
+
default=datetime.now(timezone.utc),
|
29
|
+
index=True
|
30
|
+
)
|
27
31
|
updated_at: Mapped[datetime] = mapped_column(
|
28
|
-
|
29
|
-
|
32
|
+
TIMESTAMP(timezone=True),
|
33
|
+
default=datetime.now(timezone.utc),
|
34
|
+
onupdate=datetime.now(timezone.utc),
|
35
|
+
index=True
|
36
|
+
)
|
37
|
+
deleted_at: Mapped[datetime] = mapped_column(
|
38
|
+
TIMESTAMP(timezone=True),
|
39
|
+
default=None,
|
40
|
+
nullable=True
|
30
41
|
)
|
31
42
|
is_deleted: Mapped[bool] = mapped_column(
|
32
43
|
default=False,
|
@@ -0,0 +1,150 @@
|
|
1
|
+
#기본 라이브러리
|
2
|
+
from typing import TypeVar, Generic, Type, Any, Dict, List, Optional
|
3
|
+
from sqlalchemy.orm import DeclarativeBase
|
4
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
5
|
+
from sqlalchemy.exc import SQLAlchemyError
|
6
|
+
from sqlalchemy import select
|
7
|
+
|
8
|
+
#패키지 라이브러리
|
9
|
+
from .exceptions import ErrorCode, CustomException
|
10
|
+
from .database import (
|
11
|
+
list_entities,
|
12
|
+
get_entity,
|
13
|
+
create_entity,
|
14
|
+
update_entity,
|
15
|
+
delete_entity
|
16
|
+
)
|
17
|
+
|
18
|
+
ModelType = TypeVar("ModelType", bound=DeclarativeBase)
|
19
|
+
|
20
|
+
class BaseRepository(Generic[ModelType]):
|
21
|
+
def __init__(self, session: AsyncSession, model: Type[ModelType]):
|
22
|
+
self._session = session
|
23
|
+
self.model = model
|
24
|
+
|
25
|
+
@property
|
26
|
+
def session(self) -> AsyncSession:
|
27
|
+
return self._session
|
28
|
+
|
29
|
+
@session.setter
|
30
|
+
def session(self, value: AsyncSession):
|
31
|
+
if value is None:
|
32
|
+
raise CustomException(
|
33
|
+
ErrorCode.DB_CONNECTION_ERROR,
|
34
|
+
detail="Session cannot be None",
|
35
|
+
source_function=f"{self.__class__.__name__}.session"
|
36
|
+
)
|
37
|
+
self._session = value
|
38
|
+
|
39
|
+
#######################
|
40
|
+
# 입력 및 수정, 삭제 #
|
41
|
+
#######################
|
42
|
+
async def create(
|
43
|
+
self,
|
44
|
+
entity_data: Dict[str, Any],
|
45
|
+
exclude_entities: List[str] | None = None
|
46
|
+
) -> ModelType:
|
47
|
+
try:
|
48
|
+
return await create_entity(
|
49
|
+
session=self.session,
|
50
|
+
model=self.model,
|
51
|
+
entity_data=entity_data,
|
52
|
+
exclude_entities=exclude_entities
|
53
|
+
)
|
54
|
+
except CustomException as e:
|
55
|
+
raise e
|
56
|
+
except Exception as e:
|
57
|
+
raise CustomException(
|
58
|
+
ErrorCode.INTERNAL_ERROR,
|
59
|
+
detail=str(e),
|
60
|
+
source_function=f"{self.__class__.__name__}.create",
|
61
|
+
original_error=e
|
62
|
+
)
|
63
|
+
|
64
|
+
async def update(
|
65
|
+
self,
|
66
|
+
update_data: Dict[str, Any],
|
67
|
+
conditions: Dict[str, Any],
|
68
|
+
exclude_entities: List[str] | None = None
|
69
|
+
) -> ModelType:
|
70
|
+
try:
|
71
|
+
return await update_entity(
|
72
|
+
session=self.session,
|
73
|
+
model=self.model,
|
74
|
+
update_data=update_data,
|
75
|
+
conditions=conditions,
|
76
|
+
exclude_entities=exclude_entities
|
77
|
+
)
|
78
|
+
except CustomException as e:
|
79
|
+
raise e
|
80
|
+
|
81
|
+
async def delete(
|
82
|
+
self,
|
83
|
+
conditions: Dict[str, Any]
|
84
|
+
) -> bool:
|
85
|
+
await delete_entity(
|
86
|
+
session=self.session,
|
87
|
+
model=self.model,
|
88
|
+
conditions=conditions
|
89
|
+
)
|
90
|
+
return True
|
91
|
+
#########################
|
92
|
+
# 조회 및 검색 메서드 #
|
93
|
+
#########################
|
94
|
+
async def list(
|
95
|
+
self,
|
96
|
+
skip: int = 0,
|
97
|
+
limit: int = 100,
|
98
|
+
filters: Optional[List[Dict[str, Any]]] = None,
|
99
|
+
explicit_joins: Optional[List[Any]] = None,
|
100
|
+
loading_joins: Optional[List[Any]] = None,
|
101
|
+
order: Optional[List[Dict[str, str]]] = None
|
102
|
+
) -> List[ModelType]:
|
103
|
+
"""
|
104
|
+
엔티티 목록 조회.
|
105
|
+
"""
|
106
|
+
try:
|
107
|
+
# 기본 CRUD 작업 호출
|
108
|
+
return await list_entities(
|
109
|
+
session=self.session,
|
110
|
+
model=self.model,
|
111
|
+
skip=skip,
|
112
|
+
limit=limit,
|
113
|
+
filters=filters,
|
114
|
+
explicit_joins=explicit_joins,
|
115
|
+
loading_joins=loading_joins,
|
116
|
+
order=order
|
117
|
+
)
|
118
|
+
except CustomException as e:
|
119
|
+
raise e
|
120
|
+
except Exception as e:
|
121
|
+
raise CustomException(
|
122
|
+
ErrorCode.INTERNAL_ERROR,
|
123
|
+
detail=str(e),
|
124
|
+
source_function=f"{self.__class__.__name__}.list",
|
125
|
+
original_error=e
|
126
|
+
)
|
127
|
+
|
128
|
+
async def get(
|
129
|
+
self,
|
130
|
+
conditions: Dict[str, Any] | None = None,
|
131
|
+
explicit_joins: Optional[List[Any]] = None,
|
132
|
+
loading_joins: Optional[List[Any]] = None
|
133
|
+
) -> ModelType:
|
134
|
+
try:
|
135
|
+
return await get_entity(
|
136
|
+
session=self.session,
|
137
|
+
model=self.model,
|
138
|
+
conditions=conditions,
|
139
|
+
explicit_joins=explicit_joins,
|
140
|
+
loading_joins=loading_joins
|
141
|
+
)
|
142
|
+
except CustomException as e:
|
143
|
+
raise e
|
144
|
+
except Exception as e:
|
145
|
+
raise CustomException(
|
146
|
+
ErrorCode.INTERNAL_ERROR,
|
147
|
+
detail=str(e),
|
148
|
+
source_function=f"{self.__class__.__name__}.get",
|
149
|
+
original_error=e
|
150
|
+
)
|
@@ -0,0 +1,301 @@
|
|
1
|
+
#기본 라이브러리
|
2
|
+
from fastapi import Request
|
3
|
+
from typing import TypeVar, Generic, Type, Dict, Any, Union, List, Optional, Literal
|
4
|
+
from sqlalchemy.orm import DeclarativeBase
|
5
|
+
from sqlalchemy.ext.asyncio import AsyncSession
|
6
|
+
from datetime import datetime
|
7
|
+
from ulid import ULID
|
8
|
+
|
9
|
+
#패키지 라이브러리
|
10
|
+
from .exceptions import ErrorCode, CustomException
|
11
|
+
from .base_repository import BaseRepository
|
12
|
+
from .database import (
|
13
|
+
process_response,
|
14
|
+
validate_unique_fields
|
15
|
+
)
|
16
|
+
from .security import hash_password, verify_jwt_token, verify_role_permission
|
17
|
+
ModelType = TypeVar("ModelType", bound=DeclarativeBase)
|
18
|
+
|
19
|
+
class BaseService(Generic[ModelType]):
|
20
|
+
##################
|
21
|
+
# 초기화 영역 #
|
22
|
+
##################
|
23
|
+
def __init__(
|
24
|
+
self,
|
25
|
+
model: Type[ModelType],
|
26
|
+
repository: BaseRepository[ModelType],
|
27
|
+
db_session: AsyncSession,
|
28
|
+
additional_models: Dict[str, Type[DeclarativeBase]] = None,
|
29
|
+
):
|
30
|
+
self.model = model
|
31
|
+
self.repository = repository
|
32
|
+
self.db_session = db_session
|
33
|
+
self.additional_models = additional_models or {},
|
34
|
+
|
35
|
+
#######################
|
36
|
+
# 입력 및 수정, 삭제 #
|
37
|
+
#######################
|
38
|
+
async def create(
|
39
|
+
self,
|
40
|
+
request: Request,
|
41
|
+
entity_data: Dict[str, Any],
|
42
|
+
response_model: Any = None,
|
43
|
+
exclude_entities: List[str] | None = None,
|
44
|
+
unique_check: List[Dict[str, Any]] | None = None,
|
45
|
+
fk_check: List[Dict[str, Any]] | None = None,
|
46
|
+
org_ulid_position: str = "organization_ulid",
|
47
|
+
role_permission: str | None = None,
|
48
|
+
token_settings: Dict[str, Any] | None = None
|
49
|
+
) -> ModelType:
|
50
|
+
|
51
|
+
if role_permission:
|
52
|
+
permission_result = await verify_role_permission(
|
53
|
+
request=request,
|
54
|
+
role_permission=role_permission,
|
55
|
+
token_settings=token_settings,
|
56
|
+
org_ulid_position=org_ulid_position
|
57
|
+
)
|
58
|
+
|
59
|
+
if not permission_result:
|
60
|
+
raise CustomException(
|
61
|
+
ErrorCode.FORBIDDEN,
|
62
|
+
detail=f"{role_permission}",
|
63
|
+
source_function=f"{self.__class__.__name__}.create"
|
64
|
+
)
|
65
|
+
|
66
|
+
try:
|
67
|
+
async with self.db_session.begin():
|
68
|
+
# 고유 검사 수행
|
69
|
+
if unique_check:
|
70
|
+
await validate_unique_fields(self.db_session, unique_check, find_value=True)
|
71
|
+
# 외래 키 검사 수행
|
72
|
+
if fk_check:
|
73
|
+
await validate_unique_fields(self.db_session, fk_check, find_value=False)
|
74
|
+
|
75
|
+
result = await self.repository.create(
|
76
|
+
entity_data=entity_data,
|
77
|
+
exclude_entities=exclude_entities
|
78
|
+
)
|
79
|
+
|
80
|
+
# 결과 반환
|
81
|
+
if response_model:
|
82
|
+
return process_response(result, response_model)
|
83
|
+
else:
|
84
|
+
return result
|
85
|
+
|
86
|
+
except CustomException as e:
|
87
|
+
raise e
|
88
|
+
except Exception as e:
|
89
|
+
# 다른 예외 처리
|
90
|
+
raise CustomException(
|
91
|
+
ErrorCode.INTERNAL_ERROR,
|
92
|
+
detail=str(e),
|
93
|
+
source_function=f"{self.__class__.__name__}.create",
|
94
|
+
original_error=e
|
95
|
+
)
|
96
|
+
|
97
|
+
async def update(
|
98
|
+
self,
|
99
|
+
request: Request,
|
100
|
+
ulid: str | None = None,
|
101
|
+
update_data: Dict[str, Any] | None = None,
|
102
|
+
conditions: Dict[str, Any] | None = None,
|
103
|
+
unique_check: List[Dict[str, Any]] | None = None,
|
104
|
+
exclude_entities: List[str] | None = None,
|
105
|
+
response_model: Any = None,
|
106
|
+
org_ulid_position: str = "organization_ulid",
|
107
|
+
role_permission: str = "update",
|
108
|
+
token_settings: Dict[str, Any] | None = None
|
109
|
+
) -> ModelType:
|
110
|
+
try:
|
111
|
+
async with self.db_session.begin():
|
112
|
+
# 고유 검사 수행
|
113
|
+
if unique_check:
|
114
|
+
await validate_unique_fields(self.db_session, unique_check, find_value=True)
|
115
|
+
|
116
|
+
if not ulid and not conditions:
|
117
|
+
raise CustomException(
|
118
|
+
ErrorCode.INVALID_INPUT,
|
119
|
+
detail="Either 'ulid' or 'conditions' must be provided.",
|
120
|
+
source_function="database.update_entity"
|
121
|
+
)
|
122
|
+
|
123
|
+
# ulid로 조건 생성
|
124
|
+
if ulid:
|
125
|
+
if not ULID.from_str(ulid):
|
126
|
+
raise CustomException(
|
127
|
+
ErrorCode.VALIDATION_ERROR,
|
128
|
+
detail=ulid,
|
129
|
+
source_function=f"{self.__class__.__name__}.update"
|
130
|
+
)
|
131
|
+
|
132
|
+
conditions = {"ulid": ulid}
|
133
|
+
|
134
|
+
result = await self.repository.update(
|
135
|
+
update_data=update_data,
|
136
|
+
conditions=conditions,
|
137
|
+
exclude_entities=exclude_entities
|
138
|
+
)
|
139
|
+
|
140
|
+
if response_model:
|
141
|
+
return process_response(result, response_model)
|
142
|
+
else:
|
143
|
+
return result
|
144
|
+
except CustomException as e:
|
145
|
+
raise e
|
146
|
+
except Exception as e:
|
147
|
+
raise CustomException(
|
148
|
+
ErrorCode.INTERNAL_ERROR,
|
149
|
+
detail=str(e),
|
150
|
+
source_function=f"{self.__class__.__name__}.update",
|
151
|
+
original_error=e
|
152
|
+
)
|
153
|
+
|
154
|
+
async def delete(
|
155
|
+
self,
|
156
|
+
request: Request,
|
157
|
+
ulid: str | None = None,
|
158
|
+
conditions: Dict[str, Any] | None = None,
|
159
|
+
org_ulid_position: str = "organization_ulid",
|
160
|
+
role_permission: str = "delete",
|
161
|
+
token_settings: Dict[str, Any] | None = None
|
162
|
+
) -> bool:
|
163
|
+
try:
|
164
|
+
if not ULID.from_str(ulid):
|
165
|
+
raise CustomException(
|
166
|
+
ErrorCode.VALIDATION_ERROR,
|
167
|
+
detail=ulid,
|
168
|
+
source_function=f"{self.__class__.__name__}.delete"
|
169
|
+
)
|
170
|
+
|
171
|
+
if not ulid and not conditions:
|
172
|
+
raise CustomException(
|
173
|
+
ErrorCode.INVALID_INPUT,
|
174
|
+
detail="Either 'ulid' or 'conditions' must be provided.",
|
175
|
+
source_function="database.update_entity"
|
176
|
+
)
|
177
|
+
|
178
|
+
# ulid로 조건 생성
|
179
|
+
if ulid:
|
180
|
+
conditions = {"ulid": ulid}
|
181
|
+
|
182
|
+
conditions["is_deleted"] = False
|
183
|
+
|
184
|
+
return await self.repository.delete(
|
185
|
+
conditions=conditions
|
186
|
+
)
|
187
|
+
except CustomException as e:
|
188
|
+
raise e
|
189
|
+
except Exception as e:
|
190
|
+
raise CustomException(
|
191
|
+
ErrorCode.INTERNAL_ERROR,
|
192
|
+
detail=str(e),
|
193
|
+
source_function=f"{self.__class__.__name__}.delete",
|
194
|
+
original_error=e
|
195
|
+
)
|
196
|
+
|
197
|
+
#########################
|
198
|
+
# 조회 및 검색 메서드 #
|
199
|
+
#########################
|
200
|
+
async def list(
|
201
|
+
self,
|
202
|
+
request: Request,
|
203
|
+
skip: int = 0,
|
204
|
+
limit: int = 100,
|
205
|
+
filters: List[Dict[str, Any]] | None = None,
|
206
|
+
org_ulid_position: str = "organization_ulid",
|
207
|
+
role_permission: str | None = None,
|
208
|
+
response_model: Any = None,
|
209
|
+
explicit_joins: Optional[List[Any]] = None,
|
210
|
+
loading_joins: Optional[List[Any]] = None,
|
211
|
+
order: Optional[str] = None,
|
212
|
+
token_settings: Dict[str, Any] | None = None
|
213
|
+
) -> List[Dict[str, Any]]:
|
214
|
+
filters = list(filters) if filters is not None else []
|
215
|
+
|
216
|
+
# if role_permission:
|
217
|
+
# permission_result = await verify_role_permission(
|
218
|
+
# request=request,
|
219
|
+
# role_permission=role_permission,
|
220
|
+
# token_settings=token_settings,
|
221
|
+
# org_ulid_position=org_ulid_position
|
222
|
+
# )
|
223
|
+
|
224
|
+
# if permission_result and isinstance(permission_result, dict):
|
225
|
+
# filters.append(permission_result)
|
226
|
+
|
227
|
+
try:
|
228
|
+
if order is None:
|
229
|
+
order = "created_at|desc"
|
230
|
+
|
231
|
+
order_by = order.split("|")
|
232
|
+
order = [{"field": order_by[0], "direction": order_by[1]}]
|
233
|
+
|
234
|
+
entities = await self.repository.list(
|
235
|
+
skip=skip,
|
236
|
+
limit=limit,
|
237
|
+
filters=filters,
|
238
|
+
explicit_joins=explicit_joins,
|
239
|
+
loading_joins=loading_joins,
|
240
|
+
order=order
|
241
|
+
)
|
242
|
+
return [process_response(entity, response_model) for entity in entities]
|
243
|
+
|
244
|
+
except CustomException as e:
|
245
|
+
raise e
|
246
|
+
except Exception as e:
|
247
|
+
raise CustomException(
|
248
|
+
ErrorCode.INTERNAL_ERROR,
|
249
|
+
source_function=f"{self.__class__.__name__}.list",
|
250
|
+
original_error=e
|
251
|
+
)
|
252
|
+
|
253
|
+
async def get(
|
254
|
+
self,
|
255
|
+
request: Request,
|
256
|
+
ulid: str,
|
257
|
+
model_name: str | None = None,
|
258
|
+
response_model: Any = None,
|
259
|
+
conditions: Dict[str, Any] | None = None,
|
260
|
+
explicit_joins: Optional[List[Any]] = None,
|
261
|
+
loading_joins: Optional[List[Any]] = None,
|
262
|
+
org_ulid_position: str = "organization_ulid",
|
263
|
+
role_permission: str = "get",
|
264
|
+
token_settings: Dict[str, Any] | None = None
|
265
|
+
):
|
266
|
+
try:
|
267
|
+
if not ulid and not conditions:
|
268
|
+
raise CustomException(
|
269
|
+
ErrorCode.INVALID_INPUT,
|
270
|
+
detail="Either 'ulid' or 'conditions' must be provided.",
|
271
|
+
source_function="database.update_entity"
|
272
|
+
)
|
273
|
+
|
274
|
+
# ulid로 조건 생성
|
275
|
+
if ulid:
|
276
|
+
if not ULID.from_str(ulid):
|
277
|
+
raise CustomException(
|
278
|
+
ErrorCode.VALIDATION_ERROR,
|
279
|
+
detail=ulid,
|
280
|
+
source_function=f"{self.__class__.__name__}.update"
|
281
|
+
)
|
282
|
+
|
283
|
+
conditions = {"ulid": ulid}
|
284
|
+
|
285
|
+
entity = await self.repository.get(
|
286
|
+
conditions=conditions,
|
287
|
+
explicit_joins=explicit_joins,
|
288
|
+
loading_joins=loading_joins
|
289
|
+
)
|
290
|
+
return process_response(entity, response_model)
|
291
|
+
|
292
|
+
except CustomException as e:
|
293
|
+
raise e
|
294
|
+
except Exception as e:
|
295
|
+
raise CustomException(
|
296
|
+
ErrorCode.INTERNAL_ERROR,
|
297
|
+
detail=str(e),
|
298
|
+
source_function=f"{self.__class__.__name__}.get",
|
299
|
+
original_error=e
|
300
|
+
)
|
301
|
+
|
@@ -1,6 +1,5 @@
|
|
1
1
|
"""설정 모듈."""
|
2
2
|
from typing import Union
|
3
|
-
from .database import DatabaseServiceManager
|
4
3
|
from .exceptions import CustomException, ErrorCode
|
5
4
|
|
6
5
|
class Settings:
|
@@ -11,13 +10,28 @@ class Settings:
|
|
11
10
|
jwt_algorithm: str = "HS256",
|
12
11
|
access_token_expire_minutes: int = 30,
|
13
12
|
token_issuer: str = "ai-team",
|
14
|
-
token_audience: str = "ai-team"
|
13
|
+
token_audience: str = "ai-team",
|
14
|
+
db_url: str = None,
|
15
|
+
db_echo: bool = False,
|
16
|
+
db_pool_size: int = 5,
|
17
|
+
db_max_overflow: int = 10,
|
18
|
+
db_pool_timeout: int = 30,
|
19
|
+
db_pool_recycle: int = 1800
|
15
20
|
):
|
21
|
+
# JWT 설정
|
16
22
|
self.JWT_SECRET = jwt_secret
|
17
23
|
self.JWT_ALGORITHM = jwt_algorithm
|
18
24
|
self.ACCESS_TOKEN_EXPIRE_MINUTES = access_token_expire_minutes
|
19
25
|
self.TOKEN_ISSUER = token_issuer
|
20
26
|
self.TOKEN_AUDIENCE = token_audience
|
27
|
+
|
28
|
+
# 데이터베이스 설정
|
29
|
+
self.DB_URL = db_url
|
30
|
+
self.DB_ECHO = db_echo
|
31
|
+
self.DB_POOL_SIZE = db_pool_size
|
32
|
+
self.DB_MAX_OVERFLOW = db_max_overflow
|
33
|
+
self.DB_POOL_TIMEOUT = db_pool_timeout
|
34
|
+
self.DB_POOL_RECYCLE = db_pool_recycle
|
21
35
|
|
22
36
|
_settings: Union[Settings, None] = None
|
23
37
|
|
@@ -55,18 +69,14 @@ async def init_settings(
|
|
55
69
|
jwt_algorithm=jwt_algorithm,
|
56
70
|
access_token_expire_minutes=access_token_expire_minutes,
|
57
71
|
token_issuer=token_issuer,
|
58
|
-
token_audience=token_audience
|
72
|
+
token_audience=token_audience,
|
73
|
+
db_url=db_url,
|
74
|
+
db_echo=db_echo,
|
75
|
+
db_pool_size=db_pool_size,
|
76
|
+
db_max_overflow=db_max_overflow,
|
77
|
+
db_pool_timeout=db_pool_timeout,
|
78
|
+
db_pool_recycle=db_pool_recycle
|
59
79
|
)
|
60
|
-
|
61
|
-
if db_url:
|
62
|
-
await DatabaseServiceManager.get_instance(
|
63
|
-
db_url=db_url,
|
64
|
-
db_echo=db_echo,
|
65
|
-
db_pool_size=db_pool_size,
|
66
|
-
db_max_overflow=db_max_overflow,
|
67
|
-
db_pool_timeout=db_pool_timeout,
|
68
|
-
db_pool_recycle=db_pool_recycle
|
69
|
-
)
|
70
80
|
|
71
81
|
def get_settings() -> Settings:
|
72
82
|
"""현재 설정을 반환하는 함수
|