miso-client 0.1.0__py3-none-any.whl → 3.7.2__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.
- miso_client/__init__.py +523 -130
- miso_client/api/__init__.py +35 -0
- miso_client/api/auth_api.py +367 -0
- miso_client/api/logs_api.py +91 -0
- miso_client/api/permissions_api.py +88 -0
- miso_client/api/roles_api.py +88 -0
- miso_client/api/types/__init__.py +75 -0
- miso_client/api/types/auth_types.py +183 -0
- miso_client/api/types/logs_types.py +71 -0
- miso_client/api/types/permissions_types.py +31 -0
- miso_client/api/types/roles_types.py +31 -0
- miso_client/errors.py +30 -4
- miso_client/models/__init__.py +4 -0
- miso_client/models/config.py +275 -72
- miso_client/models/error_response.py +39 -0
- miso_client/models/filter.py +255 -0
- miso_client/models/pagination.py +44 -0
- miso_client/models/sort.py +25 -0
- miso_client/services/__init__.py +6 -5
- miso_client/services/auth.py +496 -87
- miso_client/services/cache.py +42 -41
- miso_client/services/encryption.py +18 -17
- miso_client/services/logger.py +467 -328
- miso_client/services/logger_chain.py +288 -0
- miso_client/services/permission.py +130 -67
- miso_client/services/redis.py +28 -23
- miso_client/services/role.py +145 -62
- miso_client/utils/__init__.py +3 -3
- miso_client/utils/audit_log_queue.py +222 -0
- miso_client/utils/auth_strategy.py +88 -0
- miso_client/utils/auth_utils.py +65 -0
- miso_client/utils/circuit_breaker.py +125 -0
- miso_client/utils/client_token_manager.py +244 -0
- miso_client/utils/config_loader.py +88 -17
- miso_client/utils/controller_url_resolver.py +80 -0
- miso_client/utils/data_masker.py +104 -33
- miso_client/utils/environment_token.py +126 -0
- miso_client/utils/error_utils.py +216 -0
- miso_client/utils/fastapi_endpoints.py +166 -0
- miso_client/utils/filter.py +364 -0
- miso_client/utils/filter_applier.py +143 -0
- miso_client/utils/filter_parser.py +110 -0
- miso_client/utils/flask_endpoints.py +169 -0
- miso_client/utils/http_client.py +494 -262
- miso_client/utils/http_client_logging.py +352 -0
- miso_client/utils/http_client_logging_helpers.py +197 -0
- miso_client/utils/http_client_query_helpers.py +138 -0
- miso_client/utils/http_error_handler.py +92 -0
- miso_client/utils/http_log_formatter.py +115 -0
- miso_client/utils/http_log_masker.py +203 -0
- miso_client/utils/internal_http_client.py +435 -0
- miso_client/utils/jwt_tools.py +125 -16
- miso_client/utils/logger_helpers.py +206 -0
- miso_client/utils/logging_helpers.py +70 -0
- miso_client/utils/origin_validator.py +128 -0
- miso_client/utils/pagination.py +275 -0
- miso_client/utils/request_context.py +285 -0
- miso_client/utils/sensitive_fields_loader.py +116 -0
- miso_client/utils/sort.py +116 -0
- miso_client/utils/token_utils.py +114 -0
- miso_client/utils/url_validator.py +66 -0
- miso_client/utils/user_token_refresh.py +245 -0
- miso_client-3.7.2.dist-info/METADATA +1021 -0
- miso_client-3.7.2.dist-info/RECORD +68 -0
- miso_client-0.1.0.dist-info/METADATA +0 -551
- miso_client-0.1.0.dist-info/RECORD +0 -23
- {miso_client-0.1.0.dist-info → miso_client-3.7.2.dist-info}/WHEEL +0 -0
- {miso_client-0.1.0.dist-info → miso_client-3.7.2.dist-info}/licenses/LICENSE +0 -0
- {miso_client-0.1.0.dist-info → miso_client-3.7.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API type definitions.
|
|
3
|
+
|
|
4
|
+
Exports all request and response types for the API layer.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from .auth_types import (
|
|
8
|
+
DeviceCodeRequest,
|
|
9
|
+
DeviceCodeResponse,
|
|
10
|
+
DeviceCodeResponseWrapper,
|
|
11
|
+
DeviceCodeTokenPollRequest,
|
|
12
|
+
DeviceCodeTokenPollResponse,
|
|
13
|
+
DeviceCodeTokenResponse,
|
|
14
|
+
GetUserResponse,
|
|
15
|
+
GetUserResponseData,
|
|
16
|
+
LoginResponse,
|
|
17
|
+
LoginResponseData,
|
|
18
|
+
LogoutResponse,
|
|
19
|
+
RefreshTokenRequest,
|
|
20
|
+
RefreshTokenResponse,
|
|
21
|
+
ValidateTokenRequest,
|
|
22
|
+
ValidateTokenResponse,
|
|
23
|
+
ValidateTokenResponseData,
|
|
24
|
+
)
|
|
25
|
+
from .logs_types import (
|
|
26
|
+
AuditLogData,
|
|
27
|
+
BatchLogError,
|
|
28
|
+
BatchLogRequest,
|
|
29
|
+
BatchLogResponse,
|
|
30
|
+
GeneralLogData,
|
|
31
|
+
LogRequest,
|
|
32
|
+
LogResponse,
|
|
33
|
+
)
|
|
34
|
+
from .permissions_types import GetPermissionsResponse as PermissionsGetPermissionsResponse
|
|
35
|
+
from .permissions_types import GetPermissionsResponseData as PermissionsGetPermissionsResponseData
|
|
36
|
+
from .permissions_types import RefreshPermissionsResponse as PermissionsRefreshPermissionsResponse
|
|
37
|
+
from .roles_types import GetRolesResponse as RolesGetRolesResponse
|
|
38
|
+
from .roles_types import GetRolesResponseData as RolesGetRolesResponseData
|
|
39
|
+
from .roles_types import RefreshRolesResponse as RolesRefreshRolesResponse
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
# Auth types
|
|
43
|
+
"LoginResponse",
|
|
44
|
+
"LoginResponseData",
|
|
45
|
+
"ValidateTokenRequest",
|
|
46
|
+
"ValidateTokenResponse",
|
|
47
|
+
"ValidateTokenResponseData",
|
|
48
|
+
"GetUserResponse",
|
|
49
|
+
"GetUserResponseData",
|
|
50
|
+
"LogoutResponse",
|
|
51
|
+
"RefreshTokenRequest",
|
|
52
|
+
"RefreshTokenResponse",
|
|
53
|
+
"DeviceCodeTokenResponse",
|
|
54
|
+
"DeviceCodeRequest",
|
|
55
|
+
"DeviceCodeResponse",
|
|
56
|
+
"DeviceCodeResponseWrapper",
|
|
57
|
+
"DeviceCodeTokenPollRequest",
|
|
58
|
+
"DeviceCodeTokenPollResponse",
|
|
59
|
+
# Roles types
|
|
60
|
+
"RolesGetRolesResponse",
|
|
61
|
+
"RolesGetRolesResponseData",
|
|
62
|
+
"RolesRefreshRolesResponse",
|
|
63
|
+
# Permissions types
|
|
64
|
+
"PermissionsGetPermissionsResponse",
|
|
65
|
+
"PermissionsGetPermissionsResponseData",
|
|
66
|
+
"PermissionsRefreshPermissionsResponse",
|
|
67
|
+
# Logs types
|
|
68
|
+
"GeneralLogData",
|
|
69
|
+
"AuditLogData",
|
|
70
|
+
"LogRequest",
|
|
71
|
+
"BatchLogRequest",
|
|
72
|
+
"LogResponse",
|
|
73
|
+
"BatchLogResponse",
|
|
74
|
+
"BatchLogError",
|
|
75
|
+
]
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Auth API request and response types.
|
|
3
|
+
|
|
4
|
+
All types follow OpenAPI specification with camelCase field names.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from ...models.config import UserInfo
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class LoginResponse(BaseModel):
|
|
15
|
+
"""Login response with login URL."""
|
|
16
|
+
|
|
17
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
18
|
+
data: "LoginResponseData" = Field(..., description="Login data")
|
|
19
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class LoginResponseData(BaseModel):
|
|
23
|
+
"""Login response data."""
|
|
24
|
+
|
|
25
|
+
loginUrl: str = Field(..., description="Login URL for OAuth2 flow")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ValidateTokenRequest(BaseModel):
|
|
29
|
+
"""Token validation request."""
|
|
30
|
+
|
|
31
|
+
token: str = Field(..., description="JWT token to validate")
|
|
32
|
+
environment: Optional[str] = Field(default=None, description="Optional environment key")
|
|
33
|
+
application: Optional[str] = Field(default=None, description="Optional application key")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ValidateTokenResponse(BaseModel):
|
|
37
|
+
"""Token validation response."""
|
|
38
|
+
|
|
39
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
40
|
+
data: "ValidateTokenResponseData" = Field(..., description="Validation data")
|
|
41
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ValidateTokenResponseData(BaseModel):
|
|
45
|
+
"""Token validation response data."""
|
|
46
|
+
|
|
47
|
+
authenticated: bool = Field(..., description="Whether token is authenticated")
|
|
48
|
+
user: Optional[UserInfo] = Field(default=None, description="User information if authenticated")
|
|
49
|
+
expiresAt: Optional[str] = Field(default=None, description="Token expiration timestamp")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class GetUserResponse(BaseModel):
|
|
53
|
+
"""Get user response."""
|
|
54
|
+
|
|
55
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
56
|
+
data: "GetUserResponseData" = Field(..., description="User data")
|
|
57
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class GetUserResponseData(BaseModel):
|
|
61
|
+
"""Get user response data."""
|
|
62
|
+
|
|
63
|
+
user: UserInfo = Field(..., description="User information")
|
|
64
|
+
authenticated: bool = Field(..., description="Whether user is authenticated")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class LogoutResponse(BaseModel):
|
|
68
|
+
"""Logout response."""
|
|
69
|
+
|
|
70
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
71
|
+
message: str = Field(..., description="Logout message")
|
|
72
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
class RefreshTokenRequest(BaseModel):
|
|
76
|
+
"""Refresh token request."""
|
|
77
|
+
|
|
78
|
+
refreshToken: str = Field(..., description="Refresh token")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class DeviceCodeTokenResponse(BaseModel):
|
|
82
|
+
"""Device code token response."""
|
|
83
|
+
|
|
84
|
+
accessToken: str = Field(..., description="JWT access token")
|
|
85
|
+
refreshToken: Optional[str] = Field(default=None, description="Refresh token")
|
|
86
|
+
expiresIn: int = Field(..., description="Token expiration in seconds")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
class RefreshTokenResponse(BaseModel):
|
|
90
|
+
"""Refresh token response."""
|
|
91
|
+
|
|
92
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
93
|
+
data: DeviceCodeTokenResponse = Field(..., description="Token data")
|
|
94
|
+
message: Optional[str] = Field(default=None, description="Optional message")
|
|
95
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class DeviceCodeRequest(BaseModel):
|
|
99
|
+
"""Device code initiation request."""
|
|
100
|
+
|
|
101
|
+
environment: Optional[str] = Field(default=None, description="Environment key")
|
|
102
|
+
scope: Optional[str] = Field(default=None, description="OAuth2 scope string")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class DeviceCodeResponse(BaseModel):
|
|
106
|
+
"""Device code response."""
|
|
107
|
+
|
|
108
|
+
deviceCode: str = Field(..., description="Device code for polling")
|
|
109
|
+
userCode: str = Field(..., description="User code to enter")
|
|
110
|
+
verificationUri: str = Field(..., description="Verification URI")
|
|
111
|
+
verificationUriComplete: Optional[str] = Field(
|
|
112
|
+
default=None, description="Complete URI with user code"
|
|
113
|
+
)
|
|
114
|
+
expiresIn: int = Field(..., description="Device code expiration in seconds")
|
|
115
|
+
interval: int = Field(..., description="Polling interval in seconds")
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class DeviceCodeResponseWrapper(BaseModel):
|
|
119
|
+
"""Device code response wrapper."""
|
|
120
|
+
|
|
121
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
122
|
+
data: DeviceCodeResponse = Field(..., description="Device code data")
|
|
123
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class DeviceCodeTokenPollRequest(BaseModel):
|
|
127
|
+
"""Device code token poll request."""
|
|
128
|
+
|
|
129
|
+
deviceCode: str = Field(..., description="Device code from initiation")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class DeviceCodeTokenPollResponse(BaseModel):
|
|
133
|
+
"""Device code token poll response."""
|
|
134
|
+
|
|
135
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
136
|
+
data: Optional[DeviceCodeTokenResponse] = Field(default=None, description="Token data if ready")
|
|
137
|
+
error: Optional[str] = Field(default=None, description="Error code if pending")
|
|
138
|
+
errorDescription: Optional[str] = Field(default=None, description="Error description")
|
|
139
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class GetRolesResponse(BaseModel):
|
|
143
|
+
"""Get roles response."""
|
|
144
|
+
|
|
145
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
146
|
+
data: "GetRolesResponseData" = Field(..., description="Roles data")
|
|
147
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class GetRolesResponseData(BaseModel):
|
|
151
|
+
"""Get roles response data."""
|
|
152
|
+
|
|
153
|
+
roles: List[str] = Field(..., description="List of user roles")
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class RefreshRolesResponse(BaseModel):
|
|
157
|
+
"""Refresh roles response."""
|
|
158
|
+
|
|
159
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
160
|
+
data: GetRolesResponseData = Field(..., description="Roles data")
|
|
161
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class GetPermissionsResponse(BaseModel):
|
|
165
|
+
"""Get permissions response."""
|
|
166
|
+
|
|
167
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
168
|
+
data: "GetPermissionsResponseData" = Field(..., description="Permissions data")
|
|
169
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class GetPermissionsResponseData(BaseModel):
|
|
173
|
+
"""Get permissions response data."""
|
|
174
|
+
|
|
175
|
+
permissions: List[str] = Field(..., description="List of user permissions")
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class RefreshPermissionsResponse(BaseModel):
|
|
179
|
+
"""Refresh permissions response."""
|
|
180
|
+
|
|
181
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
182
|
+
data: GetPermissionsResponseData = Field(..., description="Permissions data")
|
|
183
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Logs API request and response types.
|
|
3
|
+
|
|
4
|
+
All types follow OpenAPI specification with camelCase field names.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict, List, Literal, Optional, Union
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
from ...models.config import LogEntry
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class GeneralLogData(BaseModel):
|
|
15
|
+
"""General log data structure."""
|
|
16
|
+
|
|
17
|
+
level: Literal["error", "warn", "info", "debug"] = Field(..., description="Log level")
|
|
18
|
+
message: str = Field(..., description="Log message")
|
|
19
|
+
context: Optional[Dict[str, Any]] = Field(default=None, description="Additional context")
|
|
20
|
+
correlationId: Optional[str] = Field(default=None, description="Correlation ID")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class AuditLogData(BaseModel):
|
|
24
|
+
"""Audit log data structure."""
|
|
25
|
+
|
|
26
|
+
entityType: str = Field(..., description="Entity type")
|
|
27
|
+
entityId: str = Field(..., description="Entity ID")
|
|
28
|
+
action: str = Field(..., description="Action performed")
|
|
29
|
+
oldValues: Optional[Dict[str, Any]] = Field(default=None, description="Previous values")
|
|
30
|
+
newValues: Optional[Dict[str, Any]] = Field(default=None, description="New values")
|
|
31
|
+
correlationId: Optional[str] = Field(default=None, description="Correlation ID")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class LogRequest(BaseModel):
|
|
35
|
+
"""Log request with type and data."""
|
|
36
|
+
|
|
37
|
+
type: Literal["error", "general", "audit"] = Field(..., description="Log entry type")
|
|
38
|
+
data: Union[GeneralLogData, AuditLogData] = Field(..., description="Log data")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class BatchLogRequest(BaseModel):
|
|
42
|
+
"""Batch log request."""
|
|
43
|
+
|
|
44
|
+
logs: List[LogEntry] = Field(..., description="List of log entries")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class LogResponse(BaseModel):
|
|
48
|
+
"""Log response."""
|
|
49
|
+
|
|
50
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
51
|
+
message: str = Field(..., description="Response message")
|
|
52
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class BatchLogError(BaseModel):
|
|
56
|
+
"""Batch log error entry."""
|
|
57
|
+
|
|
58
|
+
index: int = Field(..., description="Index of failed log entry")
|
|
59
|
+
error: str = Field(..., description="Error message")
|
|
60
|
+
log: Dict[str, Any] = Field(..., description="Failed log entry")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class BatchLogResponse(BaseModel):
|
|
64
|
+
"""Batch log response."""
|
|
65
|
+
|
|
66
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
67
|
+
message: str = Field(..., description="Response message")
|
|
68
|
+
processed: int = Field(..., description="Number of logs successfully processed")
|
|
69
|
+
failed: int = Field(..., description="Number of logs that failed")
|
|
70
|
+
errors: Optional[List[BatchLogError]] = Field(default=None, description="Error details")
|
|
71
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Permissions API request and response types.
|
|
3
|
+
|
|
4
|
+
All types follow OpenAPI specification with camelCase field names.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class GetPermissionsResponse(BaseModel):
|
|
13
|
+
"""Get permissions response."""
|
|
14
|
+
|
|
15
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
16
|
+
data: "GetPermissionsResponseData" = Field(..., description="Permissions data")
|
|
17
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class GetPermissionsResponseData(BaseModel):
|
|
21
|
+
"""Get permissions response data."""
|
|
22
|
+
|
|
23
|
+
permissions: List[str] = Field(..., description="List of user permissions")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class RefreshPermissionsResponse(BaseModel):
|
|
27
|
+
"""Refresh permissions response."""
|
|
28
|
+
|
|
29
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
30
|
+
data: GetPermissionsResponseData = Field(..., description="Permissions data")
|
|
31
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Roles API request and response types.
|
|
3
|
+
|
|
4
|
+
All types follow OpenAPI specification with camelCase field names.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import List
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class GetRolesResponse(BaseModel):
|
|
13
|
+
"""Get roles response."""
|
|
14
|
+
|
|
15
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
16
|
+
data: "GetRolesResponseData" = Field(..., description="Roles data")
|
|
17
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class GetRolesResponseData(BaseModel):
|
|
21
|
+
"""Get roles response data."""
|
|
22
|
+
|
|
23
|
+
roles: List[str] = Field(..., description="List of user roles")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class RefreshRolesResponse(BaseModel):
|
|
27
|
+
"""Refresh roles response."""
|
|
28
|
+
|
|
29
|
+
success: bool = Field(..., description="Whether request was successful")
|
|
30
|
+
data: GetRolesResponseData = Field(..., description="Roles data")
|
|
31
|
+
timestamp: str = Field(..., description="Response timestamp (ISO 8601)")
|
miso_client/errors.py
CHANGED
|
@@ -4,41 +4,67 @@ SDK exceptions and error handling.
|
|
|
4
4
|
This module defines custom exceptions for the MisoClient SDK.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ..models.error_response import ErrorResponse
|
|
11
|
+
|
|
7
12
|
|
|
8
13
|
class MisoClientError(Exception):
|
|
9
14
|
"""Base exception for MisoClient SDK errors."""
|
|
10
|
-
|
|
11
|
-
def __init__(
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
message: str,
|
|
19
|
+
status_code: int | None = None,
|
|
20
|
+
error_body: dict | None = None,
|
|
21
|
+
error_response: "ErrorResponse | None" = None,
|
|
22
|
+
):
|
|
12
23
|
"""
|
|
13
24
|
Initialize MisoClient error.
|
|
14
|
-
|
|
25
|
+
|
|
15
26
|
Args:
|
|
16
27
|
message: Error message
|
|
17
28
|
status_code: HTTP status code if applicable
|
|
18
29
|
error_body: Sanitized error response body (secrets masked)
|
|
30
|
+
error_response: Structured error response object (RFC 7807-style)
|
|
19
31
|
"""
|
|
20
32
|
super().__init__(message)
|
|
21
33
|
self.message = message
|
|
22
34
|
self.status_code = status_code
|
|
23
35
|
self.error_body = error_body if error_body is not None else None
|
|
36
|
+
self.error_response = error_response
|
|
37
|
+
|
|
38
|
+
# Enhance message with structured error information if available
|
|
39
|
+
if error_response and error_response.errors:
|
|
40
|
+
if len(error_response.errors) == 1:
|
|
41
|
+
self.message = error_response.errors[0]
|
|
42
|
+
else:
|
|
43
|
+
self.message = f"{error_response.title}: {'; '.join(error_response.errors)}"
|
|
44
|
+
# Override status_code from structured response if available
|
|
45
|
+
if error_response.statusCode:
|
|
46
|
+
self.status_code = error_response.statusCode
|
|
24
47
|
|
|
25
48
|
|
|
26
49
|
class AuthenticationError(MisoClientError):
|
|
27
50
|
"""Raised when authentication fails."""
|
|
51
|
+
|
|
28
52
|
pass
|
|
29
53
|
|
|
30
54
|
|
|
31
55
|
class AuthorizationError(MisoClientError):
|
|
32
56
|
"""Raised when authorization check fails."""
|
|
57
|
+
|
|
33
58
|
pass
|
|
34
59
|
|
|
35
60
|
|
|
36
61
|
class ConnectionError(MisoClientError):
|
|
37
62
|
"""Raised when connection to controller or Redis fails."""
|
|
63
|
+
|
|
38
64
|
pass
|
|
39
65
|
|
|
40
66
|
|
|
41
67
|
class ConfigurationError(MisoClientError):
|
|
42
68
|
"""Raised when configuration is invalid."""
|
|
43
|
-
pass
|
|
44
69
|
|
|
70
|
+
pass
|