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
miso_client/models/config.py
CHANGED
|
@@ -5,13 +5,17 @@ This module contains Pydantic models that define the configuration structure
|
|
|
5
5
|
and data types used throughout the MisoClient SDK.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import
|
|
8
|
+
from typing import Any, Dict, List, Literal, Optional, Union
|
|
9
|
+
|
|
9
10
|
from pydantic import BaseModel, Field
|
|
10
11
|
|
|
12
|
+
# Authentication method types
|
|
13
|
+
AuthMethod = Literal["bearer", "client-token", "client-credentials", "api-key"]
|
|
14
|
+
|
|
11
15
|
|
|
12
16
|
class RedisConfig(BaseModel):
|
|
13
17
|
"""Redis connection configuration."""
|
|
14
|
-
|
|
18
|
+
|
|
15
19
|
host: str = Field(..., description="Redis host")
|
|
16
20
|
port: int = Field(default=6379, description="Redis port")
|
|
17
21
|
password: Optional[str] = Field(default=None, description="Redis password")
|
|
@@ -19,40 +23,119 @@ class RedisConfig(BaseModel):
|
|
|
19
23
|
key_prefix: str = Field(default="miso:", description="Key prefix for Redis keys")
|
|
20
24
|
|
|
21
25
|
|
|
26
|
+
class AuditConfig(BaseModel):
|
|
27
|
+
"""Audit logging configuration for HTTP client."""
|
|
28
|
+
|
|
29
|
+
enabled: Optional[bool] = Field(
|
|
30
|
+
default=True, description="Enable/disable audit logging (default: true)"
|
|
31
|
+
)
|
|
32
|
+
level: Optional[Literal["minimal", "standard", "detailed", "full"]] = Field(
|
|
33
|
+
default="detailed", description="Audit detail level (default: 'detailed')"
|
|
34
|
+
)
|
|
35
|
+
maxResponseSize: Optional[int] = Field(
|
|
36
|
+
default=10000, description="Truncate responses larger than this (default: 10000 bytes)"
|
|
37
|
+
)
|
|
38
|
+
maxMaskingSize: Optional[int] = Field(
|
|
39
|
+
default=50000,
|
|
40
|
+
description="Skip masking for objects larger than this (default: 50000 bytes)",
|
|
41
|
+
)
|
|
42
|
+
batchSize: Optional[int] = Field(
|
|
43
|
+
default=10, description="Batch size for queued logs (default: 10)"
|
|
44
|
+
)
|
|
45
|
+
batchInterval: Optional[int] = Field(
|
|
46
|
+
default=100, description="Flush interval in milliseconds (default: 100)"
|
|
47
|
+
)
|
|
48
|
+
skipEndpoints: Optional[List[str]] = Field(
|
|
49
|
+
default=None, description="Array of endpoint patterns to exclude from audit logging"
|
|
50
|
+
)
|
|
51
|
+
circuitBreaker: Optional["CircuitBreakerConfig"] = Field(
|
|
52
|
+
default=None, description="Circuit breaker configuration for HTTP logging"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class AuthStrategy(BaseModel):
|
|
57
|
+
"""Authentication strategy configuration.
|
|
58
|
+
|
|
59
|
+
Defines which authentication methods to try and in what priority order.
|
|
60
|
+
Methods are tried in the order specified until one succeeds.
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
methods: List[AuthMethod] = Field(
|
|
64
|
+
default=["bearer", "client-token"],
|
|
65
|
+
description="Array of auth methods in priority order (default: ['bearer', 'client-token'])",
|
|
66
|
+
)
|
|
67
|
+
bearerToken: Optional[str] = Field(
|
|
68
|
+
default=None, description="Optional bearer token for bearer auth"
|
|
69
|
+
)
|
|
70
|
+
apiKey: Optional[str] = Field(default=None, description="Optional API key for api-key auth")
|
|
71
|
+
|
|
72
|
+
|
|
22
73
|
class MisoClientConfig(BaseModel):
|
|
23
74
|
"""Main MisoClient configuration.
|
|
24
|
-
|
|
75
|
+
|
|
25
76
|
Required fields:
|
|
26
77
|
- controller_url: Miso Controller base URL
|
|
27
78
|
- client_id: Client identifier for authentication
|
|
28
79
|
- client_secret: Client secret for authentication
|
|
29
|
-
|
|
80
|
+
|
|
30
81
|
Optional fields:
|
|
31
82
|
- redis: Redis configuration for caching
|
|
32
83
|
- log_level: Logging level (debug, info, warn, error)
|
|
33
84
|
- cache: Cache TTL settings for roles and permissions
|
|
85
|
+
- api_key: API key for testing (bypasses OAuth2 authentication)
|
|
34
86
|
"""
|
|
35
|
-
|
|
87
|
+
|
|
36
88
|
controller_url: str = Field(..., description="Miso Controller base URL")
|
|
37
89
|
client_id: str = Field(..., description="Client identifier for authentication")
|
|
38
90
|
client_secret: str = Field(..., description="Client secret for authentication")
|
|
39
91
|
redis: Optional[RedisConfig] = Field(default=None, description="Optional Redis configuration")
|
|
40
92
|
log_level: Literal["debug", "info", "warn", "error"] = Field(
|
|
41
|
-
default="info",
|
|
42
|
-
description="Log level"
|
|
93
|
+
default="info", description="Log level"
|
|
43
94
|
)
|
|
44
95
|
cache: Optional[Dict[str, int]] = Field(
|
|
45
96
|
default=None,
|
|
46
|
-
description="Cache TTL settings: permission_ttl, role_ttl (default: 900 seconds)"
|
|
97
|
+
description="Cache TTL settings: permission_ttl, role_ttl (default: 900 seconds)",
|
|
98
|
+
)
|
|
99
|
+
api_key: Optional[str] = Field(
|
|
100
|
+
default=None,
|
|
101
|
+
description="API key for testing - when set, bearer tokens matching this key bypass OAuth2 validation",
|
|
47
102
|
)
|
|
48
|
-
|
|
103
|
+
sensitive_fields_config: Optional[str] = Field(
|
|
104
|
+
default=None, description="Path to sensitive fields configuration JSON file"
|
|
105
|
+
)
|
|
106
|
+
audit: Optional["AuditConfig"] = Field(default=None, description="Audit logging configuration")
|
|
107
|
+
emit_events: Optional[bool] = Field(
|
|
108
|
+
default=False,
|
|
109
|
+
description="Emit log events instead of sending via HTTP/Redis (default: false)",
|
|
110
|
+
)
|
|
111
|
+
authStrategy: Optional["AuthStrategy"] = Field(
|
|
112
|
+
default=None,
|
|
113
|
+
description="Authentication strategy configuration (default: ['bearer', 'client-token'])",
|
|
114
|
+
)
|
|
115
|
+
clientTokenUri: Optional[str] = Field(
|
|
116
|
+
default=None,
|
|
117
|
+
description="URI for client token endpoint (default: '/api/v1/auth/token')",
|
|
118
|
+
)
|
|
119
|
+
allowedOrigins: Optional[List[str]] = Field(
|
|
120
|
+
default=None,
|
|
121
|
+
description="Array of allowed origins for CORS validation",
|
|
122
|
+
)
|
|
123
|
+
controllerPublicUrl: Optional[str] = Field(
|
|
124
|
+
default=None,
|
|
125
|
+
description="Public controller URL for browser environments (accessible from internet)",
|
|
126
|
+
)
|
|
127
|
+
controllerPrivateUrl: Optional[str] = Field(
|
|
128
|
+
default=None,
|
|
129
|
+
description="Private controller URL for server environments (internal network access)",
|
|
130
|
+
)
|
|
131
|
+
|
|
49
132
|
@property
|
|
50
133
|
def role_ttl(self) -> int:
|
|
51
134
|
"""Get role cache TTL in seconds."""
|
|
52
135
|
if self.cache and "role_ttl" in self.cache:
|
|
53
136
|
return self.cache["role_ttl"]
|
|
54
137
|
return self.cache.get("roleTTL", 900) if self.cache else 900 # 15 minutes default
|
|
55
|
-
|
|
138
|
+
|
|
56
139
|
@property
|
|
57
140
|
def permission_ttl(self) -> int:
|
|
58
141
|
"""Get permission cache TTL in seconds."""
|
|
@@ -60,24 +143,45 @@ class MisoClientConfig(BaseModel):
|
|
|
60
143
|
return self.cache["permission_ttl"]
|
|
61
144
|
return self.cache.get("permissionTTL", 900) if self.cache else 900 # 15 minutes default
|
|
62
145
|
|
|
146
|
+
@property
|
|
147
|
+
def validation_ttl(self) -> int:
|
|
148
|
+
"""Get token validation cache TTL in seconds."""
|
|
149
|
+
if self.cache and "validation_ttl" in self.cache:
|
|
150
|
+
return self.cache["validation_ttl"]
|
|
151
|
+
return self.cache.get("validationTTL", 120) if self.cache else 120 # 2 minutes default
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class ForeignKeyReference(BaseModel):
|
|
155
|
+
"""Foreign key reference object for API responses.
|
|
156
|
+
|
|
157
|
+
Provides essential context about referenced entities without requiring additional lookups.
|
|
158
|
+
Used consistently across all foreign keys in API response models.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
id: str = Field(..., description="Entity ID (environment-specific identifier)")
|
|
162
|
+
key: str = Field(..., description="Entity key (environment-agnostic identifier)")
|
|
163
|
+
name: str = Field(
|
|
164
|
+
..., description="Entity name (displayName, name, or firstName/lastName for User)"
|
|
165
|
+
)
|
|
166
|
+
type: str = Field(
|
|
167
|
+
..., description="Entity type (e.g., 'Environment', 'User', 'Application', 'Controller')"
|
|
168
|
+
)
|
|
169
|
+
|
|
63
170
|
|
|
64
171
|
class UserInfo(BaseModel):
|
|
65
172
|
"""User information from token validation."""
|
|
66
|
-
|
|
173
|
+
|
|
67
174
|
id: str = Field(..., description="User ID")
|
|
68
175
|
username: str = Field(..., description="Username")
|
|
69
176
|
email: Optional[str] = Field(default=None, description="User email")
|
|
70
|
-
firstName: Optional[str] = Field(default=None,
|
|
71
|
-
lastName: Optional[str] = Field(default=None,
|
|
177
|
+
firstName: Optional[str] = Field(default=None, description="First name")
|
|
178
|
+
lastName: Optional[str] = Field(default=None, description="Last name")
|
|
72
179
|
roles: Optional[List[str]] = Field(default=None, description="User roles")
|
|
73
|
-
|
|
74
|
-
class Config:
|
|
75
|
-
populate_by_name = True # Allow both snake_case and camelCase
|
|
76
180
|
|
|
77
181
|
|
|
78
182
|
class AuthResult(BaseModel):
|
|
79
183
|
"""Authentication result."""
|
|
80
|
-
|
|
184
|
+
|
|
81
185
|
authenticated: bool = Field(..., description="Whether authentication was successful")
|
|
82
186
|
user: Optional[UserInfo] = Field(default=None, description="User information if authenticated")
|
|
83
187
|
error: Optional[str] = Field(default=None, description="Error message if authentication failed")
|
|
@@ -85,90 +189,189 @@ class AuthResult(BaseModel):
|
|
|
85
189
|
|
|
86
190
|
class LogEntry(BaseModel):
|
|
87
191
|
"""Log entry structure."""
|
|
88
|
-
|
|
192
|
+
|
|
89
193
|
timestamp: str = Field(..., description="ISO timestamp")
|
|
90
194
|
level: Literal["error", "audit", "info", "debug"] = Field(..., description="Log level")
|
|
91
195
|
environment: str = Field(..., description="Environment name (extracted by backend)")
|
|
92
196
|
application: str = Field(..., description="Application identifier (clientId)")
|
|
93
|
-
applicationId: Optional[
|
|
94
|
-
|
|
197
|
+
applicationId: Optional["ForeignKeyReference"] = Field(
|
|
198
|
+
default=None, description="Application reference (foreign key object)"
|
|
199
|
+
)
|
|
200
|
+
userId: Optional["ForeignKeyReference"] = Field(
|
|
201
|
+
default=None, description="User reference (foreign key object)"
|
|
202
|
+
)
|
|
95
203
|
message: str = Field(..., description="Log message")
|
|
96
204
|
context: Optional[Dict[str, Any]] = Field(default=None, description="Additional context")
|
|
97
|
-
correlationId: Optional[str] = Field(default=None,
|
|
98
|
-
requestId: Optional[str] = Field(default=None,
|
|
99
|
-
sessionId: Optional[str] = Field(default=None,
|
|
100
|
-
stackTrace: Optional[str] = Field(default=None,
|
|
101
|
-
ipAddress: Optional[str] = Field(default=None,
|
|
102
|
-
userAgent: Optional[str] = Field(default=None,
|
|
205
|
+
correlationId: Optional[str] = Field(default=None, description="Correlation ID for tracing")
|
|
206
|
+
requestId: Optional[str] = Field(default=None, description="Request ID")
|
|
207
|
+
sessionId: Optional[str] = Field(default=None, description="Session ID")
|
|
208
|
+
stackTrace: Optional[str] = Field(default=None, description="Stack trace for errors")
|
|
209
|
+
ipAddress: Optional[str] = Field(default=None, description="IP address")
|
|
210
|
+
userAgent: Optional[str] = Field(default=None, description="User agent")
|
|
103
211
|
hostname: Optional[str] = Field(default=None, description="Hostname")
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
212
|
+
|
|
213
|
+
# Indexed context fields (top-level for fast queries)
|
|
214
|
+
sourceKey: Optional[str] = Field(default=None, description="ExternalDataSource.key")
|
|
215
|
+
sourceDisplayName: Optional[str] = Field(default=None, description="Human-readable source name")
|
|
216
|
+
externalSystemKey: Optional[str] = Field(default=None, description="ExternalSystem.key")
|
|
217
|
+
externalSystemDisplayName: Optional[str] = Field(
|
|
218
|
+
default=None, description="Human-readable system name"
|
|
219
|
+
)
|
|
220
|
+
recordKey: Optional[str] = Field(default=None, description="ExternalRecord.key")
|
|
221
|
+
recordDisplayName: Optional[str] = Field(
|
|
222
|
+
default=None, description="Human-readable record identifier"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Credential context (for performance analysis)
|
|
226
|
+
credentialId: Optional[str] = Field(default=None, description="Credential ID")
|
|
227
|
+
credentialType: Optional[str] = Field(
|
|
228
|
+
default=None, description="Credential type (apiKey, oauth2, etc.)"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Request/Response metrics
|
|
232
|
+
requestSize: Optional[int] = Field(default=None, description="Request body size in bytes")
|
|
233
|
+
responseSize: Optional[int] = Field(default=None, description="Response body size in bytes")
|
|
234
|
+
durationMs: Optional[int] = Field(default=None, description="Duration in milliseconds")
|
|
235
|
+
durationSeconds: Optional[float] = Field(default=None, description="Duration in seconds")
|
|
236
|
+
timeout: Optional[float] = Field(default=None, description="Request timeout in seconds")
|
|
237
|
+
retryCount: Optional[int] = Field(default=None, description="Number of retry attempts")
|
|
238
|
+
|
|
239
|
+
# Error classification
|
|
240
|
+
errorCategory: Optional[str] = Field(
|
|
241
|
+
default=None, description="Error category: network, timeout, auth, validation, server"
|
|
242
|
+
)
|
|
243
|
+
httpStatusCategory: Optional[str] = Field(
|
|
244
|
+
default=None, description="HTTP status category: 2xx, 4xx, 5xx"
|
|
245
|
+
)
|
|
107
246
|
|
|
108
247
|
|
|
109
248
|
class RoleResult(BaseModel):
|
|
110
249
|
"""Role query result."""
|
|
111
|
-
|
|
112
|
-
userId: str = Field(...,
|
|
250
|
+
|
|
251
|
+
userId: str = Field(..., description="User ID")
|
|
113
252
|
roles: List[str] = Field(..., description="List of user roles")
|
|
114
253
|
environment: str = Field(..., description="Environment name")
|
|
115
254
|
application: str = Field(..., description="Application name")
|
|
116
|
-
|
|
117
|
-
class Config:
|
|
118
|
-
populate_by_name = True
|
|
119
255
|
|
|
120
256
|
|
|
121
257
|
class PermissionResult(BaseModel):
|
|
122
258
|
"""Permission query result."""
|
|
123
|
-
|
|
124
|
-
userId: str = Field(...,
|
|
259
|
+
|
|
260
|
+
userId: str = Field(..., description="User ID")
|
|
125
261
|
permissions: List[str] = Field(..., description="List of user permissions")
|
|
126
262
|
environment: str = Field(..., description="Environment name")
|
|
127
263
|
application: str = Field(..., description="Application name")
|
|
128
|
-
|
|
129
|
-
class Config:
|
|
130
|
-
populate_by_name = True
|
|
131
264
|
|
|
132
265
|
|
|
133
266
|
class ClientTokenResponse(BaseModel):
|
|
134
267
|
"""Client token response."""
|
|
135
|
-
|
|
268
|
+
|
|
136
269
|
success: bool = Field(..., description="Whether token request was successful")
|
|
137
270
|
token: str = Field(..., description="Client token")
|
|
138
|
-
expiresIn: int = Field(...,
|
|
139
|
-
expiresAt: str = Field(...,
|
|
140
|
-
|
|
141
|
-
class Config:
|
|
142
|
-
populate_by_name = True
|
|
271
|
+
expiresIn: int = Field(..., description="Token expiration in seconds")
|
|
272
|
+
expiresAt: str = Field(..., description="Token expiration ISO timestamp")
|
|
143
273
|
|
|
144
274
|
|
|
145
|
-
class
|
|
146
|
-
"""
|
|
147
|
-
|
|
148
|
-
startTime: int = Field(..., alias="start_time", description="Start time in milliseconds")
|
|
149
|
-
endTime: Optional[int] = Field(default=None, alias="end_time", description="End time in milliseconds")
|
|
150
|
-
duration: Optional[int] = Field(default=None, description="Duration in milliseconds")
|
|
151
|
-
memoryUsage: Optional[Dict[str, int]] = Field(
|
|
152
|
-
default=None,
|
|
153
|
-
alias="memory_usage",
|
|
154
|
-
description="Memory usage metrics (rss, heapTotal, heapUsed, external, arrayBuffers)"
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
class Config:
|
|
158
|
-
populate_by_name = True
|
|
275
|
+
class ClientLoggingOptions(BaseModel):
|
|
276
|
+
"""Options for client logging.
|
|
159
277
|
|
|
278
|
+
Supports both string IDs (for backward compatibility) and ForeignKeyReference objects.
|
|
279
|
+
When string IDs are provided, they will be converted to ForeignKeyReference objects
|
|
280
|
+
in LogEntry if needed (requires additional context from API responses).
|
|
281
|
+
"""
|
|
160
282
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
283
|
+
applicationId: Optional[Union[str, "ForeignKeyReference"]] = Field(
|
|
284
|
+
default=None, description="Application ID (string) or Application reference (object)"
|
|
285
|
+
)
|
|
286
|
+
userId: Optional[Union[str, "ForeignKeyReference"]] = Field(
|
|
287
|
+
default=None, description="User ID (string) or User reference (object)"
|
|
288
|
+
)
|
|
289
|
+
correlationId: Optional[str] = Field(default=None, description="Correlation ID")
|
|
290
|
+
requestId: Optional[str] = Field(default=None, description="Request ID")
|
|
291
|
+
sessionId: Optional[str] = Field(default=None, description="Session ID")
|
|
169
292
|
token: Optional[str] = Field(default=None, description="JWT token for context extraction")
|
|
170
|
-
maskSensitiveData: Optional[bool] = Field(default=None,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
293
|
+
maskSensitiveData: Optional[bool] = Field(default=None, description="Enable data masking")
|
|
294
|
+
ipAddress: Optional[str] = Field(default=None, description="Client IP address")
|
|
295
|
+
userAgent: Optional[str] = Field(default=None, description="User agent string")
|
|
296
|
+
|
|
297
|
+
# Indexed context
|
|
298
|
+
sourceKey: Optional[str] = Field(default=None, description="ExternalDataSource.key")
|
|
299
|
+
sourceDisplayName: Optional[str] = Field(default=None, description="Human-readable source name")
|
|
300
|
+
externalSystemKey: Optional[str] = Field(default=None, description="ExternalSystem.key")
|
|
301
|
+
externalSystemDisplayName: Optional[str] = Field(
|
|
302
|
+
default=None, description="Human-readable system name"
|
|
303
|
+
)
|
|
304
|
+
recordKey: Optional[str] = Field(default=None, description="ExternalRecord.key")
|
|
305
|
+
recordDisplayName: Optional[str] = Field(
|
|
306
|
+
default=None, description="Human-readable record identifier"
|
|
307
|
+
)
|
|
308
|
+
|
|
309
|
+
# Credential context
|
|
310
|
+
credentialId: Optional[str] = Field(default=None, description="Credential ID")
|
|
311
|
+
credentialType: Optional[str] = Field(default=None, description="Credential type")
|
|
312
|
+
|
|
313
|
+
# Request metrics
|
|
314
|
+
requestSize: Optional[int] = Field(default=None, description="Request body size in bytes")
|
|
315
|
+
responseSize: Optional[int] = Field(default=None, description="Response body size in bytes")
|
|
316
|
+
durationMs: Optional[int] = Field(default=None, description="Duration in milliseconds")
|
|
317
|
+
durationSeconds: Optional[float] = Field(default=None, description="Duration in seconds")
|
|
318
|
+
timeout: Optional[float] = Field(default=None, description="Request timeout in seconds")
|
|
319
|
+
retryCount: Optional[int] = Field(default=None, description="Retry count")
|
|
320
|
+
|
|
321
|
+
# Error classification
|
|
322
|
+
errorCategory: Optional[str] = Field(default=None, description="Error category")
|
|
323
|
+
httpStatusCategory: Optional[str] = Field(default=None, description="HTTP status category")
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
class CircuitBreakerConfig(BaseModel):
|
|
327
|
+
"""Circuit breaker configuration for HTTP logging."""
|
|
328
|
+
|
|
329
|
+
failureThreshold: Optional[int] = Field(
|
|
330
|
+
default=3, description="Number of consecutive failures before opening circuit (default: 3)"
|
|
331
|
+
)
|
|
332
|
+
resetTimeout: Optional[int] = Field(
|
|
333
|
+
default=60, description="Seconds to wait before resetting circuit (default: 60)"
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
class DataClientConfigResponse(BaseModel):
|
|
338
|
+
"""DataClient configuration returned by client-token endpoint.
|
|
339
|
+
|
|
340
|
+
Contains all necessary configuration for browser-side DataClient initialization.
|
|
341
|
+
"""
|
|
342
|
+
|
|
343
|
+
baseUrl: str = Field(..., description="API base URL (derived from request)")
|
|
344
|
+
controllerUrl: str = Field(..., description="MISO Controller URL (from misoClient config)")
|
|
345
|
+
controllerPublicUrl: Optional[str] = Field(
|
|
346
|
+
default=None, description="Public controller URL for browser environments (if set)"
|
|
347
|
+
)
|
|
348
|
+
clientId: str = Field(..., description="Client ID (from misoClient config)")
|
|
349
|
+
clientTokenUri: str = Field(..., description="Client token endpoint URI")
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
class ClientTokenEndpointResponse(BaseModel):
|
|
353
|
+
"""Client token endpoint response.
|
|
354
|
+
|
|
355
|
+
Includes token, expiration, and DataClient configuration.
|
|
356
|
+
"""
|
|
357
|
+
|
|
358
|
+
token: str = Field(..., description="Client token string")
|
|
359
|
+
expiresIn: int = Field(..., description="Token expiration time in seconds")
|
|
360
|
+
config: Optional[DataClientConfigResponse] = Field(
|
|
361
|
+
default=None, description="DataClient configuration (included when includeConfig is true)"
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class ClientTokenEndpointOptions(BaseModel):
|
|
366
|
+
"""Options for createClientTokenEndpoint."""
|
|
367
|
+
|
|
368
|
+
clientTokenUri: Optional[str] = Field(
|
|
369
|
+
default="/api/v1/auth/client-token",
|
|
370
|
+
description="Client token endpoint URI (default: '/api/v1/auth/client-token')",
|
|
371
|
+
)
|
|
372
|
+
expiresIn: Optional[int] = Field(
|
|
373
|
+
default=1800, description="Token expiration time in seconds (default: 1800)"
|
|
374
|
+
)
|
|
375
|
+
includeConfig: Optional[bool] = Field(
|
|
376
|
+
default=True, description="Whether to include DataClient config in response (default: true)"
|
|
377
|
+
)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Structured error response model following RFC 7807-style format.
|
|
3
|
+
|
|
4
|
+
This module provides a generic error response interface that can be used
|
|
5
|
+
across different applications for consistent error handling.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import List, Optional
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ErrorResponse(BaseModel):
|
|
14
|
+
"""
|
|
15
|
+
Structured error response following RFC 7807-style format.
|
|
16
|
+
|
|
17
|
+
This model represents a standardized error response structure that includes:
|
|
18
|
+
- Multiple error messages
|
|
19
|
+
- Error type identifier
|
|
20
|
+
- Human-readable title
|
|
21
|
+
- HTTP status code
|
|
22
|
+
- Request instance URI (optional)
|
|
23
|
+
|
|
24
|
+
Example:
|
|
25
|
+
{
|
|
26
|
+
"errors": ["Error message 1", "Error message 2"],
|
|
27
|
+
"type": "/Errors/Bad Input",
|
|
28
|
+
"title": "Bad Request",
|
|
29
|
+
"statusCode": 400,
|
|
30
|
+
"instance": "/OpenApi/rest/Xzy"
|
|
31
|
+
}
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
errors: List[str] = Field(..., description="List of error messages")
|
|
35
|
+
type: str = Field(..., description="Error type URI (e.g., '/Errors/Bad Input')")
|
|
36
|
+
title: Optional[str] = Field(default=None, description="Human-readable error title")
|
|
37
|
+
statusCode: int = Field(..., description="HTTP status code")
|
|
38
|
+
instance: Optional[str] = Field(default=None, description="Request instance URI")
|
|
39
|
+
correlationId: Optional[str] = Field(default=None, description="Request key for error tracking")
|