trovesuite 1.0.3__py3-none-any.whl → 1.0.5__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.
- trovesuite/__init__.py +6 -4
- trovesuite/auth/__init__.py +2 -5
- trovesuite/auth/auth_controller.py +2 -1
- trovesuite/auth/auth_read_dto.py +0 -1
- trovesuite/auth/auth_service.py +3 -3
- trovesuite/auth/auth_write_dto.py +1 -1
- trovesuite/configs/database.py +29 -17
- trovesuite/notification/__init__.py +14 -0
- trovesuite/notification/notification_base.py +13 -0
- trovesuite/notification/notification_controller.py +21 -0
- trovesuite/notification/notification_read_dto.py +21 -0
- trovesuite/notification/notification_service.py +73 -0
- trovesuite/notification/notification_write_dto.py +21 -0
- {trovesuite-1.0.3.dist-info → trovesuite-1.0.5.dist-info}/METADATA +126 -5
- trovesuite-1.0.5.dist-info/RECORD +27 -0
- trovesuite-1.0.3.dist-info/RECORD +0 -21
- {trovesuite-1.0.3.dist-info → trovesuite-1.0.5.dist-info}/WHEEL +0 -0
- {trovesuite-1.0.3.dist-info → trovesuite-1.0.5.dist-info}/licenses/LICENSE +0 -0
- {trovesuite-1.0.3.dist-info → trovesuite-1.0.5.dist-info}/top_level.txt +0 -0
trovesuite/__init__.py
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
"""
|
|
2
|
-
TroveSuite
|
|
2
|
+
TroveSuite Package
|
|
3
3
|
|
|
4
|
-
A comprehensive authentication and
|
|
5
|
-
Provides JWT token validation, user authorization, and
|
|
4
|
+
A comprehensive authentication, authorization, and notification service for ERP systems.
|
|
5
|
+
Provides JWT token validation, user authorization, permission checking, and notification capabilities.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
from .auth import AuthService
|
|
9
|
+
from .notification import NotificationService
|
|
9
10
|
|
|
10
11
|
__version__ = "1.0.8"
|
|
11
12
|
__author__ = "Bright Debrah Owusu"
|
|
12
13
|
__email__ = "owusu.debrah@deladetech.com"
|
|
13
14
|
|
|
14
15
|
__all__ = [
|
|
15
|
-
"AuthService"
|
|
16
|
+
"AuthService",
|
|
17
|
+
"NotificationService"
|
|
16
18
|
]
|
trovesuite/auth/__init__.py
CHANGED
|
@@ -5,13 +5,10 @@ Authentication and authorization services for ERP systems.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from .auth_service import AuthService
|
|
8
|
-
from .
|
|
9
|
-
from .auth_read_dto import AuthServiceReadDto, AuthControllerReadDto
|
|
8
|
+
from .auth_write_dto import AuthServiceWriteDto
|
|
10
9
|
|
|
11
10
|
__all__ = [
|
|
12
11
|
"AuthService",
|
|
13
|
-
"
|
|
14
|
-
"AuthServiceReadDto",
|
|
15
|
-
"AuthControllerReadDto"
|
|
12
|
+
"AuthServiceWriteDto"
|
|
16
13
|
]
|
|
17
14
|
|
|
@@ -2,9 +2,10 @@ from fastapi import APIRouter
|
|
|
2
2
|
from src.trovesuite.auth.auth_write_dto import AuthControllerWriteDto
|
|
3
3
|
from src.trovesuite.auth.auth_read_dto import AuthControllerReadDto
|
|
4
4
|
from src.trovesuite.auth.auth_service import AuthService
|
|
5
|
+
from src.trovesuite.entities.sh_response import Respons
|
|
5
6
|
|
|
6
7
|
auth_router = APIRouter()
|
|
7
8
|
|
|
8
|
-
@auth_router.post("/auth", response_model=AuthControllerReadDto)
|
|
9
|
+
@auth_router.post("/auth", response_model=Respons[AuthControllerReadDto])
|
|
9
10
|
async def authorize(data: AuthControllerWriteDto):
|
|
10
11
|
return AuthService.authorize(data=data)
|
trovesuite/auth/auth_read_dto.py
CHANGED
|
@@ -11,7 +11,6 @@ class AuthControllerReadDto(BaseModel):
|
|
|
11
11
|
role_id: Optional[str] = None
|
|
12
12
|
tenant_id: Optional[str] = None
|
|
13
13
|
permissions: Optional[List[str]] = None
|
|
14
|
-
shared_resource_id: Optional[str] = None
|
|
15
14
|
resource_id: Optional[str] = None
|
|
16
15
|
|
|
17
16
|
class AuthServiceReadDto(AuthControllerReadDto):
|
trovesuite/auth/auth_service.py
CHANGED
|
@@ -48,7 +48,7 @@ class AuthService:
|
|
|
48
48
|
|
|
49
49
|
user_id: str = data.user_id
|
|
50
50
|
tenant_id: str = data.tenant_id
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
"""Check if a user is authorized based on login settings and roles"""
|
|
53
53
|
# Input validation
|
|
54
54
|
if not user_id or not isinstance(user_id, str):
|
|
@@ -68,14 +68,14 @@ class AuthService:
|
|
|
68
68
|
status_code=400,
|
|
69
69
|
error="INVALID_TENANT_ID"
|
|
70
70
|
)
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
try:
|
|
73
73
|
|
|
74
74
|
is_tenant_verified = DatabaseManager.execute_query(
|
|
75
75
|
f"SELECT is_verified FROM {db_settings.MAIN_TENANTS_TABLE} WHERE delete_status = 'NOT_DELETED' AND id = %s",
|
|
76
76
|
(tenant_id,),
|
|
77
77
|
)
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
if not is_tenant_verified or len(is_tenant_verified) == 0:
|
|
80
80
|
logger.warning("Login failed - tenant not found: %s", tenant_id)
|
|
81
81
|
return Respons[AuthServiceReadDto](
|
trovesuite/configs/database.py
CHANGED
|
@@ -13,7 +13,6 @@ logger = get_logger("database")
|
|
|
13
13
|
|
|
14
14
|
# Database connection pool
|
|
15
15
|
_connection_pool: Optional[psycopg2.pool.ThreadedConnectionPool] = None
|
|
16
|
-
_sqlmodel_engine = None
|
|
17
16
|
|
|
18
17
|
|
|
19
18
|
class DatabaseConfig:
|
|
@@ -21,16 +20,20 @@ class DatabaseConfig:
|
|
|
21
20
|
|
|
22
21
|
def __init__(self):
|
|
23
22
|
self.settings = db_settings
|
|
23
|
+
self.database_url = self.settings.database_url
|
|
24
24
|
self.pool_size = 5
|
|
25
25
|
self.max_overflow = 10
|
|
26
|
-
|
|
27
|
-
@property
|
|
28
|
-
def database_url(self):
|
|
29
|
-
"""Get database URL (lazy evaluation)"""
|
|
30
|
-
return self.settings.database_url
|
|
31
26
|
|
|
32
27
|
def get_connection_params(self) -> dict:
|
|
33
28
|
"""Get database connection parameters"""
|
|
29
|
+
if self.settings.DATABASE_URL:
|
|
30
|
+
# Use full DATABASE_URL if available
|
|
31
|
+
return {
|
|
32
|
+
"dsn": self.settings.DATABASE_URL,
|
|
33
|
+
"cursor_factory": RealDictCursor
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# fallback to individual DB_* variables
|
|
34
37
|
return {
|
|
35
38
|
"host": self.settings.DB_HOST,
|
|
36
39
|
"port": self.settings.DB_PORT,
|
|
@@ -98,18 +101,19 @@ def get_connection_pool() -> psycopg2.pool.ThreadedConnectionPool:
|
|
|
98
101
|
"""Get the database connection pool"""
|
|
99
102
|
global _connection_pool
|
|
100
103
|
if _connection_pool is None:
|
|
101
|
-
|
|
104
|
+
error_msg = (
|
|
105
|
+
"Database not initialized. This usually means:\n"
|
|
106
|
+
"1. Missing or incorrect .env file in app/ directory\n"
|
|
107
|
+
"2. Database credentials are wrong\n"
|
|
108
|
+
"3. Database container is not running\n"
|
|
109
|
+
"4. Database initialization failed during startup\n"
|
|
110
|
+
"Please check the startup logs for more details."
|
|
111
|
+
)
|
|
112
|
+
logger.error(error_msg)
|
|
113
|
+
raise Exception(error_msg)
|
|
102
114
|
return _connection_pool
|
|
103
115
|
|
|
104
116
|
|
|
105
|
-
def get_sqlmodel_engine():
|
|
106
|
-
"""Get the SQLModel engine"""
|
|
107
|
-
global _sqlmodel_engine
|
|
108
|
-
if _sqlmodel_engine is None:
|
|
109
|
-
raise Exception("Database not initialized. Call initialize_database() first.")
|
|
110
|
-
return _sqlmodel_engine
|
|
111
|
-
|
|
112
|
-
|
|
113
117
|
@contextmanager
|
|
114
118
|
def get_db_connection():
|
|
115
119
|
"""Get a database connection from the pool (context manager)"""
|
|
@@ -217,5 +221,13 @@ class DatabaseManager:
|
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
|
|
220
|
-
# Database initialization
|
|
221
|
-
|
|
224
|
+
# Database initialization on module import
|
|
225
|
+
try:
|
|
226
|
+
initialize_database()
|
|
227
|
+
except Exception as e:
|
|
228
|
+
logger.error(f"Failed to initialize database on startup: {str(e)}")
|
|
229
|
+
logger.error("⚠️ CRITICAL: Application started without database connection!")
|
|
230
|
+
logger.error("⚠️ Please check your .env file and database configuration")
|
|
231
|
+
logger.error("⚠️ The application will not function properly without a database connection")
|
|
232
|
+
# Don't raise here to allow the app to start even if DB is unavailable
|
|
233
|
+
# But log it clearly so it's obvious what's wrong
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TroveSuite Notification Service
|
|
3
|
+
|
|
4
|
+
Provides email and SMS notification capabilities for TroveSuite applications.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .notification_service import NotificationService
|
|
8
|
+
from .notification_write_dto import NotificationEmailServiceWriteDto, NotificationSMSServiceWriteDto
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"NotificationService",
|
|
12
|
+
"NotificationEmailServiceWriteDto",
|
|
13
|
+
"NotificationSMSServiceWriteDto"
|
|
14
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from typing import List, Optional, Union
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
class NotificationEmailBase(BaseModel):
|
|
5
|
+
sender_email: str
|
|
6
|
+
receiver_email: Union[str, List[str]]
|
|
7
|
+
password: str
|
|
8
|
+
subject: str
|
|
9
|
+
text_message: str
|
|
10
|
+
html_message: Optional[str] = None
|
|
11
|
+
|
|
12
|
+
class NotificationSMSBase(BaseModel):
|
|
13
|
+
pass
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from src.trovesuite.notification.notification_write_dto import (
|
|
2
|
+
NotificationEmailControllerWriteDto,
|
|
3
|
+
NotificationSMSControllerWriteDto
|
|
4
|
+
)
|
|
5
|
+
from src.trovesuite.notification.notification_read_dto import (
|
|
6
|
+
NotificationEmailControllerReadDto,
|
|
7
|
+
NotificationSMSControllerReadDto
|
|
8
|
+
)
|
|
9
|
+
from src.trovesuite.notification.notification_service import NotificationService
|
|
10
|
+
from src.trovesuite.entities.sh_response import Respons
|
|
11
|
+
from fastapi import APIRouter
|
|
12
|
+
|
|
13
|
+
notification_router = APIRouter()
|
|
14
|
+
|
|
15
|
+
@notification_router.post("/send_email", response_model=Respons[NotificationEmailControllerReadDto])
|
|
16
|
+
async def send_email(data: NotificationEmailControllerWriteDto):
|
|
17
|
+
return NotificationService.send_email(data=data)
|
|
18
|
+
|
|
19
|
+
@notification_router.post("/send_sms", response_model=Respons[NotificationSMSControllerReadDto])
|
|
20
|
+
async def send_sms(data: NotificationSMSControllerWriteDto):
|
|
21
|
+
return NotificationService.send_sms(data=data)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from src.trovesuite.notification.notification_base import (
|
|
2
|
+
NotificationEmailBase,
|
|
3
|
+
NotificationSMSBase
|
|
4
|
+
)
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
# EMAIL Notification
|
|
8
|
+
|
|
9
|
+
class NotificationEmailControllerReadDto(NotificationEmailBase):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
class NotificationEmailServiceReadDto(BaseModel):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
# SMS Notification
|
|
16
|
+
|
|
17
|
+
class NotificationSMSControllerReadDto(NotificationSMSBase):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
class NotificationSMSServiceReadDto(BaseModel):
|
|
21
|
+
pass
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import smtplib
|
|
2
|
+
from email.mime.text import MIMEText
|
|
3
|
+
from email.mime.multipart import MIMEMultipart
|
|
4
|
+
from src.trovesuite.entities.sh_response import Respons
|
|
5
|
+
from src.trovesuite.notification.notification_read_dto import (
|
|
6
|
+
NotificationEmailServiceReadDto,
|
|
7
|
+
NotificationSMSServiceReadDto
|
|
8
|
+
)
|
|
9
|
+
from src.trovesuite.notification.notification_write_dto import (
|
|
10
|
+
NotificationEmailServiceWriteDto,
|
|
11
|
+
NotificationSMSServiceWriteDto
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
class NotificationService:
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def send_email(data: NotificationEmailServiceWriteDto) -> Respons[NotificationEmailServiceReadDto]:
|
|
18
|
+
"""
|
|
19
|
+
Send an email (single or multiple recipients) via Gmail SMTP.
|
|
20
|
+
Supports both plain text and HTML email bodies.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# Extract input data
|
|
24
|
+
receiver_email = data.receiver_email
|
|
25
|
+
text_message = data.text_message
|
|
26
|
+
html_message = getattr(data, "html_message", None)
|
|
27
|
+
sender_email = data.sender_email
|
|
28
|
+
password = data.password
|
|
29
|
+
subject = data.subject
|
|
30
|
+
|
|
31
|
+
# Allow single email or list
|
|
32
|
+
if isinstance(receiver_email, str):
|
|
33
|
+
receiver_email = [receiver_email]
|
|
34
|
+
|
|
35
|
+
# Create the email container
|
|
36
|
+
message = MIMEMultipart("alternative")
|
|
37
|
+
message["From"] = sender_email
|
|
38
|
+
message["To"] = ", ".join(receiver_email)
|
|
39
|
+
message["Subject"] = subject
|
|
40
|
+
|
|
41
|
+
# Attach plain text
|
|
42
|
+
message.attach(MIMEText(text_message, "plain"))
|
|
43
|
+
|
|
44
|
+
# Attach HTML if provided
|
|
45
|
+
if html_message:
|
|
46
|
+
message.attach(MIMEText(html_message, "html"))
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
with smtplib.SMTP_SSL("smtp.gmail.com", 465) as server:
|
|
50
|
+
server.login(sender_email, password)
|
|
51
|
+
server.sendmail(sender_email, receiver_email, message.as_string())
|
|
52
|
+
|
|
53
|
+
return Respons[NotificationEmailServiceReadDto](
|
|
54
|
+
detail=f"Email successfully sent to {len(receiver_email)} recipient(s)",
|
|
55
|
+
error=None,
|
|
56
|
+
data=[],
|
|
57
|
+
status_code=200,
|
|
58
|
+
success=True,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
except Exception as e:
|
|
62
|
+
print(e)
|
|
63
|
+
return Respons[NotificationEmailServiceReadDto](
|
|
64
|
+
detail="An error occurred while sending the email",
|
|
65
|
+
error=str(e),
|
|
66
|
+
data=[],
|
|
67
|
+
status_code=500,
|
|
68
|
+
success=False,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@staticmethod
|
|
72
|
+
def send_sms(data: NotificationSMSServiceWriteDto) -> Respons[NotificationSMSServiceReadDto]:
|
|
73
|
+
pass
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from src.trovesuite.notification.notification_base import (
|
|
3
|
+
NotificationEmailBase,
|
|
4
|
+
NotificationSMSBase
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
# Email Notification
|
|
8
|
+
|
|
9
|
+
class NotificationEmailControllerWriteDto(NotificationEmailBase):
|
|
10
|
+
pass
|
|
11
|
+
|
|
12
|
+
class NotificationEmailServiceWriteDto(NotificationEmailControllerWriteDto):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
# SMS Notification
|
|
16
|
+
|
|
17
|
+
class NotificationSMSControllerWriteDto(NotificationSMSBase):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
class NotificationSMSServiceWriteDto(BaseModel):
|
|
21
|
+
pass
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: trovesuite
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.5
|
|
4
4
|
Summary: TroveSuite services package providing authentication, authorization, notifications, and other enterprise services for TroveSuite applications
|
|
5
5
|
Home-page: https://dev.azure.com/brightgclt/trovesuite/_git/packages
|
|
6
6
|
Author: Bright Debrah Owusu
|
|
@@ -34,6 +34,8 @@ Requires-Dist: python-multipart>=0.0.6
|
|
|
34
34
|
Requires-Dist: python-jose[cryptography]>=3.3.0
|
|
35
35
|
Requires-Dist: passlib[bcrypt]>=1.7.4
|
|
36
36
|
Requires-Dist: passlib[argon2]<2.0.0,>=1.7.4
|
|
37
|
+
Requires-Dist: uvicorn<0.39.0,>=0.38.0
|
|
38
|
+
Requires-Dist: pyjwt<3.0.0,>=2.10.1
|
|
37
39
|
Provides-Extra: dev
|
|
38
40
|
Requires-Dist: pytest>=8.4.2; extra == "dev"
|
|
39
41
|
Requires-Dist: pytest-asyncio>=0.21.1; extra == "dev"
|
|
@@ -117,10 +119,26 @@ poetry install --with dev
|
|
|
117
119
|
|
|
118
120
|
## Quick Start
|
|
119
121
|
|
|
122
|
+
### Import Patterns
|
|
123
|
+
|
|
124
|
+
The package provides clean, simplified import patterns:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
# Import services and DTOs from main package
|
|
128
|
+
from trovesuite import AuthService, NotificationService
|
|
129
|
+
from trovesuite.auth import AuthServiceWriteDto
|
|
130
|
+
from trovesuite.notification import NotificationEmailServiceWriteDto, NotificationSMSServiceWriteDto
|
|
131
|
+
|
|
132
|
+
# Or import everything you need in one line
|
|
133
|
+
from trovesuite import AuthService, NotificationService
|
|
134
|
+
from trovesuite.auth import AuthServiceWriteDto
|
|
135
|
+
from trovesuite.notification import NotificationEmailServiceWriteDto
|
|
136
|
+
```
|
|
137
|
+
|
|
120
138
|
### Basic Usage
|
|
121
139
|
|
|
122
140
|
```python
|
|
123
|
-
from trovesuite import AuthService
|
|
141
|
+
from trovesuite import AuthService, NotificationService
|
|
124
142
|
from trovesuite.configs.settings import db_settings
|
|
125
143
|
|
|
126
144
|
# Configure your database settings
|
|
@@ -135,7 +153,7 @@ db_settings.SECRET_KEY = "your-secret-key"
|
|
|
135
153
|
auth_service = AuthService()
|
|
136
154
|
|
|
137
155
|
# Authorize a user
|
|
138
|
-
from trovesuite.auth
|
|
156
|
+
from trovesuite.auth import AuthServiceWriteDto
|
|
139
157
|
auth_data = AuthServiceWriteDto(user_id="user123", tenant="tenant456")
|
|
140
158
|
result = AuthService.authorize(auth_data)
|
|
141
159
|
|
|
@@ -147,6 +165,30 @@ else:
|
|
|
147
165
|
print(f"Authorization failed: {result.detail}")
|
|
148
166
|
```
|
|
149
167
|
|
|
168
|
+
### Notification Service Usage
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from trovesuite import NotificationService
|
|
172
|
+
from trovesuite.notification import NotificationEmailServiceWriteDto
|
|
173
|
+
|
|
174
|
+
# Send an email notification
|
|
175
|
+
email_data = NotificationEmailServiceWriteDto(
|
|
176
|
+
sender_email="your-email@gmail.com",
|
|
177
|
+
receiver_email=["recipient1@example.com", "recipient2@example.com"],
|
|
178
|
+
password="your-app-password", # Gmail app password
|
|
179
|
+
subject="Test Notification",
|
|
180
|
+
text_message="This is a plain text message",
|
|
181
|
+
html_message="<h1>This is an HTML message</h1><p>With rich formatting!</p>"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
result = NotificationService.send_email(email_data)
|
|
185
|
+
|
|
186
|
+
if result.success:
|
|
187
|
+
print(f"Email sent successfully: {result.detail}")
|
|
188
|
+
else:
|
|
189
|
+
print(f"Email failed: {result.error}")
|
|
190
|
+
```
|
|
191
|
+
|
|
150
192
|
### JWT Token Decoding
|
|
151
193
|
|
|
152
194
|
```python
|
|
@@ -164,7 +206,7 @@ async def protected_route(token: str = Depends(oauth2_scheme)):
|
|
|
164
206
|
tenant_id = user_data["tenant_id"]
|
|
165
207
|
|
|
166
208
|
# Authorize user
|
|
167
|
-
from trovesuite.auth
|
|
209
|
+
from trovesuite.auth import AuthServiceWriteDto
|
|
168
210
|
auth_data = AuthServiceWriteDto(user_id=user_id, tenant=tenant_id)
|
|
169
211
|
auth_result = AuthService.authorize(auth_data)
|
|
170
212
|
return auth_result
|
|
@@ -393,8 +435,84 @@ Check if user has all of the required permissions.
|
|
|
393
435
|
**Returns:**
|
|
394
436
|
- `bool`: True if user has all of the required permissions
|
|
395
437
|
|
|
438
|
+
### NotificationService
|
|
439
|
+
|
|
440
|
+
#### `send_email(data: NotificationEmailServiceWriteDto) -> Respons[NotificationEmailServiceReadDto]`
|
|
441
|
+
|
|
442
|
+
Sends an email notification via Gmail SMTP. Supports both plain text and HTML email bodies.
|
|
443
|
+
|
|
444
|
+
**Parameters:**
|
|
445
|
+
- `data`: Email notification data including sender, recipients, subject, and message content
|
|
446
|
+
|
|
447
|
+
**Returns:**
|
|
448
|
+
- `Respons[NotificationEmailServiceReadDto]`: Email sending result with success status and details
|
|
449
|
+
|
|
450
|
+
**Example:**
|
|
451
|
+
```python
|
|
452
|
+
from trovesuite import NotificationService
|
|
453
|
+
from trovesuite.notification import NotificationEmailServiceWriteDto
|
|
454
|
+
|
|
455
|
+
email_data = NotificationEmailServiceWriteDto(
|
|
456
|
+
sender_email="sender@gmail.com",
|
|
457
|
+
receiver_email=["user1@example.com", "user2@example.com"],
|
|
458
|
+
password="your-gmail-app-password",
|
|
459
|
+
subject="Welcome to TroveSuite",
|
|
460
|
+
text_message="Welcome! This is a plain text message.",
|
|
461
|
+
html_message="<h1>Welcome!</h1><p>This is an <strong>HTML</strong> message.</p>"
|
|
462
|
+
)
|
|
463
|
+
|
|
464
|
+
result = NotificationService.send_email(email_data)
|
|
465
|
+
if result.success:
|
|
466
|
+
print("Email sent successfully!")
|
|
467
|
+
else:
|
|
468
|
+
print(f"Failed to send email: {result.error}")
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
#### `send_sms(data: NotificationSMSServiceWriteDto) -> Respons[NotificationSMSServiceReadDto]`
|
|
472
|
+
|
|
473
|
+
Sends an SMS notification (currently not implemented).
|
|
474
|
+
|
|
475
|
+
**Parameters:**
|
|
476
|
+
- `data`: SMS notification data
|
|
477
|
+
|
|
478
|
+
**Returns:**
|
|
479
|
+
- `Respons[NotificationSMSServiceReadDto]`: SMS sending result
|
|
480
|
+
|
|
396
481
|
### Data Models
|
|
397
482
|
|
|
483
|
+
#### `NotificationEmailServiceWriteDto`
|
|
484
|
+
|
|
485
|
+
```python
|
|
486
|
+
class NotificationEmailServiceWriteDto(BaseModel):
|
|
487
|
+
sender_email: str
|
|
488
|
+
receiver_email: Union[str, List[str]] # Single email or list of emails
|
|
489
|
+
password: str # Gmail app password
|
|
490
|
+
subject: str
|
|
491
|
+
text_message: str
|
|
492
|
+
html_message: Optional[str] = None # Optional HTML content
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
#### `NotificationEmailServiceReadDto`
|
|
496
|
+
|
|
497
|
+
```python
|
|
498
|
+
class NotificationEmailServiceReadDto(BaseModel):
|
|
499
|
+
pass # Empty response model for email service
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
#### `NotificationSMSServiceWriteDto`
|
|
503
|
+
|
|
504
|
+
```python
|
|
505
|
+
class NotificationSMSServiceWriteDto(BaseModel):
|
|
506
|
+
pass # To be implemented for SMS functionality
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
#### `NotificationSMSServiceReadDto`
|
|
510
|
+
|
|
511
|
+
```python
|
|
512
|
+
class NotificationSMSServiceReadDto(BaseModel):
|
|
513
|
+
pass # To be implemented for SMS functionality
|
|
514
|
+
```
|
|
515
|
+
|
|
398
516
|
#### `AuthServiceReadDto`
|
|
399
517
|
|
|
400
518
|
```python
|
|
@@ -563,7 +681,7 @@ For support, email brightgclt@gmail.com or create a work item in the [Azure DevO
|
|
|
563
681
|
|
|
564
682
|
### 1.0.8
|
|
565
683
|
- Restructured package for direct service imports
|
|
566
|
-
- Added notification services
|
|
684
|
+
- Added comprehensive notification services with email support
|
|
567
685
|
- Excluded controllers from package build
|
|
568
686
|
- Updated import paths for better usability
|
|
569
687
|
- JWT token validation
|
|
@@ -572,3 +690,6 @@ For support, email brightgclt@gmail.com or create a work item in the [Azure DevO
|
|
|
572
690
|
- PostgreSQL database integration
|
|
573
691
|
- Comprehensive logging
|
|
574
692
|
- Azure integration support
|
|
693
|
+
- Email notification service with Gmail SMTP support
|
|
694
|
+
- Support for both plain text and HTML email content
|
|
695
|
+
- Multiple recipient support for email notifications
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
trovesuite/__init__.py,sha256=c7z8TrIWz156VyDw2qEclTdJxKqAdbhQyCjDLY4s0uM,457
|
|
2
|
+
trovesuite/auth/__init__.py,sha256=OjZllVvjul1glDazJ-d5TrNjgHFigFlQQi1G99DYshk,239
|
|
3
|
+
trovesuite/auth/auth_base.py,sha256=rZHQVLeJRBQ8GClgF5UwG-er4_HXVX5-nt8o6_Z29uY,75
|
|
4
|
+
trovesuite/auth/auth_controller.py,sha256=mMAyTV_0rFeArpcIDu9Pr_IATvFZU6wfIo6ViQoUv0U,477
|
|
5
|
+
trovesuite/auth/auth_read_dto.py,sha256=pQT1ouRVZMAiJn4wAG7NQOKQKTquTMWUe-dYcpLTmEo,533
|
|
6
|
+
trovesuite/auth/auth_service.py,sha256=if2RFI6F1DpbNEuCTSpPbhHVBdYQEg4hVkoxTCnvC4k,14298
|
|
7
|
+
trovesuite/auth/auth_write_dto.py,sha256=rdwI7w6-9QZGv1H0PAGrjkLBCzaMHjgPIXeLb9RmNec,234
|
|
8
|
+
trovesuite/configs/__init__.py,sha256=h1mSZOaZ3kUy1ZMO_m9O9KklsxywM0RfMVZLh9h9WvQ,328
|
|
9
|
+
trovesuite/configs/database.py,sha256=TYPlwydfWirOvCdA1N2gdqJWeesnxLBmRcxqVInZzEA,8320
|
|
10
|
+
trovesuite/configs/logging.py,sha256=mGjR2d4urVNry9l5_aXycMMtcY2RAFIpEL35hw33KZg,9308
|
|
11
|
+
trovesuite/configs/settings.py,sha256=yUbkiFi4QdO9JZG1RRFbP4tYurT47HmN-ohgYcs2SHM,2561
|
|
12
|
+
trovesuite/entities/__init__.py,sha256=Dbl_03Bueyh2vOP2hykd40MmNMrl5nNHSRGP-kqwwNo,160
|
|
13
|
+
trovesuite/entities/health.py,sha256=H8-XUywzvMfZy2dZwDyJGAUbmuULuZYvYIUWhiaVGdY,2729
|
|
14
|
+
trovesuite/entities/sh_response.py,sha256=1_sw3PpVaDxWsNiBU0W9YLHZgTFxEj4JJBLBfSY63Ho,1579
|
|
15
|
+
trovesuite/notification/__init__.py,sha256=mjglzmlk29SREP6LfvBYGmCSc-K1SKKAEx_OJdJ2Vrs,394
|
|
16
|
+
trovesuite/notification/notification_base.py,sha256=6Xo0Gnnpg3RgN1_SRkAcH-K4l7DwNDZvn1gRm3oMWyk,320
|
|
17
|
+
trovesuite/notification/notification_controller.py,sha256=w-SpRTjeInrgsUX0sAzFVjXiBo395ge6v-dn1Cc8ogU,920
|
|
18
|
+
trovesuite/notification/notification_read_dto.py,sha256=pZg3KHZJA4c5MoXqTHCgUiGnd8mRrQjVOaCtWXtuT7U,450
|
|
19
|
+
trovesuite/notification/notification_service.py,sha256=u3-rHnTr3dgLX_RGjkG6c9mYVPspRCSEDBtDrGN-Rj0,2500
|
|
20
|
+
trovesuite/notification/notification_write_dto.py,sha256=WrdFWIa9sK5rrwgp1bUOOikwE7xL8O9z110EGnXedzw,479
|
|
21
|
+
trovesuite/utils/__init__.py,sha256=3UPKTz9cluTgAM-ldNsJxsnoPTZiqacXlAmzUEHy6q8,143
|
|
22
|
+
trovesuite/utils/helper.py,sha256=lvZ1mvaqY84dkIPB5Ov0uwYDOWBziAS8twobEJZh2Ik,1002
|
|
23
|
+
trovesuite-1.0.5.dist-info/licenses/LICENSE,sha256=EJT35ct-Q794JYPdAQy3XNczQGKkU1HzToLeK1YVw2s,1070
|
|
24
|
+
trovesuite-1.0.5.dist-info/METADATA,sha256=JD98gu0c53MANB7pMF73Eg6axkfk_RW3HpmSU5KFVOA,19704
|
|
25
|
+
trovesuite-1.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
26
|
+
trovesuite-1.0.5.dist-info/top_level.txt,sha256=GzKhG_-MTaxeHrIgkGkBH_nof2vroGFBrjeHKWUIwNc,11
|
|
27
|
+
trovesuite-1.0.5.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
trovesuite/__init__.py,sha256=a9jSrjmrhOey6yE2I83TO_rVJDogIwGDyL3HJBGiGqM,347
|
|
2
|
-
trovesuite/auth/__init__.py,sha256=d8d5POjq9lGe7GVbc7Qm6hUpx1bgLqEVQFG1iYafdxI,337
|
|
3
|
-
trovesuite/auth/auth_base.py,sha256=rZHQVLeJRBQ8GClgF5UwG-er4_HXVX5-nt8o6_Z29uY,75
|
|
4
|
-
trovesuite/auth/auth_controller.py,sha256=47LsxPvE2wCqpadLPf_m68M8eR7Zu9HxfSSxZQZKQyM,412
|
|
5
|
-
trovesuite/auth/auth_read_dto.py,sha256=3gSyz6YrdXvH6yPSPnqDpOmccWnSY-oH_c7izX96_LA,578
|
|
6
|
-
trovesuite/auth/auth_service.py,sha256=hz76IhwFG9T9YIivJt70Ao0ywEgHRrB0yly7Rr8uOv8,14286
|
|
7
|
-
trovesuite/auth/auth_write_dto.py,sha256=TkZw78-XNSr5Gy4sCl6DBs1CFsX2V2yMttpSQiXsDqE,231
|
|
8
|
-
trovesuite/configs/__init__.py,sha256=h1mSZOaZ3kUy1ZMO_m9O9KklsxywM0RfMVZLh9h9WvQ,328
|
|
9
|
-
trovesuite/configs/database.py,sha256=tXj-AYIUs-gjYrgioTnQafbDhsaIsgimWWLXR3ru-1A,7580
|
|
10
|
-
trovesuite/configs/logging.py,sha256=mGjR2d4urVNry9l5_aXycMMtcY2RAFIpEL35hw33KZg,9308
|
|
11
|
-
trovesuite/configs/settings.py,sha256=yUbkiFi4QdO9JZG1RRFbP4tYurT47HmN-ohgYcs2SHM,2561
|
|
12
|
-
trovesuite/entities/__init__.py,sha256=Dbl_03Bueyh2vOP2hykd40MmNMrl5nNHSRGP-kqwwNo,160
|
|
13
|
-
trovesuite/entities/health.py,sha256=H8-XUywzvMfZy2dZwDyJGAUbmuULuZYvYIUWhiaVGdY,2729
|
|
14
|
-
trovesuite/entities/sh_response.py,sha256=1_sw3PpVaDxWsNiBU0W9YLHZgTFxEj4JJBLBfSY63Ho,1579
|
|
15
|
-
trovesuite/utils/__init__.py,sha256=3UPKTz9cluTgAM-ldNsJxsnoPTZiqacXlAmzUEHy6q8,143
|
|
16
|
-
trovesuite/utils/helper.py,sha256=lvZ1mvaqY84dkIPB5Ov0uwYDOWBziAS8twobEJZh2Ik,1002
|
|
17
|
-
trovesuite-1.0.3.dist-info/licenses/LICENSE,sha256=EJT35ct-Q794JYPdAQy3XNczQGKkU1HzToLeK1YVw2s,1070
|
|
18
|
-
trovesuite-1.0.3.dist-info/METADATA,sha256=ytVHnT7Y477a_2vvdMx3Lb9dC-dFPwsv2ptN_0HW1uM,15925
|
|
19
|
-
trovesuite-1.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
20
|
-
trovesuite-1.0.3.dist-info/top_level.txt,sha256=GzKhG_-MTaxeHrIgkGkBH_nof2vroGFBrjeHKWUIwNc,11
|
|
21
|
-
trovesuite-1.0.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|