dominus-sdk-python-dev 2.1.6__py3-none-any.whl → 2.1.7__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.
- dominus/__init__.py +47 -47
- dominus/config/__init__.py +24 -24
- dominus/config/endpoints.py +39 -39
- dominus/errors.py +201 -201
- dominus/helpers/__init__.py +2 -2
- dominus/helpers/auth.py +23 -23
- dominus/helpers/cache.py +192 -192
- dominus/helpers/core.py +657 -657
- dominus/helpers/crypto.py +118 -118
- dominus/namespaces/__init__.py +26 -26
- dominus/namespaces/_deprecated_crossover.py +10 -10
- dominus/namespaces/_deprecated_sql.py +1341 -1341
- dominus/namespaces/auth.py +1056 -1056
- dominus/namespaces/courier.py +251 -251
- dominus/namespaces/db.py +267 -267
- dominus/namespaces/ddl.py +590 -590
- dominus/namespaces/files.py +299 -299
- dominus/namespaces/health.py +59 -59
- dominus/namespaces/logs.py +367 -367
- dominus/namespaces/open.py +72 -72
- dominus/namespaces/portal.py +504 -504
- dominus/namespaces/redis.py +357 -357
- dominus/namespaces/secrets.py +126 -126
- dominus/services/__init__.py +2 -2
- dominus/services/_deprecated_architect.py +323 -323
- dominus/services/_deprecated_sovereign.py +93 -93
- dominus/start.py +1034 -1034
- {dominus_sdk_python_dev-2.1.6.dist-info → dominus_sdk_python_dev-2.1.7.dist-info}/METADATA +381 -381
- dominus_sdk_python_dev-2.1.7.dist-info/RECORD +31 -0
- dominus_sdk_python_dev-2.1.6.dist-info/RECORD +0 -31
- {dominus_sdk_python_dev-2.1.6.dist-info → dominus_sdk_python_dev-2.1.7.dist-info}/WHEEL +0 -0
- {dominus_sdk_python_dev-2.1.6.dist-info → dominus_sdk_python_dev-2.1.7.dist-info}/top_level.txt +0 -0
dominus/__init__.py
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
"""
|
|
2
|
-
CB Dominus SDK - Ultra-flat async SDK for CareBridge Services
|
|
3
|
-
|
|
4
|
-
Ultra-Flat API:
|
|
5
|
-
from dominus import dominus
|
|
6
|
-
|
|
7
|
-
# Secrets (root level)
|
|
8
|
-
value = await dominus.get("DB_URL")
|
|
9
|
-
await dominus.upsert("KEY", "value")
|
|
10
|
-
|
|
11
|
-
# Auth (root level)
|
|
12
|
-
await dominus.add_user(username="john", password="secret", role_id="...")
|
|
13
|
-
await dominus.add_scope(slug="read", display_name="Read", tenant_category_id=1)
|
|
14
|
-
result = await dominus.verify_user_password(username="john", password="secret")
|
|
15
|
-
|
|
16
|
-
# SQL data - app schema (root level)
|
|
17
|
-
tables = await dominus.list_tables()
|
|
18
|
-
rows = await dominus.query_table("users")
|
|
19
|
-
await dominus.insert_row("users", {"name": "John"})
|
|
20
|
-
|
|
21
|
-
# SQL data - secure schema (secure namespace)
|
|
22
|
-
rows = await dominus.secure.query_table("patients")
|
|
23
|
-
await dominus.secure.insert_row("patients", {"mrn": "12345"})
|
|
24
|
-
|
|
25
|
-
# Schema DDL - app schema (root level)
|
|
26
|
-
await dominus.add_table("users", [{"name": "id", "type": "UUID"}])
|
|
27
|
-
|
|
28
|
-
# Schema DDL - secure schema (secure namespace)
|
|
29
|
-
await dominus.secure.add_table("patients", [...])
|
|
30
|
-
|
|
31
|
-
# Open DSN
|
|
32
|
-
dsn = await dominus.open.dsn()
|
|
33
|
-
|
|
34
|
-
# Health
|
|
35
|
-
status = await dominus.health.check()
|
|
36
|
-
|
|
37
|
-
Backward Compatible String API:
|
|
38
|
-
result = await dominus("secrets.get", key="DB_URL")
|
|
39
|
-
"""
|
|
40
|
-
from .start import dominus
|
|
41
|
-
from .helpers.core import DominusResponse
|
|
42
|
-
|
|
43
|
-
__version__ = "0.3.0"
|
|
44
|
-
__all__ = [
|
|
45
|
-
"dominus",
|
|
46
|
-
"DominusResponse",
|
|
47
|
-
]
|
|
1
|
+
"""
|
|
2
|
+
CB Dominus SDK - Ultra-flat async SDK for CareBridge Services
|
|
3
|
+
|
|
4
|
+
Ultra-Flat API:
|
|
5
|
+
from dominus import dominus
|
|
6
|
+
|
|
7
|
+
# Secrets (root level)
|
|
8
|
+
value = await dominus.get("DB_URL")
|
|
9
|
+
await dominus.upsert("KEY", "value")
|
|
10
|
+
|
|
11
|
+
# Auth (root level)
|
|
12
|
+
await dominus.add_user(username="john", password="secret", role_id="...")
|
|
13
|
+
await dominus.add_scope(slug="read", display_name="Read", tenant_category_id=1)
|
|
14
|
+
result = await dominus.verify_user_password(username="john", password="secret")
|
|
15
|
+
|
|
16
|
+
# SQL data - app schema (root level)
|
|
17
|
+
tables = await dominus.list_tables()
|
|
18
|
+
rows = await dominus.query_table("users")
|
|
19
|
+
await dominus.insert_row("users", {"name": "John"})
|
|
20
|
+
|
|
21
|
+
# SQL data - secure schema (secure namespace)
|
|
22
|
+
rows = await dominus.secure.query_table("patients")
|
|
23
|
+
await dominus.secure.insert_row("patients", {"mrn": "12345"})
|
|
24
|
+
|
|
25
|
+
# Schema DDL - app schema (root level)
|
|
26
|
+
await dominus.add_table("users", [{"name": "id", "type": "UUID"}])
|
|
27
|
+
|
|
28
|
+
# Schema DDL - secure schema (secure namespace)
|
|
29
|
+
await dominus.secure.add_table("patients", [...])
|
|
30
|
+
|
|
31
|
+
# Open DSN
|
|
32
|
+
dsn = await dominus.open.dsn()
|
|
33
|
+
|
|
34
|
+
# Health
|
|
35
|
+
status = await dominus.health.check()
|
|
36
|
+
|
|
37
|
+
Backward Compatible String API:
|
|
38
|
+
result = await dominus("secrets.get", key="DB_URL")
|
|
39
|
+
"""
|
|
40
|
+
from .start import dominus
|
|
41
|
+
from .helpers.core import DominusResponse
|
|
42
|
+
|
|
43
|
+
__version__ = "0.3.0"
|
|
44
|
+
__all__ = [
|
|
45
|
+
"dominus",
|
|
46
|
+
"DominusResponse",
|
|
47
|
+
]
|
dominus/config/__init__.py
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
"""SDK Configuration"""
|
|
2
|
-
from .endpoints import (
|
|
3
|
-
SOVEREIGN_URL,
|
|
4
|
-
ARCHITECT_URL,
|
|
5
|
-
ORCHESTRATOR_URL,
|
|
6
|
-
WARDEN_URL,
|
|
7
|
-
get_service_url,
|
|
8
|
-
get_architect_url,
|
|
9
|
-
get_sovereign_url,
|
|
10
|
-
PROJECT_NUMBER,
|
|
11
|
-
REGION,
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
__all__ = [
|
|
15
|
-
"SOVEREIGN_URL",
|
|
16
|
-
"ARCHITECT_URL",
|
|
17
|
-
"ORCHESTRATOR_URL",
|
|
18
|
-
"WARDEN_URL",
|
|
19
|
-
"get_service_url",
|
|
20
|
-
"get_architect_url",
|
|
21
|
-
"get_sovereign_url",
|
|
22
|
-
"PROJECT_NUMBER",
|
|
23
|
-
"REGION",
|
|
24
|
-
]
|
|
1
|
+
"""SDK Configuration"""
|
|
2
|
+
from .endpoints import (
|
|
3
|
+
SOVEREIGN_URL,
|
|
4
|
+
ARCHITECT_URL,
|
|
5
|
+
ORCHESTRATOR_URL,
|
|
6
|
+
WARDEN_URL,
|
|
7
|
+
get_service_url,
|
|
8
|
+
get_architect_url,
|
|
9
|
+
get_sovereign_url,
|
|
10
|
+
PROJECT_NUMBER,
|
|
11
|
+
REGION,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"SOVEREIGN_URL",
|
|
16
|
+
"ARCHITECT_URL",
|
|
17
|
+
"ORCHESTRATOR_URL",
|
|
18
|
+
"WARDEN_URL",
|
|
19
|
+
"get_service_url",
|
|
20
|
+
"get_architect_url",
|
|
21
|
+
"get_sovereign_url",
|
|
22
|
+
"PROJECT_NUMBER",
|
|
23
|
+
"REGION",
|
|
24
|
+
]
|
dominus/config/endpoints.py
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Dominus Orchestrator Endpoints
|
|
3
|
-
|
|
4
|
-
Single backend URL for all services. The SDK now targets dominus-orchestrator
|
|
5
|
-
which consolidates all service functionality.
|
|
6
|
-
|
|
7
|
-
Usage:
|
|
8
|
-
from dominus.config.endpoints import BASE_URL
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
# Dominus Orchestrator Production URL
|
|
12
|
-
BASE_URL = "https://dominus-orchestrator-production-775398158805.us-east4.run.app"
|
|
13
|
-
|
|
14
|
-
# Legacy aliases (all point to orchestrator now) - DEPRECATED
|
|
15
|
-
SOVEREIGN_URL = BASE_URL
|
|
16
|
-
ARCHITECT_URL = BASE_URL
|
|
17
|
-
ORCHESTRATOR_URL = BASE_URL
|
|
18
|
-
WARDEN_URL = BASE_URL
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def get_base_url() -> str:
|
|
22
|
-
"""Get the dominus-orchestrator base URL."""
|
|
23
|
-
return BASE_URL
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# DEPRECATED - use get_base_url()
|
|
27
|
-
def get_sovereign_url(environment: str = None) -> str:
|
|
28
|
-
"""Deprecated: Use get_base_url() instead."""
|
|
29
|
-
return BASE_URL
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def get_architect_url(environment: str = None) -> str:
|
|
33
|
-
"""Deprecated: Use get_base_url() instead."""
|
|
34
|
-
return BASE_URL
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def get_service_url(service: str, environment: str = None) -> str:
|
|
38
|
-
"""Deprecated: Use get_base_url() instead. All services are now consolidated."""
|
|
39
|
-
return BASE_URL
|
|
1
|
+
"""
|
|
2
|
+
Dominus Orchestrator Endpoints
|
|
3
|
+
|
|
4
|
+
Single backend URL for all services. The SDK now targets dominus-orchestrator
|
|
5
|
+
which consolidates all service functionality.
|
|
6
|
+
|
|
7
|
+
Usage:
|
|
8
|
+
from dominus.config.endpoints import BASE_URL
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
# Dominus Orchestrator Production URL
|
|
12
|
+
BASE_URL = "https://dominus-orchestrator-production-775398158805.us-east4.run.app"
|
|
13
|
+
|
|
14
|
+
# Legacy aliases (all point to orchestrator now) - DEPRECATED
|
|
15
|
+
SOVEREIGN_URL = BASE_URL
|
|
16
|
+
ARCHITECT_URL = BASE_URL
|
|
17
|
+
ORCHESTRATOR_URL = BASE_URL
|
|
18
|
+
WARDEN_URL = BASE_URL
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_base_url() -> str:
|
|
22
|
+
"""Get the dominus-orchestrator base URL."""
|
|
23
|
+
return BASE_URL
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# DEPRECATED - use get_base_url()
|
|
27
|
+
def get_sovereign_url(environment: str = None) -> str:
|
|
28
|
+
"""Deprecated: Use get_base_url() instead."""
|
|
29
|
+
return BASE_URL
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def get_architect_url(environment: str = None) -> str:
|
|
33
|
+
"""Deprecated: Use get_base_url() instead."""
|
|
34
|
+
return BASE_URL
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_service_url(service: str, environment: str = None) -> str:
|
|
38
|
+
"""Deprecated: Use get_base_url() instead. All services are now consolidated."""
|
|
39
|
+
return BASE_URL
|
dominus/errors.py
CHANGED
|
@@ -1,201 +1,201 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Dominus SDK Error Classes
|
|
3
|
-
|
|
4
|
-
Custom exceptions for the Dominus SDK with structured error information.
|
|
5
|
-
"""
|
|
6
|
-
from typing import Any, Dict, Optional
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class DominusError(Exception):
|
|
10
|
-
"""
|
|
11
|
-
Base exception for all Dominus SDK errors.
|
|
12
|
-
|
|
13
|
-
Provides structured error information including HTTP status codes,
|
|
14
|
-
error messages, and optional details from the backend.
|
|
15
|
-
|
|
16
|
-
Attributes:
|
|
17
|
-
message: Human-readable error message
|
|
18
|
-
status_code: HTTP status code (if applicable)
|
|
19
|
-
details: Additional error details from backend
|
|
20
|
-
endpoint: The endpoint that was called (if applicable)
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
def __init__(
|
|
24
|
-
self,
|
|
25
|
-
message: str,
|
|
26
|
-
status_code: Optional[int] = None,
|
|
27
|
-
details: Optional[Dict[str, Any]] = None,
|
|
28
|
-
endpoint: Optional[str] = None
|
|
29
|
-
):
|
|
30
|
-
self.message = message
|
|
31
|
-
self.status_code = status_code
|
|
32
|
-
self.details = details or {}
|
|
33
|
-
self.endpoint = endpoint
|
|
34
|
-
super().__init__(self.message)
|
|
35
|
-
|
|
36
|
-
def __str__(self) -> str:
|
|
37
|
-
parts = [self.message]
|
|
38
|
-
if self.status_code:
|
|
39
|
-
parts.append(f"(status {self.status_code})")
|
|
40
|
-
if self.endpoint:
|
|
41
|
-
parts.append(f"at {self.endpoint}")
|
|
42
|
-
return " ".join(parts)
|
|
43
|
-
|
|
44
|
-
def __repr__(self) -> str:
|
|
45
|
-
return (
|
|
46
|
-
f"DominusError(message={self.message!r}, "
|
|
47
|
-
f"status_code={self.status_code}, "
|
|
48
|
-
f"details={self.details!r}, "
|
|
49
|
-
f"endpoint={self.endpoint!r})"
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
class AuthenticationError(DominusError):
|
|
54
|
-
"""Raised when authentication fails (invalid token, expired JWT, etc.)."""
|
|
55
|
-
|
|
56
|
-
def __init__(
|
|
57
|
-
self,
|
|
58
|
-
message: str = "Authentication failed",
|
|
59
|
-
status_code: int = 401,
|
|
60
|
-
details: Optional[Dict[str, Any]] = None,
|
|
61
|
-
endpoint: Optional[str] = None
|
|
62
|
-
):
|
|
63
|
-
super().__init__(message, status_code, details, endpoint)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
class AuthorizationError(DominusError):
|
|
67
|
-
"""Raised when authorization fails (insufficient permissions)."""
|
|
68
|
-
|
|
69
|
-
def __init__(
|
|
70
|
-
self,
|
|
71
|
-
message: str = "Permission denied",
|
|
72
|
-
status_code: int = 403,
|
|
73
|
-
details: Optional[Dict[str, Any]] = None,
|
|
74
|
-
endpoint: Optional[str] = None
|
|
75
|
-
):
|
|
76
|
-
super().__init__(message, status_code, details, endpoint)
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
class NotFoundError(DominusError):
|
|
80
|
-
"""Raised when a requested resource is not found."""
|
|
81
|
-
|
|
82
|
-
def __init__(
|
|
83
|
-
self,
|
|
84
|
-
message: str = "Resource not found",
|
|
85
|
-
status_code: int = 404,
|
|
86
|
-
details: Optional[Dict[str, Any]] = None,
|
|
87
|
-
endpoint: Optional[str] = None
|
|
88
|
-
):
|
|
89
|
-
super().__init__(message, status_code, details, endpoint)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
class ValidationError(DominusError):
|
|
93
|
-
"""Raised when request validation fails."""
|
|
94
|
-
|
|
95
|
-
def __init__(
|
|
96
|
-
self,
|
|
97
|
-
message: str = "Validation failed",
|
|
98
|
-
status_code: int = 400,
|
|
99
|
-
details: Optional[Dict[str, Any]] = None,
|
|
100
|
-
endpoint: Optional[str] = None
|
|
101
|
-
):
|
|
102
|
-
super().__init__(message, status_code, details, endpoint)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
class ConflictError(DominusError):
|
|
106
|
-
"""Raised when there's a conflict (duplicate key, version mismatch, etc.)."""
|
|
107
|
-
|
|
108
|
-
def __init__(
|
|
109
|
-
self,
|
|
110
|
-
message: str = "Conflict",
|
|
111
|
-
status_code: int = 409,
|
|
112
|
-
details: Optional[Dict[str, Any]] = None,
|
|
113
|
-
endpoint: Optional[str] = None
|
|
114
|
-
):
|
|
115
|
-
super().__init__(message, status_code, details, endpoint)
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
class ServiceError(DominusError):
|
|
119
|
-
"""Raised when a backend service error occurs."""
|
|
120
|
-
|
|
121
|
-
def __init__(
|
|
122
|
-
self,
|
|
123
|
-
message: str = "Service error",
|
|
124
|
-
status_code: int = 500,
|
|
125
|
-
details: Optional[Dict[str, Any]] = None,
|
|
126
|
-
endpoint: Optional[str] = None
|
|
127
|
-
):
|
|
128
|
-
super().__init__(message, status_code, details, endpoint)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
class ConnectionError(DominusError):
|
|
132
|
-
"""Raised when connection to the backend fails."""
|
|
133
|
-
|
|
134
|
-
def __init__(
|
|
135
|
-
self,
|
|
136
|
-
message: str = "Connection failed",
|
|
137
|
-
status_code: Optional[int] = None,
|
|
138
|
-
details: Optional[Dict[str, Any]] = None,
|
|
139
|
-
endpoint: Optional[str] = None
|
|
140
|
-
):
|
|
141
|
-
super().__init__(message, status_code, details, endpoint)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
class TimeoutError(DominusError):
|
|
145
|
-
"""Raised when a request times out."""
|
|
146
|
-
|
|
147
|
-
def __init__(
|
|
148
|
-
self,
|
|
149
|
-
message: str = "Request timed out",
|
|
150
|
-
status_code: Optional[int] = None,
|
|
151
|
-
details: Optional[Dict[str, Any]] = None,
|
|
152
|
-
endpoint: Optional[str] = None
|
|
153
|
-
):
|
|
154
|
-
super().__init__(message, status_code, details, endpoint)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
class SecureTableError(DominusError):
|
|
158
|
-
"""Raised when accessing a secure table without providing a reason."""
|
|
159
|
-
|
|
160
|
-
def __init__(
|
|
161
|
-
self,
|
|
162
|
-
message: str = "Access to secure table requires 'reason' parameter",
|
|
163
|
-
status_code: int = 403,
|
|
164
|
-
details: Optional[Dict[str, Any]] = None,
|
|
165
|
-
endpoint: Optional[str] = None
|
|
166
|
-
):
|
|
167
|
-
super().__init__(message, status_code, details, endpoint)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def raise_for_status(
|
|
171
|
-
status_code: int,
|
|
172
|
-
message: str,
|
|
173
|
-
details: Optional[Dict[str, Any]] = None,
|
|
174
|
-
endpoint: Optional[str] = None
|
|
175
|
-
) -> None:
|
|
176
|
-
"""
|
|
177
|
-
Raise appropriate DominusError subclass based on status code.
|
|
178
|
-
|
|
179
|
-
Args:
|
|
180
|
-
status_code: HTTP status code
|
|
181
|
-
message: Error message
|
|
182
|
-
details: Optional error details
|
|
183
|
-
endpoint: Optional endpoint that was called
|
|
184
|
-
|
|
185
|
-
Raises:
|
|
186
|
-
Appropriate DominusError subclass
|
|
187
|
-
"""
|
|
188
|
-
error_classes = {
|
|
189
|
-
400: ValidationError,
|
|
190
|
-
401: AuthenticationError,
|
|
191
|
-
403: AuthorizationError,
|
|
192
|
-
404: NotFoundError,
|
|
193
|
-
409: ConflictError,
|
|
194
|
-
500: ServiceError,
|
|
195
|
-
502: ServiceError,
|
|
196
|
-
503: ServiceError,
|
|
197
|
-
504: TimeoutError,
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
error_class = error_classes.get(status_code, DominusError)
|
|
201
|
-
raise error_class(message, status_code, details, endpoint)
|
|
1
|
+
"""
|
|
2
|
+
Dominus SDK Error Classes
|
|
3
|
+
|
|
4
|
+
Custom exceptions for the Dominus SDK with structured error information.
|
|
5
|
+
"""
|
|
6
|
+
from typing import Any, Dict, Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DominusError(Exception):
|
|
10
|
+
"""
|
|
11
|
+
Base exception for all Dominus SDK errors.
|
|
12
|
+
|
|
13
|
+
Provides structured error information including HTTP status codes,
|
|
14
|
+
error messages, and optional details from the backend.
|
|
15
|
+
|
|
16
|
+
Attributes:
|
|
17
|
+
message: Human-readable error message
|
|
18
|
+
status_code: HTTP status code (if applicable)
|
|
19
|
+
details: Additional error details from backend
|
|
20
|
+
endpoint: The endpoint that was called (if applicable)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
message: str,
|
|
26
|
+
status_code: Optional[int] = None,
|
|
27
|
+
details: Optional[Dict[str, Any]] = None,
|
|
28
|
+
endpoint: Optional[str] = None
|
|
29
|
+
):
|
|
30
|
+
self.message = message
|
|
31
|
+
self.status_code = status_code
|
|
32
|
+
self.details = details or {}
|
|
33
|
+
self.endpoint = endpoint
|
|
34
|
+
super().__init__(self.message)
|
|
35
|
+
|
|
36
|
+
def __str__(self) -> str:
|
|
37
|
+
parts = [self.message]
|
|
38
|
+
if self.status_code:
|
|
39
|
+
parts.append(f"(status {self.status_code})")
|
|
40
|
+
if self.endpoint:
|
|
41
|
+
parts.append(f"at {self.endpoint}")
|
|
42
|
+
return " ".join(parts)
|
|
43
|
+
|
|
44
|
+
def __repr__(self) -> str:
|
|
45
|
+
return (
|
|
46
|
+
f"DominusError(message={self.message!r}, "
|
|
47
|
+
f"status_code={self.status_code}, "
|
|
48
|
+
f"details={self.details!r}, "
|
|
49
|
+
f"endpoint={self.endpoint!r})"
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class AuthenticationError(DominusError):
|
|
54
|
+
"""Raised when authentication fails (invalid token, expired JWT, etc.)."""
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
message: str = "Authentication failed",
|
|
59
|
+
status_code: int = 401,
|
|
60
|
+
details: Optional[Dict[str, Any]] = None,
|
|
61
|
+
endpoint: Optional[str] = None
|
|
62
|
+
):
|
|
63
|
+
super().__init__(message, status_code, details, endpoint)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class AuthorizationError(DominusError):
|
|
67
|
+
"""Raised when authorization fails (insufficient permissions)."""
|
|
68
|
+
|
|
69
|
+
def __init__(
|
|
70
|
+
self,
|
|
71
|
+
message: str = "Permission denied",
|
|
72
|
+
status_code: int = 403,
|
|
73
|
+
details: Optional[Dict[str, Any]] = None,
|
|
74
|
+
endpoint: Optional[str] = None
|
|
75
|
+
):
|
|
76
|
+
super().__init__(message, status_code, details, endpoint)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class NotFoundError(DominusError):
|
|
80
|
+
"""Raised when a requested resource is not found."""
|
|
81
|
+
|
|
82
|
+
def __init__(
|
|
83
|
+
self,
|
|
84
|
+
message: str = "Resource not found",
|
|
85
|
+
status_code: int = 404,
|
|
86
|
+
details: Optional[Dict[str, Any]] = None,
|
|
87
|
+
endpoint: Optional[str] = None
|
|
88
|
+
):
|
|
89
|
+
super().__init__(message, status_code, details, endpoint)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class ValidationError(DominusError):
|
|
93
|
+
"""Raised when request validation fails."""
|
|
94
|
+
|
|
95
|
+
def __init__(
|
|
96
|
+
self,
|
|
97
|
+
message: str = "Validation failed",
|
|
98
|
+
status_code: int = 400,
|
|
99
|
+
details: Optional[Dict[str, Any]] = None,
|
|
100
|
+
endpoint: Optional[str] = None
|
|
101
|
+
):
|
|
102
|
+
super().__init__(message, status_code, details, endpoint)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class ConflictError(DominusError):
|
|
106
|
+
"""Raised when there's a conflict (duplicate key, version mismatch, etc.)."""
|
|
107
|
+
|
|
108
|
+
def __init__(
|
|
109
|
+
self,
|
|
110
|
+
message: str = "Conflict",
|
|
111
|
+
status_code: int = 409,
|
|
112
|
+
details: Optional[Dict[str, Any]] = None,
|
|
113
|
+
endpoint: Optional[str] = None
|
|
114
|
+
):
|
|
115
|
+
super().__init__(message, status_code, details, endpoint)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class ServiceError(DominusError):
|
|
119
|
+
"""Raised when a backend service error occurs."""
|
|
120
|
+
|
|
121
|
+
def __init__(
|
|
122
|
+
self,
|
|
123
|
+
message: str = "Service error",
|
|
124
|
+
status_code: int = 500,
|
|
125
|
+
details: Optional[Dict[str, Any]] = None,
|
|
126
|
+
endpoint: Optional[str] = None
|
|
127
|
+
):
|
|
128
|
+
super().__init__(message, status_code, details, endpoint)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ConnectionError(DominusError):
|
|
132
|
+
"""Raised when connection to the backend fails."""
|
|
133
|
+
|
|
134
|
+
def __init__(
|
|
135
|
+
self,
|
|
136
|
+
message: str = "Connection failed",
|
|
137
|
+
status_code: Optional[int] = None,
|
|
138
|
+
details: Optional[Dict[str, Any]] = None,
|
|
139
|
+
endpoint: Optional[str] = None
|
|
140
|
+
):
|
|
141
|
+
super().__init__(message, status_code, details, endpoint)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class TimeoutError(DominusError):
|
|
145
|
+
"""Raised when a request times out."""
|
|
146
|
+
|
|
147
|
+
def __init__(
|
|
148
|
+
self,
|
|
149
|
+
message: str = "Request timed out",
|
|
150
|
+
status_code: Optional[int] = None,
|
|
151
|
+
details: Optional[Dict[str, Any]] = None,
|
|
152
|
+
endpoint: Optional[str] = None
|
|
153
|
+
):
|
|
154
|
+
super().__init__(message, status_code, details, endpoint)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class SecureTableError(DominusError):
|
|
158
|
+
"""Raised when accessing a secure table without providing a reason."""
|
|
159
|
+
|
|
160
|
+
def __init__(
|
|
161
|
+
self,
|
|
162
|
+
message: str = "Access to secure table requires 'reason' parameter",
|
|
163
|
+
status_code: int = 403,
|
|
164
|
+
details: Optional[Dict[str, Any]] = None,
|
|
165
|
+
endpoint: Optional[str] = None
|
|
166
|
+
):
|
|
167
|
+
super().__init__(message, status_code, details, endpoint)
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def raise_for_status(
|
|
171
|
+
status_code: int,
|
|
172
|
+
message: str,
|
|
173
|
+
details: Optional[Dict[str, Any]] = None,
|
|
174
|
+
endpoint: Optional[str] = None
|
|
175
|
+
) -> None:
|
|
176
|
+
"""
|
|
177
|
+
Raise appropriate DominusError subclass based on status code.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
status_code: HTTP status code
|
|
181
|
+
message: Error message
|
|
182
|
+
details: Optional error details
|
|
183
|
+
endpoint: Optional endpoint that was called
|
|
184
|
+
|
|
185
|
+
Raises:
|
|
186
|
+
Appropriate DominusError subclass
|
|
187
|
+
"""
|
|
188
|
+
error_classes = {
|
|
189
|
+
400: ValidationError,
|
|
190
|
+
401: AuthenticationError,
|
|
191
|
+
403: AuthorizationError,
|
|
192
|
+
404: NotFoundError,
|
|
193
|
+
409: ConflictError,
|
|
194
|
+
500: ServiceError,
|
|
195
|
+
502: ServiceError,
|
|
196
|
+
503: ServiceError,
|
|
197
|
+
504: TimeoutError,
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
error_class = error_classes.get(status_code, DominusError)
|
|
201
|
+
raise error_class(message, status_code, details, endpoint)
|
dominus/helpers/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"""Helper modules for CB Dominus SDK - Internal use only"""
|
|
2
|
-
|
|
1
|
+
"""Helper modules for CB Dominus SDK - Internal use only"""
|
|
2
|
+
|