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.
Files changed (69) hide show
  1. miso_client/__init__.py +523 -130
  2. miso_client/api/__init__.py +35 -0
  3. miso_client/api/auth_api.py +367 -0
  4. miso_client/api/logs_api.py +91 -0
  5. miso_client/api/permissions_api.py +88 -0
  6. miso_client/api/roles_api.py +88 -0
  7. miso_client/api/types/__init__.py +75 -0
  8. miso_client/api/types/auth_types.py +183 -0
  9. miso_client/api/types/logs_types.py +71 -0
  10. miso_client/api/types/permissions_types.py +31 -0
  11. miso_client/api/types/roles_types.py +31 -0
  12. miso_client/errors.py +30 -4
  13. miso_client/models/__init__.py +4 -0
  14. miso_client/models/config.py +275 -72
  15. miso_client/models/error_response.py +39 -0
  16. miso_client/models/filter.py +255 -0
  17. miso_client/models/pagination.py +44 -0
  18. miso_client/models/sort.py +25 -0
  19. miso_client/services/__init__.py +6 -5
  20. miso_client/services/auth.py +496 -87
  21. miso_client/services/cache.py +42 -41
  22. miso_client/services/encryption.py +18 -17
  23. miso_client/services/logger.py +467 -328
  24. miso_client/services/logger_chain.py +288 -0
  25. miso_client/services/permission.py +130 -67
  26. miso_client/services/redis.py +28 -23
  27. miso_client/services/role.py +145 -62
  28. miso_client/utils/__init__.py +3 -3
  29. miso_client/utils/audit_log_queue.py +222 -0
  30. miso_client/utils/auth_strategy.py +88 -0
  31. miso_client/utils/auth_utils.py +65 -0
  32. miso_client/utils/circuit_breaker.py +125 -0
  33. miso_client/utils/client_token_manager.py +244 -0
  34. miso_client/utils/config_loader.py +88 -17
  35. miso_client/utils/controller_url_resolver.py +80 -0
  36. miso_client/utils/data_masker.py +104 -33
  37. miso_client/utils/environment_token.py +126 -0
  38. miso_client/utils/error_utils.py +216 -0
  39. miso_client/utils/fastapi_endpoints.py +166 -0
  40. miso_client/utils/filter.py +364 -0
  41. miso_client/utils/filter_applier.py +143 -0
  42. miso_client/utils/filter_parser.py +110 -0
  43. miso_client/utils/flask_endpoints.py +169 -0
  44. miso_client/utils/http_client.py +494 -262
  45. miso_client/utils/http_client_logging.py +352 -0
  46. miso_client/utils/http_client_logging_helpers.py +197 -0
  47. miso_client/utils/http_client_query_helpers.py +138 -0
  48. miso_client/utils/http_error_handler.py +92 -0
  49. miso_client/utils/http_log_formatter.py +115 -0
  50. miso_client/utils/http_log_masker.py +203 -0
  51. miso_client/utils/internal_http_client.py +435 -0
  52. miso_client/utils/jwt_tools.py +125 -16
  53. miso_client/utils/logger_helpers.py +206 -0
  54. miso_client/utils/logging_helpers.py +70 -0
  55. miso_client/utils/origin_validator.py +128 -0
  56. miso_client/utils/pagination.py +275 -0
  57. miso_client/utils/request_context.py +285 -0
  58. miso_client/utils/sensitive_fields_loader.py +116 -0
  59. miso_client/utils/sort.py +116 -0
  60. miso_client/utils/token_utils.py +114 -0
  61. miso_client/utils/url_validator.py +66 -0
  62. miso_client/utils/user_token_refresh.py +245 -0
  63. miso_client-3.7.2.dist-info/METADATA +1021 -0
  64. miso_client-3.7.2.dist-info/RECORD +68 -0
  65. miso_client-0.1.0.dist-info/METADATA +0 -551
  66. miso_client-0.1.0.dist-info/RECORD +0 -23
  67. {miso_client-0.1.0.dist-info → miso_client-3.7.2.dist-info}/WHEEL +0 -0
  68. {miso_client-0.1.0.dist-info → miso_client-3.7.2.dist-info}/licenses/LICENSE +0 -0
  69. {miso_client-0.1.0.dist-info → miso_client-3.7.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,255 @@
1
+ """
2
+ Filter types for MisoClient SDK.
3
+
4
+ This module contains Pydantic models and classes that define filter structures
5
+ for query filtering matching the Miso/Dataplane API conventions.
6
+ """
7
+
8
+ from typing import Any, Dict, List, Literal, Optional, Union
9
+
10
+ from pydantic import BaseModel, Field
11
+
12
+ FilterOperator = Literal[
13
+ "eq",
14
+ "neq",
15
+ "in",
16
+ "nin",
17
+ "gt",
18
+ "lt",
19
+ "gte",
20
+ "lte",
21
+ "contains",
22
+ "like",
23
+ "isNull",
24
+ "isNotNull",
25
+ ]
26
+
27
+
28
+ class FilterOption(BaseModel):
29
+ """
30
+ Single filter option with field, operator, and value.
31
+
32
+ Fields:
33
+ field: Field name to filter on
34
+ op: Filter operator (eq, neq, in, nin, gt, lt, gte, lte, contains, like, isNull, isNotNull)
35
+ value: Filter value (supports single values or arrays for 'in'/'nin' operators)
36
+ """
37
+
38
+ field: str = Field(..., description="Field name to filter on")
39
+ op: FilterOperator = Field(..., description="Filter operator")
40
+ value: Optional[Union[str, int, float, bool, List[Any]]] = Field(
41
+ default=None,
42
+ description="Filter value (supports arrays for 'in'/'nin' operators, optional for 'isNull'/'isNotNull')",
43
+ )
44
+
45
+
46
+ class FilterQuery(BaseModel):
47
+ """
48
+ Complete filter query with filters, sort, pagination, and field selection.
49
+
50
+ Fields:
51
+ filters: Optional list of filter options
52
+ sort: Optional list of sort options (field strings with optional '-' prefix for desc)
53
+ page: Optional page number (1-based)
54
+ pageSize: Optional number of items per page
55
+ fields: Optional list of fields to include in response
56
+ """
57
+
58
+ filters: Optional[List[FilterOption]] = Field(
59
+ default=None, description="List of filter options"
60
+ )
61
+ sort: Optional[List[str]] = Field(
62
+ default=None,
63
+ description="List of sort options (e.g., ['-updated_at', 'created_at'])",
64
+ )
65
+ page: Optional[int] = Field(default=None, description="Page number (1-based)")
66
+ pageSize: Optional[int] = Field(default=None, description="Number of items per page")
67
+ fields: Optional[List[str]] = Field(
68
+ default=None, description="List of fields to include in response"
69
+ )
70
+
71
+ def to_json(self) -> Dict[str, Any]:
72
+ """
73
+ Convert FilterQuery to JSON dict (camelCase).
74
+
75
+ Returns:
76
+ Dictionary with filter data in camelCase format
77
+ """
78
+ return self.model_dump(exclude_none=True)
79
+
80
+ @classmethod
81
+ def from_json(cls, json_data: Dict[str, Any]) -> "FilterQuery":
82
+ """
83
+ Create FilterQuery from JSON dict.
84
+
85
+ Args:
86
+ json_data: Dictionary with filter data (camelCase or snake_case)
87
+
88
+ Returns:
89
+ FilterQuery instance
90
+ """
91
+ return cls(**json_data)
92
+
93
+ def to_json_filter(self) -> "JsonFilter":
94
+ """
95
+ Convert FilterQuery to JsonFilter.
96
+
97
+ Returns:
98
+ JsonFilter instance with same filters, sort, pagination, and fields
99
+ """
100
+ return JsonFilter(
101
+ filters=self.filters,
102
+ sort=self.sort,
103
+ page=self.page,
104
+ pageSize=self.pageSize,
105
+ fields=self.fields,
106
+ )
107
+
108
+
109
+ class FilterGroup(BaseModel):
110
+ """
111
+ Filter group for complex AND/OR logic.
112
+
113
+ Fields:
114
+ operator: Group operator ('and' or 'or')
115
+ filters: Optional list of FilterOption objects in this group
116
+ groups: Optional nested filter groups
117
+ """
118
+
119
+ operator: Literal["and", "or"] = Field(default="and", description="Group operator (and/or)")
120
+ filters: Optional[List[FilterOption]] = Field(
121
+ default=None, description="List of filter options in this group"
122
+ )
123
+ groups: Optional[List["FilterGroup"]] = Field(default=None, description="Nested filter groups")
124
+
125
+
126
+ class JsonFilter(BaseModel):
127
+ """
128
+ Unified JSON filter model for query string and JSON body filtering.
129
+
130
+ Supports both simple filters and filter groups with AND/OR logic.
131
+ Fields use camelCase for API compatibility.
132
+
133
+ Fields:
134
+ filters: Optional list of FilterOption objects (AND logic by default)
135
+ groups: Optional list of filter groups for complex AND/OR logic
136
+ sort: Optional list of sort options
137
+ page: Optional page number (1-based)
138
+ pageSize: Optional number of items per page
139
+ fields: Optional list of fields to include in response
140
+ """
141
+
142
+ filters: Optional[List[FilterOption]] = Field(
143
+ default=None, description="List of filter options (AND logic)"
144
+ )
145
+ groups: Optional[List[FilterGroup]] = Field(
146
+ default=None, description="List of filter groups for complex AND/OR logic"
147
+ )
148
+ sort: Optional[List[str]] = Field(
149
+ default=None,
150
+ description="List of sort options (e.g., ['-updated_at', 'created_at'])",
151
+ )
152
+ page: Optional[int] = Field(default=None, description="Page number (1-based)")
153
+ pageSize: Optional[int] = Field(default=None, description="Number of items per page")
154
+ fields: Optional[List[str]] = Field(
155
+ default=None, description="List of fields to include in response"
156
+ )
157
+
158
+
159
+ class FilterBuilder:
160
+ """
161
+ Builder pattern for dynamic filter construction.
162
+
163
+ Allows chaining filter additions for building complex filter queries.
164
+ """
165
+
166
+ def __init__(self):
167
+ """Initialize empty filter builder."""
168
+ self._filters: List[FilterOption] = []
169
+
170
+ def add(self, field: str, op: FilterOperator, value: Any) -> "FilterBuilder":
171
+ """
172
+ Add a filter option to the builder.
173
+
174
+ Args:
175
+ field: Field name to filter on
176
+ op: Filter operator
177
+ value: Filter value
178
+
179
+ Returns:
180
+ FilterBuilder instance for method chaining
181
+ """
182
+ self._filters.append(FilterOption(field=field, op=op, value=value))
183
+ return self
184
+
185
+ def add_many(self, filters: List[FilterOption]) -> "FilterBuilder":
186
+ """
187
+ Add multiple filter options to the builder.
188
+
189
+ Args:
190
+ filters: List of FilterOption objects
191
+
192
+ Returns:
193
+ FilterBuilder instance for method chaining
194
+ """
195
+ self._filters.extend(filters)
196
+ return self
197
+
198
+ def build(self) -> List[FilterOption]:
199
+ """
200
+ Build the filter list.
201
+
202
+ Returns:
203
+ List of FilterOption objects
204
+ """
205
+ return self._filters.copy()
206
+
207
+ def to_query_string(self) -> str:
208
+ """
209
+ Convert filters to query string format.
210
+
211
+ Format: ?filter=field:op:value&filter=field:op:value
212
+
213
+ Returns:
214
+ Query string with filter parameters
215
+ """
216
+ if not self._filters:
217
+ return ""
218
+
219
+ query_parts: List[str] = []
220
+ for filter_option in self._filters:
221
+ # Handle null check operators (no value needed)
222
+ if filter_option.op in ("isNull", "isNotNull"):
223
+ query_parts.append(f"filter={filter_option.field}:{filter_option.op}")
224
+ else:
225
+ # Format value for query string
226
+ if isinstance(filter_option.value, list):
227
+ # For arrays (in/nin), join with commas
228
+ value_str = ",".join(str(v) for v in filter_option.value)
229
+ elif filter_option.value is not None:
230
+ value_str = str(filter_option.value)
231
+ else:
232
+ value_str = ""
233
+
234
+ query_parts.append(f"filter={filter_option.field}:{filter_option.op}:{value_str}")
235
+
236
+ return "&".join(query_parts)
237
+
238
+ def to_json_filter(self) -> JsonFilter:
239
+ """
240
+ Convert FilterBuilder to JsonFilter.
241
+
242
+ Returns:
243
+ JsonFilter instance with filters from builder
244
+ """
245
+ return JsonFilter(filters=self._filters.copy() if self._filters else None)
246
+
247
+ def to_json(self) -> Dict[str, Any]:
248
+ """
249
+ Convert FilterBuilder to JSON dict (camelCase).
250
+
251
+ Returns:
252
+ Dictionary with filter data in camelCase format
253
+ """
254
+ json_filter = self.to_json_filter()
255
+ return json_filter.model_dump(exclude_none=True)
@@ -0,0 +1,44 @@
1
+ """
2
+ Pagination types for MisoClient SDK.
3
+
4
+ This module contains Pydantic models that define pagination structures
5
+ for paginated list responses matching the Miso/Dataplane API conventions.
6
+ """
7
+
8
+ from typing import Generic, List, TypeVar
9
+
10
+ from pydantic import BaseModel, Field
11
+
12
+ T = TypeVar("T")
13
+
14
+
15
+ class Meta(BaseModel):
16
+ """
17
+ Pagination metadata for list responses.
18
+
19
+ Fields:
20
+ totalItems: Total number of items across all pages
21
+ currentPage: Current page number (1-based, maps from `page` query param)
22
+ pageSize: Number of items per page (maps from `pageSize` query param)
23
+ type: Resource type identifier (e.g., 'item', 'user', 'group')
24
+ """
25
+
26
+ totalItems: int = Field(..., description="Total number of items")
27
+ currentPage: int = Field(..., description="Current page number (1-based)")
28
+ pageSize: int = Field(..., description="Number of items per page")
29
+ type: str = Field(..., description="Resource type identifier")
30
+
31
+
32
+ class PaginatedListResponse(BaseModel, Generic[T]):
33
+ """
34
+ Paginated list response structure.
35
+
36
+ Generic type parameter T represents the item type in the data array.
37
+
38
+ Fields:
39
+ meta: Pagination metadata
40
+ data: Array of items for current page
41
+ """
42
+
43
+ meta: Meta = Field(..., description="Pagination metadata")
44
+ data: List[T] = Field(..., description="Array of items for current page")
@@ -0,0 +1,25 @@
1
+ """
2
+ Sort types for MisoClient SDK.
3
+
4
+ This module contains Pydantic models that define sort structures
5
+ for query sorting matching the Miso/Dataplane API conventions.
6
+ """
7
+
8
+ from typing import Literal
9
+
10
+ from pydantic import BaseModel, Field
11
+
12
+ SortOrder = Literal["asc", "desc"]
13
+
14
+
15
+ class SortOption(BaseModel):
16
+ """
17
+ Sort option with field and order.
18
+
19
+ Fields:
20
+ field: Field name to sort by
21
+ order: Sort order ('asc' for ascending, 'desc' for descending)
22
+ """
23
+
24
+ field: str = Field(..., description="Field name to sort by")
25
+ order: SortOrder = Field(..., description="Sort order ('asc' or 'desc')")
@@ -1,12 +1,13 @@
1
1
  """Service implementations for MisoClient SDK."""
2
2
 
3
3
  from .auth import AuthService
4
- from .role import RoleService
4
+ from .cache import CacheService
5
+ from .encryption import EncryptionService
6
+ from .logger import LoggerService
7
+ from .logger_chain import LoggerChain
5
8
  from .permission import PermissionService
6
- from .logger import LoggerService, LoggerChain
7
9
  from .redis import RedisService
8
- from .encryption import EncryptionService
9
- from .cache import CacheService
10
+ from .role import RoleService
10
11
 
11
12
  __all__ = [
12
13
  "AuthService",
@@ -17,4 +18,4 @@ __all__ = [
17
18
  "RedisService",
18
19
  "EncryptionService",
19
20
  "CacheService",
20
- ]
21
+ ]