statuspro-openapi-client 0.1.0__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.
- statuspro_openapi_client-0.1.0.dist-info/METADATA +337 -0
- statuspro_openapi_client-0.1.0.dist-info/RECORD +74 -0
- statuspro_openapi_client-0.1.0.dist-info/WHEEL +4 -0
- statuspro_openapi_client-0.1.0.dist-info/entry_points.txt +3 -0
- statuspro_openapi_client-0.1.0.dist-info/licenses/LICENSE +21 -0
- statuspro_public_api_client/__init__.py +36 -0
- statuspro_public_api_client/_logging.py +33 -0
- statuspro_public_api_client/api/__init__.py +1 -0
- statuspro_public_api_client/api/orders/__init__.py +1 -0
- statuspro_public_api_client/api/orders/add_order_comment.py +215 -0
- statuspro_public_api_client/api/orders/bulk_update_order_status.py +194 -0
- statuspro_public_api_client/api/orders/get_order.py +188 -0
- statuspro_public_api_client/api/orders/get_viable_statuses.py +193 -0
- statuspro_public_api_client/api/orders/list_orders.py +366 -0
- statuspro_public_api_client/api/orders/lookup_order.py +208 -0
- statuspro_public_api_client/api/orders/set_order_due_date.py +215 -0
- statuspro_public_api_client/api/orders/update_order_status.py +215 -0
- statuspro_public_api_client/api/statuses/__init__.py +1 -0
- statuspro_public_api_client/api/statuses/get_statuses.py +161 -0
- statuspro_public_api_client/api_wrapper/__init__.py +15 -0
- statuspro_public_api_client/api_wrapper/_namespace.py +40 -0
- statuspro_public_api_client/api_wrapper/_registry.py +43 -0
- statuspro_public_api_client/api_wrapper/_resource.py +116 -0
- statuspro_public_api_client/client.py +267 -0
- statuspro_public_api_client/client_types.py +54 -0
- statuspro_public_api_client/domain/__init__.py +33 -0
- statuspro_public_api_client/domain/base.py +117 -0
- statuspro_public_api_client/domain/converters.py +71 -0
- statuspro_public_api_client/domain/order.py +87 -0
- statuspro_public_api_client/domain/status.py +30 -0
- statuspro_public_api_client/errors.py +16 -0
- statuspro_public_api_client/helpers/__init__.py +21 -0
- statuspro_public_api_client/helpers/base.py +26 -0
- statuspro_public_api_client/helpers/orders.py +78 -0
- statuspro_public_api_client/helpers/statuses.py +37 -0
- statuspro_public_api_client/log_setup.py +99 -0
- statuspro_public_api_client/models/__init__.py +53 -0
- statuspro_public_api_client/models/add_order_comment_request.py +68 -0
- statuspro_public_api_client/models/bulk_status_update_request.py +124 -0
- statuspro_public_api_client/models/bulk_status_update_response.py +72 -0
- statuspro_public_api_client/models/customer.py +74 -0
- statuspro_public_api_client/models/error_response.py +58 -0
- statuspro_public_api_client/models/history_item.py +171 -0
- statuspro_public_api_client/models/list_orders_financial_status_item.py +15 -0
- statuspro_public_api_client/models/list_orders_fulfillment_status_item.py +11 -0
- statuspro_public_api_client/models/locale_translation.py +66 -0
- statuspro_public_api_client/models/mail_log.py +82 -0
- statuspro_public_api_client/models/message_response.py +58 -0
- statuspro_public_api_client/models/order_list_item.py +180 -0
- statuspro_public_api_client/models/order_list_meta.py +120 -0
- statuspro_public_api_client/models/order_list_response.py +81 -0
- statuspro_public_api_client/models/order_response.py +220 -0
- statuspro_public_api_client/models/progress_timeline_item.py +93 -0
- statuspro_public_api_client/models/set_due_date_request.py +95 -0
- statuspro_public_api_client/models/status.py +190 -0
- statuspro_public_api_client/models/status_definition.py +82 -0
- statuspro_public_api_client/models/status_translations.py +62 -0
- statuspro_public_api_client/models/update_order_status_request.py +92 -0
- statuspro_public_api_client/models/validation_error_response.py +81 -0
- statuspro_public_api_client/models/validation_error_response_errors.py +54 -0
- statuspro_public_api_client/models/viable_status.py +82 -0
- statuspro_public_api_client/models_pydantic/__init__.py +122 -0
- statuspro_public_api_client/models_pydantic/_auto_registry.py +115 -0
- statuspro_public_api_client/models_pydantic/_base.py +349 -0
- statuspro_public_api_client/models_pydantic/_generated/__init__.py +53 -0
- statuspro_public_api_client/models_pydantic/_generated/errors.py +24 -0
- statuspro_public_api_client/models_pydantic/_generated/orders.py +136 -0
- statuspro_public_api_client/models_pydantic/_generated/statuses.py +25 -0
- statuspro_public_api_client/models_pydantic/_registry.py +171 -0
- statuspro_public_api_client/models_pydantic/converters.py +184 -0
- statuspro_public_api_client/py.typed +1 -0
- statuspro_public_api_client/statuspro-openapi.yaml +859 -0
- statuspro_public_api_client/statuspro_client.py +1156 -0
- statuspro_public_api_client/utils.py +290 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"""Registry for mapping between attrs and Pydantic model classes.
|
|
2
|
+
|
|
3
|
+
This module provides a registry that maps attrs model classes to their
|
|
4
|
+
corresponding Pydantic model classes and vice versa. This is essential
|
|
5
|
+
for the bi-directional conversion functionality in _base.py.
|
|
6
|
+
|
|
7
|
+
The registry is populated automatically when models are generated,
|
|
8
|
+
via the _auto_registry.py module.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from typing import TYPE_CHECKING, Any
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from ._base import StatusProPydanticBase
|
|
17
|
+
|
|
18
|
+
# Registries mapping class names and types
|
|
19
|
+
_attrs_to_pydantic: dict[type, type[StatusProPydanticBase]] = {}
|
|
20
|
+
_pydantic_to_attrs: dict[type[StatusProPydanticBase], type] = {}
|
|
21
|
+
_attrs_name_to_class: dict[str, type] = {}
|
|
22
|
+
_pydantic_name_to_class: dict[str, type[StatusProPydanticBase]] = {}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def register(attrs_class: type, pydantic_class: type[StatusProPydanticBase]) -> None:
|
|
26
|
+
"""Register a mapping between an attrs class and a Pydantic class.
|
|
27
|
+
|
|
28
|
+
This function should be called for each model pair after generation.
|
|
29
|
+
It enables the from_attrs() and to_attrs() conversion methods to work.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
attrs_class: The attrs model class (from models/).
|
|
33
|
+
pydantic_class: The corresponding Pydantic model class.
|
|
34
|
+
|
|
35
|
+
Raises:
|
|
36
|
+
TypeError: If attrs_class is not an attrs class or pydantic_class is not
|
|
37
|
+
a subclass of StatusProPydanticBase.
|
|
38
|
+
ValueError: If the classes are already registered with different mappings.
|
|
39
|
+
"""
|
|
40
|
+
# Import StatusProPydanticBase at runtime to avoid circular imports
|
|
41
|
+
from ._base import StatusProPydanticBase as BaseClass
|
|
42
|
+
|
|
43
|
+
# Validate attrs_class has attrs attributes
|
|
44
|
+
if not hasattr(attrs_class, "__attrs_attrs__"):
|
|
45
|
+
msg = f"{attrs_class.__name__} is not an attrs class (missing __attrs_attrs__)"
|
|
46
|
+
raise TypeError(msg)
|
|
47
|
+
|
|
48
|
+
# Validate pydantic_class is a proper Pydantic model
|
|
49
|
+
if not isinstance(pydantic_class, type) or not issubclass(
|
|
50
|
+
pydantic_class, BaseClass
|
|
51
|
+
):
|
|
52
|
+
msg = f"{pydantic_class.__name__} is not a subclass of StatusProPydanticBase"
|
|
53
|
+
raise TypeError(msg)
|
|
54
|
+
|
|
55
|
+
# Check for conflicting registrations
|
|
56
|
+
existing_pydantic = _attrs_to_pydantic.get(attrs_class)
|
|
57
|
+
if existing_pydantic is not None and existing_pydantic is not pydantic_class:
|
|
58
|
+
msg = (
|
|
59
|
+
f"{attrs_class.__name__} is already registered to "
|
|
60
|
+
f"{existing_pydantic.__name__}, cannot register to {pydantic_class.__name__}"
|
|
61
|
+
)
|
|
62
|
+
raise ValueError(msg)
|
|
63
|
+
|
|
64
|
+
existing_attrs = _pydantic_to_attrs.get(pydantic_class)
|
|
65
|
+
if existing_attrs is not None and existing_attrs is not attrs_class:
|
|
66
|
+
msg = (
|
|
67
|
+
f"{pydantic_class.__name__} is already registered to "
|
|
68
|
+
f"{existing_attrs.__name__}, cannot register to {attrs_class.__name__}"
|
|
69
|
+
)
|
|
70
|
+
raise ValueError(msg)
|
|
71
|
+
|
|
72
|
+
_attrs_to_pydantic[attrs_class] = pydantic_class
|
|
73
|
+
_pydantic_to_attrs[pydantic_class] = attrs_class
|
|
74
|
+
_attrs_name_to_class[attrs_class.__name__] = attrs_class
|
|
75
|
+
_pydantic_name_to_class[pydantic_class.__name__] = pydantic_class
|
|
76
|
+
|
|
77
|
+
# Also set the _attrs_model class variable on the pydantic class
|
|
78
|
+
pydantic_class._attrs_model = attrs_class
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def get_pydantic_class(attrs_class: type) -> type[StatusProPydanticBase] | None:
|
|
82
|
+
"""Get the Pydantic class for a given attrs class.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
attrs_class: An attrs model class.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
The corresponding Pydantic model class, or None if not registered.
|
|
89
|
+
"""
|
|
90
|
+
return _attrs_to_pydantic.get(attrs_class)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def get_attrs_class(pydantic_class: type[StatusProPydanticBase]) -> type | None:
|
|
94
|
+
"""Get the attrs class for a given Pydantic class.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
pydantic_class: A Pydantic model class.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
The corresponding attrs model class, or None if not registered.
|
|
101
|
+
"""
|
|
102
|
+
return _pydantic_to_attrs.get(pydantic_class)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def get_pydantic_class_by_name(name: str) -> type[StatusProPydanticBase] | None:
|
|
106
|
+
"""Get a Pydantic class by its name.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
name: The class name to look up.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
The Pydantic model class, or None if not found.
|
|
113
|
+
"""
|
|
114
|
+
return _pydantic_name_to_class.get(name)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def get_attrs_class_by_name(name: str) -> type | None:
|
|
118
|
+
"""Get an attrs class by its name.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
name: The class name to look up.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
The attrs model class, or None if not found.
|
|
125
|
+
"""
|
|
126
|
+
return _attrs_name_to_class.get(name)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def list_registered_models() -> list[tuple[str, str]]:
|
|
130
|
+
"""List all registered model pairs.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
List of (attrs_class_name, pydantic_class_name) tuples.
|
|
134
|
+
"""
|
|
135
|
+
return [
|
|
136
|
+
(attrs_cls.__name__, pydantic_cls.__name__)
|
|
137
|
+
for attrs_cls, pydantic_cls in _attrs_to_pydantic.items()
|
|
138
|
+
]
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def is_registered(model_class: type) -> bool:
|
|
142
|
+
"""Check if a model class is registered (either attrs or pydantic).
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
model_class: A model class to check.
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
True if the class is registered in either direction.
|
|
149
|
+
"""
|
|
150
|
+
return model_class in _attrs_to_pydantic or model_class in _pydantic_to_attrs
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def clear_registry() -> None:
|
|
154
|
+
"""Clear all registrations. Mainly for testing purposes."""
|
|
155
|
+
_attrs_to_pydantic.clear()
|
|
156
|
+
_pydantic_to_attrs.clear()
|
|
157
|
+
_attrs_name_to_class.clear()
|
|
158
|
+
_pydantic_name_to_class.clear()
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def get_registration_stats() -> dict[str, Any]:
|
|
162
|
+
"""Get statistics about the current registry state.
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
Dictionary with counts and other stats.
|
|
166
|
+
"""
|
|
167
|
+
return {
|
|
168
|
+
"total_pairs": len(_attrs_to_pydantic),
|
|
169
|
+
"attrs_classes": len(_attrs_name_to_class),
|
|
170
|
+
"pydantic_classes": len(_pydantic_name_to_class),
|
|
171
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""Batch conversion utilities for attrs <-> Pydantic model conversion.
|
|
2
|
+
|
|
3
|
+
This module provides convenience functions for converting API responses
|
|
4
|
+
and collections of models between attrs and Pydantic representations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import TYPE_CHECKING, TypeVar, overload
|
|
10
|
+
|
|
11
|
+
from . import _registry
|
|
12
|
+
from ._base import StatusProPydanticBase
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from collections.abc import Sequence
|
|
16
|
+
|
|
17
|
+
from ..client_types import Response
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
T = TypeVar("T", bound=StatusProPydanticBase)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@overload
|
|
24
|
+
def convert_response[T: StatusProPydanticBase](
|
|
25
|
+
response: Response[None],
|
|
26
|
+
pydantic_class: type[T],
|
|
27
|
+
) -> None: ...
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@overload
|
|
31
|
+
def convert_response[T: StatusProPydanticBase](
|
|
32
|
+
response: Response[list[object]],
|
|
33
|
+
pydantic_class: type[T],
|
|
34
|
+
) -> list[T]: ...
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@overload
|
|
38
|
+
def convert_response[T: StatusProPydanticBase](
|
|
39
|
+
response: Response[object],
|
|
40
|
+
pydantic_class: type[T],
|
|
41
|
+
) -> T: ...
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def convert_response[T: StatusProPydanticBase](
|
|
45
|
+
response: Response[object] | Response[list[object]] | Response[None],
|
|
46
|
+
pydantic_class: type[T],
|
|
47
|
+
) -> T | list[T] | None:
|
|
48
|
+
"""Convert an API response's parsed data to Pydantic models.
|
|
49
|
+
|
|
50
|
+
This is the recommended way to convert API responses when you want
|
|
51
|
+
Pydantic models instead of attrs models.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
response: The Response object from an API call.
|
|
55
|
+
pydantic_class: The Pydantic model class to convert to.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
- None if response.parsed is None
|
|
59
|
+
- A list of Pydantic models if response.parsed is a list
|
|
60
|
+
- A single Pydantic model otherwise
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
```python
|
|
64
|
+
from statuspro_public_api_client.api.product import get_all_products
|
|
65
|
+
from statuspro_public_api_client.models_pydantic import Product
|
|
66
|
+
from statuspro_public_api_client.models_pydantic.converters import (
|
|
67
|
+
convert_response,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
response = await get_all_products.asyncio_detailed(client=client)
|
|
71
|
+
products = convert_response(response, Product) # list[Product]
|
|
72
|
+
```
|
|
73
|
+
"""
|
|
74
|
+
if response.parsed is None:
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
if isinstance(response.parsed, list):
|
|
78
|
+
return batch_convert(response.parsed, pydantic_class)
|
|
79
|
+
|
|
80
|
+
return pydantic_class.from_attrs(response.parsed)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def batch_convert[T: StatusProPydanticBase](
|
|
84
|
+
attrs_objects: Sequence[object],
|
|
85
|
+
pydantic_class: type[T],
|
|
86
|
+
) -> list[T]:
|
|
87
|
+
"""Convert a list of attrs objects to Pydantic models.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
attrs_objects: A sequence of attrs model instances.
|
|
91
|
+
pydantic_class: The Pydantic model class to convert to.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
A list of Pydantic model instances.
|
|
95
|
+
|
|
96
|
+
Example:
|
|
97
|
+
```python
|
|
98
|
+
from statuspro_public_api_client.models_pydantic import Product
|
|
99
|
+
from statuspro_public_api_client.models_pydantic.converters import (
|
|
100
|
+
batch_convert,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
pydantic_products = batch_convert(attrs_products, Product)
|
|
104
|
+
```
|
|
105
|
+
"""
|
|
106
|
+
return [pydantic_class.from_attrs(obj) for obj in attrs_objects]
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def batch_convert_to_attrs(
|
|
110
|
+
pydantic_objects: Sequence[StatusProPydanticBase],
|
|
111
|
+
) -> list[object]:
|
|
112
|
+
"""Convert a list of Pydantic models to attrs objects.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
pydantic_objects: A sequence of Pydantic model instances.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
A list of attrs model instances.
|
|
119
|
+
|
|
120
|
+
Example:
|
|
121
|
+
```python
|
|
122
|
+
attrs_products = batch_convert_to_attrs(pydantic_products)
|
|
123
|
+
```
|
|
124
|
+
"""
|
|
125
|
+
return [obj.to_attrs() for obj in pydantic_objects]
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def to_pydantic(attrs_obj: object) -> StatusProPydanticBase | None:
|
|
129
|
+
"""Convert any registered attrs object to its Pydantic equivalent.
|
|
130
|
+
|
|
131
|
+
This function automatically looks up the correct Pydantic class
|
|
132
|
+
from the registry.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
attrs_obj: An attrs model instance.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
The corresponding Pydantic model instance, or None if the class
|
|
139
|
+
is not registered.
|
|
140
|
+
|
|
141
|
+
Example:
|
|
142
|
+
```python
|
|
143
|
+
from statuspro_public_api_client.models_pydantic.converters import (
|
|
144
|
+
to_pydantic,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
pydantic_product = to_pydantic(attrs_product)
|
|
148
|
+
```
|
|
149
|
+
"""
|
|
150
|
+
if attrs_obj is None:
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
pydantic_class = _registry.get_pydantic_class(type(attrs_obj))
|
|
154
|
+
if pydantic_class is None:
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
return pydantic_class.from_attrs(attrs_obj)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def to_attrs(pydantic_obj: StatusProPydanticBase) -> object | None:
|
|
161
|
+
"""Convert any registered Pydantic object to its attrs equivalent.
|
|
162
|
+
|
|
163
|
+
This is equivalent to calling pydantic_obj.to_attrs() but provides
|
|
164
|
+
a consistent functional interface.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
pydantic_obj: A Pydantic model instance.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
The corresponding attrs model instance.
|
|
171
|
+
|
|
172
|
+
Example:
|
|
173
|
+
```python
|
|
174
|
+
from statuspro_public_api_client.models_pydantic.converters import (
|
|
175
|
+
to_attrs,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
attrs_product = to_attrs(pydantic_product)
|
|
179
|
+
```
|
|
180
|
+
"""
|
|
181
|
+
if pydantic_obj is None:
|
|
182
|
+
return None
|
|
183
|
+
|
|
184
|
+
return pydantic_obj.to_attrs()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Marker file for PEP 561
|