trovesuite 1.0.1__py3-none-any.whl → 1.0.31__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 +12 -5
- trovesuite/auth/__init__.py +2 -5
- trovesuite/auth/auth_controller.py +6 -5
- trovesuite/auth/auth_read_dto.py +3 -3
- trovesuite/auth/auth_service.py +223 -80
- trovesuite/auth/auth_write_dto.py +1 -1
- trovesuite/configs/database.py +212 -58
- trovesuite/configs/settings.py +75 -132
- trovesuite/entities/health.py +4 -4
- 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/storage/__init__.py +42 -0
- trovesuite/storage/storage_base.py +63 -0
- trovesuite/storage/storage_controller.py +198 -0
- trovesuite/storage/storage_read_dto.py +74 -0
- trovesuite/storage/storage_service.py +529 -0
- trovesuite/storage/storage_write_dto.py +70 -0
- trovesuite/utils/__init__.py +3 -1
- trovesuite/utils/helper.py +714 -5
- trovesuite/utils/templates.py +487 -0
- {trovesuite-1.0.1.dist-info → trovesuite-1.0.31.dist-info}/METADATA +184 -9
- trovesuite-1.0.31.dist-info/RECORD +34 -0
- trovesuite-1.0.1.dist-info/RECORD +0 -21
- {trovesuite-1.0.1.dist-info → trovesuite-1.0.31.dist-info}/WHEEL +0 -0
- {trovesuite-1.0.1.dist-info → trovesuite-1.0.31.dist-info}/licenses/LICENSE +0 -0
- {trovesuite-1.0.1.dist-info → trovesuite-1.0.31.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from .notification_write_dto import (
|
|
2
|
+
NotificationEmailControllerWriteDto,
|
|
3
|
+
NotificationSMSControllerWriteDto
|
|
4
|
+
)
|
|
5
|
+
from .notification_read_dto import (
|
|
6
|
+
NotificationEmailControllerReadDto,
|
|
7
|
+
NotificationSMSControllerReadDto
|
|
8
|
+
)
|
|
9
|
+
from .notification_service import NotificationService
|
|
10
|
+
from ..entities.sh_response import Respons
|
|
11
|
+
from fastapi import APIRouter
|
|
12
|
+
|
|
13
|
+
notification_router = APIRouter(tags=["Notification"])
|
|
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 .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 ..entities.sh_response import Respons
|
|
5
|
+
from .notification_read_dto import (
|
|
6
|
+
NotificationEmailServiceReadDto,
|
|
7
|
+
NotificationSMSServiceReadDto
|
|
8
|
+
)
|
|
9
|
+
from .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 .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
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TroveSuite Storage Service
|
|
3
|
+
|
|
4
|
+
Provides Azure Storage blob management capabilities for TroveSuite applications.
|
|
5
|
+
Includes container creation, file upload/download/update/delete, and presigned URL generation.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .storage_service import StorageService
|
|
9
|
+
from .storage_write_dto import (
|
|
10
|
+
StorageContainerCreateServiceWriteDto,
|
|
11
|
+
StorageFileUploadServiceWriteDto,
|
|
12
|
+
StorageFileUpdateServiceWriteDto,
|
|
13
|
+
StorageFileDeleteServiceWriteDto,
|
|
14
|
+
StorageFileDownloadServiceWriteDto,
|
|
15
|
+
StorageFileUrlServiceWriteDto
|
|
16
|
+
)
|
|
17
|
+
from .storage_read_dto import (
|
|
18
|
+
StorageContainerCreateServiceReadDto,
|
|
19
|
+
StorageFileUploadServiceReadDto,
|
|
20
|
+
StorageFileUpdateServiceReadDto,
|
|
21
|
+
StorageFileDeleteServiceReadDto,
|
|
22
|
+
StorageFileDownloadServiceReadDto,
|
|
23
|
+
StorageFileUrlServiceReadDto
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"StorageService",
|
|
28
|
+
# Write DTOs
|
|
29
|
+
"StorageContainerCreateServiceWriteDto",
|
|
30
|
+
"StorageFileUploadServiceWriteDto",
|
|
31
|
+
"StorageFileUpdateServiceWriteDto",
|
|
32
|
+
"StorageFileDeleteServiceWriteDto",
|
|
33
|
+
"StorageFileDownloadServiceWriteDto",
|
|
34
|
+
"StorageFileUrlServiceWriteDto",
|
|
35
|
+
# Read DTOs
|
|
36
|
+
"StorageContainerCreateServiceReadDto",
|
|
37
|
+
"StorageFileUploadServiceReadDto",
|
|
38
|
+
"StorageFileUpdateServiceReadDto",
|
|
39
|
+
"StorageFileDeleteServiceReadDto",
|
|
40
|
+
"StorageFileDownloadServiceReadDto",
|
|
41
|
+
"StorageFileUrlServiceReadDto",
|
|
42
|
+
]
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class StorageConnectionBase(BaseModel):
|
|
6
|
+
"""Base model for Azure Storage connection using Managed Identity"""
|
|
7
|
+
storage_account_url: str # e.g., https://<account-name>.blob.core.windows.net
|
|
8
|
+
container_name: str
|
|
9
|
+
managed_identity_client_id: Optional[str] = None # Optional: For user-assigned managed identity
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class StorageFileUploadBase(BaseModel):
|
|
13
|
+
"""Base model for file upload operations"""
|
|
14
|
+
storage_account_url: str
|
|
15
|
+
container_name: str
|
|
16
|
+
file_content: bytes
|
|
17
|
+
blob_name: str
|
|
18
|
+
directory_path: Optional[str] = None
|
|
19
|
+
content_type: Optional[str] = None
|
|
20
|
+
managed_identity_client_id: Optional[str] = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class StorageFileUpdateBase(BaseModel):
|
|
24
|
+
"""Base model for file update operations"""
|
|
25
|
+
storage_account_url: str
|
|
26
|
+
container_name: str
|
|
27
|
+
blob_name: str
|
|
28
|
+
file_content: bytes
|
|
29
|
+
content_type: Optional[str] = None
|
|
30
|
+
managed_identity_client_id: Optional[str] = None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class StorageFileDeleteBase(BaseModel):
|
|
34
|
+
"""Base model for file delete operations"""
|
|
35
|
+
storage_account_url: str
|
|
36
|
+
container_name: str
|
|
37
|
+
blob_name: str
|
|
38
|
+
managed_identity_client_id: Optional[str] = None
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class StorageFileDownloadBase(BaseModel):
|
|
42
|
+
"""Base model for file download operations"""
|
|
43
|
+
storage_account_url: str
|
|
44
|
+
container_name: str
|
|
45
|
+
blob_name: str
|
|
46
|
+
managed_identity_client_id: Optional[str] = None
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class StorageFileUrlBase(BaseModel):
|
|
50
|
+
"""Base model for getting presigned URL"""
|
|
51
|
+
storage_account_url: str
|
|
52
|
+
container_name: str
|
|
53
|
+
blob_name: str
|
|
54
|
+
expiry_hours: Optional[int] = 1
|
|
55
|
+
managed_identity_client_id: Optional[str] = None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class StorageContainerCreateBase(BaseModel):
|
|
59
|
+
"""Base model for creating a container"""
|
|
60
|
+
storage_account_url: str
|
|
61
|
+
container_name: str
|
|
62
|
+
public_access: Optional[str] = None
|
|
63
|
+
managed_identity_client_id: Optional[str] = None
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
from fastapi import APIRouter, File, UploadFile, Form
|
|
3
|
+
from fastapi.responses import StreamingResponse
|
|
4
|
+
from io import BytesIO
|
|
5
|
+
from .storage_write_dto import (
|
|
6
|
+
StorageContainerCreateControllerWriteDto,
|
|
7
|
+
StorageFileUploadControllerWriteDto,
|
|
8
|
+
StorageFileUpdateControllerWriteDto,
|
|
9
|
+
StorageFileDeleteControllerWriteDto,
|
|
10
|
+
StorageFileDownloadControllerWriteDto,
|
|
11
|
+
StorageFileUrlControllerWriteDto
|
|
12
|
+
)
|
|
13
|
+
from .storage_read_dto import (
|
|
14
|
+
StorageContainerCreateControllerReadDto,
|
|
15
|
+
StorageFileUploadControllerReadDto,
|
|
16
|
+
StorageFileUpdateControllerReadDto,
|
|
17
|
+
StorageFileDeleteControllerReadDto,
|
|
18
|
+
StorageFileDownloadControllerReadDto,
|
|
19
|
+
StorageFileUrlControllerReadDto
|
|
20
|
+
)
|
|
21
|
+
from .storage_service import StorageService
|
|
22
|
+
from ..entities.sh_response import Respons
|
|
23
|
+
|
|
24
|
+
storage_router = APIRouter(tags=["File Storage"])
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@storage_router.post("/create-container", response_model=Respons[StorageContainerCreateControllerReadDto])
|
|
28
|
+
async def create_container(data: StorageContainerCreateControllerWriteDto):
|
|
29
|
+
"""
|
|
30
|
+
Create a new Azure Storage container.
|
|
31
|
+
|
|
32
|
+
Example request body:
|
|
33
|
+
{
|
|
34
|
+
"storage_account_url": "https://myaccount.blob.core.windows.net",
|
|
35
|
+
"container_name": "my-container",
|
|
36
|
+
"public_access": null,
|
|
37
|
+
"managed_identity_client_id": "your-client-id" // optional
|
|
38
|
+
}
|
|
39
|
+
"""
|
|
40
|
+
return StorageService.create_container(data=data)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@storage_router.post("/upload", response_model=Respons[StorageFileUploadControllerReadDto])
|
|
44
|
+
async def upload_file(
|
|
45
|
+
storage_account_url: str = Form(...),
|
|
46
|
+
container_name: str = Form(...),
|
|
47
|
+
blob_name: str = Form(...),
|
|
48
|
+
file: UploadFile = File(...),
|
|
49
|
+
directory_path: str = Form(None),
|
|
50
|
+
managed_identity_client_id: str = Form(None)
|
|
51
|
+
):
|
|
52
|
+
"""
|
|
53
|
+
Upload a file to Azure Storage.
|
|
54
|
+
|
|
55
|
+
Use form-data with the following fields:
|
|
56
|
+
- storage_account_url: Your Azure storage URL
|
|
57
|
+
- container_name: Container name
|
|
58
|
+
- blob_name: Name for the blob
|
|
59
|
+
- file: The file to upload
|
|
60
|
+
- directory_path: Optional directory path (e.g., "uploads/2024")
|
|
61
|
+
- managed_identity_client_id: Optional client ID for user-assigned managed identity
|
|
62
|
+
"""
|
|
63
|
+
content = await file.read()
|
|
64
|
+
|
|
65
|
+
upload_data = StorageFileUploadControllerWriteDto(
|
|
66
|
+
storage_account_url=storage_account_url,
|
|
67
|
+
container_name=container_name,
|
|
68
|
+
file_content=content,
|
|
69
|
+
blob_name=blob_name,
|
|
70
|
+
directory_path=directory_path,
|
|
71
|
+
content_type=file.content_type,
|
|
72
|
+
managed_identity_client_id=managed_identity_client_id
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
return StorageService.upload_file(data=upload_data)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@storage_router.put("/update", response_model=Respons[StorageFileUpdateControllerReadDto])
|
|
79
|
+
async def update_file(
|
|
80
|
+
storage_account_url: str = Form(...),
|
|
81
|
+
container_name: str = Form(...),
|
|
82
|
+
blob_name: str = Form(...),
|
|
83
|
+
file: UploadFile = File(...),
|
|
84
|
+
managed_identity_client_id: str = Form(None)
|
|
85
|
+
):
|
|
86
|
+
"""
|
|
87
|
+
Update an existing file in Azure Storage.
|
|
88
|
+
|
|
89
|
+
Use form-data with the following fields:
|
|
90
|
+
- storage_account_url: Your Azure storage URL
|
|
91
|
+
- container_name: Container name
|
|
92
|
+
- blob_name: Full blob name including path (e.g., "uploads/2024/file.pdf")
|
|
93
|
+
- file: The new file content
|
|
94
|
+
- managed_identity_client_id: Optional client ID for user-assigned managed identity
|
|
95
|
+
"""
|
|
96
|
+
content = await file.read()
|
|
97
|
+
|
|
98
|
+
update_data = StorageFileUpdateControllerWriteDto(
|
|
99
|
+
storage_account_url=storage_account_url,
|
|
100
|
+
container_name=container_name,
|
|
101
|
+
blob_name=blob_name,
|
|
102
|
+
file_content=content,
|
|
103
|
+
content_type=file.content_type,
|
|
104
|
+
managed_identity_client_id=managed_identity_client_id
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
return StorageService.update_file(data=update_data)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@storage_router.delete("/delete", response_model=Respons[StorageFileDeleteControllerReadDto])
|
|
111
|
+
async def delete_file(data: StorageFileDeleteControllerWriteDto):
|
|
112
|
+
"""
|
|
113
|
+
Delete a file from Azure Storage.
|
|
114
|
+
|
|
115
|
+
Example request body:
|
|
116
|
+
{
|
|
117
|
+
"storage_account_url": "https://myaccount.blob.core.windows.net",
|
|
118
|
+
"container_name": "my-container",
|
|
119
|
+
"blob_name": "uploads/2024/file.pdf",
|
|
120
|
+
"managed_identity_client_id": "your-client-id" // optional
|
|
121
|
+
}
|
|
122
|
+
"""
|
|
123
|
+
return StorageService.delete_file(data=data)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@storage_router.delete("/delete-multiple", response_model=Respons[StorageFileDeleteControllerReadDto])
|
|
127
|
+
async def delete_multiple_files(
|
|
128
|
+
storage_account_url: str,
|
|
129
|
+
container_name: str,
|
|
130
|
+
blob_names: List[str],
|
|
131
|
+
managed_identity_client_id: str = None
|
|
132
|
+
):
|
|
133
|
+
"""
|
|
134
|
+
Delete multiple files from Azure Storage.
|
|
135
|
+
|
|
136
|
+
Example request body:
|
|
137
|
+
{
|
|
138
|
+
"storage_account_url": "https://myaccount.blob.core.windows.net",
|
|
139
|
+
"container_name": "my-container",
|
|
140
|
+
"blob_names": ["file1.pdf", "file2.pdf", "folder/file3.jpg"],
|
|
141
|
+
"managed_identity_client_id": "your-client-id" // optional
|
|
142
|
+
}
|
|
143
|
+
"""
|
|
144
|
+
return StorageService.delete_multiple_files(
|
|
145
|
+
storage_account_url=storage_account_url,
|
|
146
|
+
container_name=container_name,
|
|
147
|
+
blob_names=blob_names,
|
|
148
|
+
managed_identity_client_id=managed_identity_client_id
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@storage_router.post("/download")
|
|
153
|
+
async def download_file(data: StorageFileDownloadControllerWriteDto):
|
|
154
|
+
"""
|
|
155
|
+
Download a file from Azure Storage.
|
|
156
|
+
|
|
157
|
+
Returns the file as a streaming response.
|
|
158
|
+
|
|
159
|
+
Example request body:
|
|
160
|
+
{
|
|
161
|
+
"storage_account_url": "https://myaccount.blob.core.windows.net",
|
|
162
|
+
"container_name": "my-container",
|
|
163
|
+
"blob_name": "uploads/2024/file.pdf",
|
|
164
|
+
"managed_identity_client_id": "your-client-id" // optional
|
|
165
|
+
}
|
|
166
|
+
"""
|
|
167
|
+
result = StorageService.download_file(data=data)
|
|
168
|
+
|
|
169
|
+
if not result.success:
|
|
170
|
+
return result
|
|
171
|
+
|
|
172
|
+
file_data = result.data[0]
|
|
173
|
+
|
|
174
|
+
# Return as streaming response
|
|
175
|
+
return StreamingResponse(
|
|
176
|
+
BytesIO(file_data.content),
|
|
177
|
+
media_type=file_data.content_type or "application/octet-stream",
|
|
178
|
+
headers={
|
|
179
|
+
"Content-Disposition": f"attachment; filename={data.blob_name.split('/')[-1]}"
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@storage_router.post("/get-url", response_model=Respons[StorageFileUrlControllerReadDto])
|
|
185
|
+
async def get_file_url(data: StorageFileUrlControllerWriteDto):
|
|
186
|
+
"""
|
|
187
|
+
Generate a presigned URL for a file.
|
|
188
|
+
|
|
189
|
+
Example request body:
|
|
190
|
+
{
|
|
191
|
+
"storage_account_url": "https://myaccount.blob.core.windows.net",
|
|
192
|
+
"container_name": "my-container",
|
|
193
|
+
"blob_name": "uploads/2024/file.pdf",
|
|
194
|
+
"expiry_hours": 2,
|
|
195
|
+
"managed_identity_client_id": "your-client-id" // optional
|
|
196
|
+
}
|
|
197
|
+
"""
|
|
198
|
+
return StorageService.get_file_url(data=data)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Container Creation
|
|
6
|
+
|
|
7
|
+
class StorageContainerCreateControllerReadDto(BaseModel):
|
|
8
|
+
container_name: str
|
|
9
|
+
container_url: Optional[str] = None
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class StorageContainerCreateServiceReadDto(StorageContainerCreateControllerReadDto):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# File Upload
|
|
17
|
+
|
|
18
|
+
class StorageFileUploadControllerReadDto(BaseModel):
|
|
19
|
+
blob_name: str
|
|
20
|
+
blob_url: str
|
|
21
|
+
content_type: Optional[str] = None
|
|
22
|
+
size: Optional[int] = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class StorageFileUploadServiceReadDto(StorageFileUploadControllerReadDto):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# File Update
|
|
30
|
+
|
|
31
|
+
class StorageFileUpdateControllerReadDto(BaseModel):
|
|
32
|
+
blob_name: str
|
|
33
|
+
blob_url: str
|
|
34
|
+
updated_at: Optional[str] = None
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class StorageFileUpdateServiceReadDto(StorageFileUpdateControllerReadDto):
|
|
38
|
+
pass
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# File Delete
|
|
42
|
+
|
|
43
|
+
class StorageFileDeleteControllerReadDto(BaseModel):
|
|
44
|
+
blob_name: str
|
|
45
|
+
deleted: bool
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class StorageFileDeleteServiceReadDto(StorageFileDeleteControllerReadDto):
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# File Download
|
|
53
|
+
|
|
54
|
+
class StorageFileDownloadControllerReadDto(BaseModel):
|
|
55
|
+
blob_name: str
|
|
56
|
+
content: bytes
|
|
57
|
+
content_type: Optional[str] = None
|
|
58
|
+
size: Optional[int] = None
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class StorageFileDownloadServiceReadDto(StorageFileDownloadControllerReadDto):
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
# File URL
|
|
66
|
+
|
|
67
|
+
class StorageFileUrlControllerReadDto(BaseModel):
|
|
68
|
+
blob_name: str
|
|
69
|
+
presigned_url: str
|
|
70
|
+
expires_in_hours: int
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class StorageFileUrlServiceReadDto(StorageFileUrlControllerReadDto):
|
|
74
|
+
pass
|