catalystwan 0.41.2.dev4__py3-none-any.whl → 0.41.2.dev6__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.
catalystwan/exceptions.py CHANGED
@@ -216,3 +216,10 @@ class CatalystwanDeprecationWarning(DeprecationWarning):
216
216
  f" The public API SHOULD NOT be considered stable."
217
217
  )
218
218
  return message
219
+
220
+
221
+ class ParcelModelNotFound(CatalystwanException):
222
+ """Raised when there is no model matching parcelType field"""
223
+
224
+ def __init__(self, type_):
225
+ self.message = f"Cannot determine model class for parcel type: {type_}"
@@ -0,0 +1,54 @@
1
+ # Copyright 2025 Cisco Systems, Inc. and its affiliates
2
+ from typing import Literal, Union
3
+
4
+ import pytest
5
+ from pydantic import Field
6
+ from typing_extensions import Annotated
7
+
8
+ from catalystwan.api.configuration_groups.parcel import _ParcelBase
9
+ from catalystwan.exceptions import ParcelModelNotFound
10
+ from catalystwan.models.configuration.feature_profile.parcel import find_type, list_types
11
+ from catalystwan.models.configuration.feature_profile.sdwan.topology import (
12
+ AnyTopologyParcel,
13
+ CustomControlParcel,
14
+ HubSpokeParcel,
15
+ MeshParcel,
16
+ )
17
+
18
+
19
+ def test_list_types():
20
+ observed_types = list_types(AnyTopologyParcel)
21
+ assert set(observed_types) == {MeshParcel, HubSpokeParcel, CustomControlParcel}
22
+
23
+
24
+ def test_find_type():
25
+ observed_type = find_type("mesh", AnyTopologyParcel)
26
+ assert observed_type == MeshParcel
27
+
28
+
29
+ def test_find_type_raises_when_no_match():
30
+ with pytest.raises(ParcelModelNotFound):
31
+ find_type("unknown", AnyTopologyParcel)
32
+
33
+
34
+ def test_find_type_raises_for_bogus_param():
35
+ with pytest.raises(ParcelModelNotFound):
36
+ find_type("unknown", None)
37
+
38
+
39
+ def test_find_type_custom():
40
+ # Arrange
41
+ class CustomParcel(_ParcelBase):
42
+ type_: Literal["custom"] = Field(default="custom", exclude=True)
43
+
44
+ CustomUnion = Annotated[
45
+ Union[
46
+ MeshParcel,
47
+ CustomParcel,
48
+ ],
49
+ Field(discriminator="type_"),
50
+ ]
51
+ # Act
52
+ observed_type = find_type("custom", CustomUnion)
53
+ # Assert
54
+ assert observed_type == CustomParcel
@@ -1,11 +1,13 @@
1
1
  # Copyright 2024 Cisco Systems, Inc. and its affiliates
2
2
  from functools import lru_cache
3
- from typing import Generic, List, Literal, Optional, Sequence, TypeVar, Union, cast
3
+ from typing import Generic, List, Literal, Optional, Sequence, Type, TypeVar, Union, cast
4
4
  from uuid import UUID
5
5
 
6
6
  from pydantic import AliasChoices, BaseModel, ConfigDict, Field, model_validator
7
7
  from typing_extensions import Annotated
8
8
 
9
+ from catalystwan.api.configuration_groups.parcel import _ParcelBase
10
+ from catalystwan.exceptions import ParcelModelNotFound
9
11
  from catalystwan.models.configuration.feature_profile.sdwan.application_priority import AnyApplicationPriorityParcel
10
12
  from catalystwan.models.configuration.feature_profile.sdwan.cli import AnyCliParcel
11
13
  from catalystwan.models.configuration.feature_profile.sdwan.dns_security import AnyDnsSecurityParcel
@@ -160,6 +162,7 @@ AnyParcel = Annotated[
160
162
  ]
161
163
 
162
164
  T = TypeVar("T", bound=AnyParcel)
165
+ UT = TypeVar("UT", bound=_ParcelBase)
163
166
 
164
167
 
165
168
  class Parcel(BaseModel, Generic[T]):
@@ -227,12 +230,15 @@ class ParcelId(BaseModel):
227
230
 
228
231
 
229
232
  @lru_cache
230
- def list_types(any_union: T) -> Sequence[T]:
231
- return cast(Sequence[T], resolve_nested_base_model_unions(any_union))
233
+ def list_types(any_union: Type[UT]) -> Sequence[UT]:
234
+ return cast(Sequence[UT], resolve_nested_base_model_unions(any_union))
232
235
 
233
236
 
234
237
  @lru_cache
235
- def find_type(name: str, any_union: T) -> T:
238
+ def find_type(name: str, any_union: Type[UT]) -> UT:
236
239
  parcel_types = list_types(any_union)
237
- parcel_type = next(t for t in parcel_types if t._get_parcel_type() == name)
238
- return cast(T, parcel_type)
240
+ try:
241
+ parcel_type = next(t for t in parcel_types if t._get_parcel_type() == name)
242
+ except StopIteration:
243
+ raise ParcelModelNotFound(name)
244
+ return cast(UT, parcel_type)
@@ -259,7 +259,7 @@ class AppqoeParcel(_ParcelBase):
259
259
  virtual_application: Optional[List[VirtualApplication]] = Field(
260
260
  default=None, validation_alias=AliasPath("data", "virtualApplication")
261
261
  )
262
- appqoe_device_role: Global[str] = Field(
262
+ appqoe_device_role: Global[AppqoeDeviceRole] = Field(
263
263
  default=as_global("forwarder"), validation_alias=AliasPath("data", "appqoeDeviceRole")
264
264
  )
265
265
 
@@ -168,7 +168,7 @@ class IPv4RouteGatewayNextHop(BaseModel):
168
168
  class IPv4RouteGatewayNextHopWithTracker(BaseModel):
169
169
  model_config = ConfigDict(arbitrary_types_allowed=True, populate_by_name=True)
170
170
 
171
- address: Union[Variable, Global[str]]
171
+ address: Union[Variable, Global[str], Global[IPv4Address]]
172
172
  distance: Union[Variable, Global[int], Default[int]] = Default[int](value=1)
173
173
  tracker: Union[Global[UUID], Default[None]] = as_default(None)
174
174
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: catalystwan
3
- Version: 0.41.2.dev4
3
+ Version: 0.41.2.dev6
4
4
  Summary: Cisco Catalyst WAN SDK for Python
5
5
  Author: kagorski
6
6
  Author-email: kagorski@cisco.com
@@ -212,7 +212,7 @@ catalystwan/endpoints/tenant_management.py,sha256=c-kIRoS60aVklVPPrmbnW5kaiNgU23
212
212
  catalystwan/endpoints/tenant_migration.py,sha256=e6eIzRvlrnzUWqamKbWsYjX8drtB-GQKvhrJtX2VDKY,3649
213
213
  catalystwan/endpoints/troubleshooting_tools/device_connectivity.py,sha256=JkTZfebTwcambJsgjcJ8qxxBDE5XbUFyYpNqr9681DQ,3661
214
214
  catalystwan/endpoints/url_monitoring.py,sha256=ZySOjuCpIAZ4SIsah56yJ-uybYw0W9s6OjQp2FujN0g,802
215
- catalystwan/exceptions.py,sha256=vbUfR5qp1A0_Mr7WKyEzU5A6V8rJpaee128rjEp48UQ,6391
215
+ catalystwan/exceptions.py,sha256=MAtoZ9xrXmUgG-zMbdtChF7B2sHAgVlzv-euHOY1kKo,6620
216
216
  catalystwan/integration_tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
217
217
  catalystwan/integration_tests/base.py,sha256=0BcKgDZcGjdPH2316C-1Se4FUeAtdrNXdkUVp_aXEZc,2367
218
218
  catalystwan/integration_tests/feature_profile/sdwan/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -231,6 +231,7 @@ catalystwan/integration_tests/feature_profile/sdwan/test_system.py,sha256=ab6fG7
231
231
  catalystwan/integration_tests/feature_profile/sdwan/test_tracker.py,sha256=GnIEHmUoIZObtBK-YvjYYtDsFnGSDpAVwi4rk9-r7XE,5117
232
232
  catalystwan/integration_tests/feature_profile/sdwan/test_transport.py,sha256=xRS880JCUD06xL_EaHKNylvaXB9wRHqUYsORhU2MYus,78923
233
233
  catalystwan/integration_tests/feature_profile/sdwan/topology/test_topology.py,sha256=2vsAd0pk3wcfo8wFTRttnw4gjSPJi1KFfFCu5lGAiJQ,4340
234
+ catalystwan/integration_tests/feature_profile/test_parcel.py,sha256=4dqt5IP39lJ6vTsx3X7OdAHpYdbsIlDdpASFAM6d87Y,1517
234
235
  catalystwan/integration_tests/profile_builder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
235
236
  catalystwan/integration_tests/profile_builder/test_pb_service.py,sha256=WO6VVA7kNXesyGtk67e0lMDZBd4Z8wB7espBh0TzUTA,9420
236
237
  catalystwan/integration_tests/profile_builder/test_pb_transport.py,sha256=QQ5f1q6OV9dIyRQy1lb3Wp9beIKaWDaDLnNoGm4XY6A,10376
@@ -245,7 +246,7 @@ catalystwan/models/configuration/common.py,sha256=2X9gj5awWPKtLPFgWfxhkRrMoX22t1
245
246
  catalystwan/models/configuration/feature_profile/README.md,sha256=IQMhbnEAbLtotT80aL2emekH-ou8CqR0WSYXhZXilJw,10050
246
247
  catalystwan/models/configuration/feature_profile/builder.py,sha256=GDqK7ZxnWHTKWHRw13xvD1aDl60xe6gFsP_B9z5T8a8,663
247
248
  catalystwan/models/configuration/feature_profile/common.py,sha256=a5xohaoXzAewtqYYdk2GJy7B-rxxlxYatlP2WZ1eZqY,30423
248
- catalystwan/models/configuration/feature_profile/parcel.py,sha256=c2pSHjEVA_PeqBlrqYVdB4I4L5KOVFqR4UrSXTX1uoM,7319
249
+ catalystwan/models/configuration/feature_profile/parcel.py,sha256=k3IyNVzjtDrTjUEBYvzQeQWeqNhRNk2tXDYqbQXWX2o,7583
249
250
  catalystwan/models/configuration/feature_profile/sdwan/acl/__init__.py,sha256=-AXvVMLyaAYWUnwzTT_mvar37ZpO2vNRy_ZsUIA5dGo,324
250
251
  catalystwan/models/configuration/feature_profile/sdwan/acl/ipv4acl.py,sha256=HpiY0DCZWE9EHCbMbyIJ-iRharSRO3IGcSV3kWbMXjY,12167
251
252
  catalystwan/models/configuration/feature_profile/sdwan/acl/ipv6acl.py,sha256=MRtDNb2v1TNNf3yijLFlzL3H1KxHOquPmww1V9ZCacI,12969
@@ -314,7 +315,7 @@ catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py,sha256=4vX
314
315
  catalystwan/models/configuration/feature_profile/sdwan/routing/ospf.py,sha256=hfsfL9Fy4q7eUybhSzPDGTFgdlK1VO3zPUy1aNOOCIc,7647
315
316
  catalystwan/models/configuration/feature_profile/sdwan/routing/ospfv3.py,sha256=KW0UgMPt08OxLbX4JoShNby83HCMhlHICRLLW8pYinQ,13268
316
317
  catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py,sha256=AzPWWFozmwg5nzwEj-bYhg2HTeJJ8FFPQHmvyxDvSnQ,2378
317
- catalystwan/models/configuration/feature_profile/sdwan/service/appqoe.py,sha256=4V5BWUYDBJEQJ7OWZRXe9Qasw4VzD52_XqmMIUv6cK8,10210
318
+ catalystwan/models/configuration/feature_profile/sdwan/service/appqoe.py,sha256=6_diZuOtJnq0x6QFuwHQ3IgSmV5a6S-Yql7uN-JlF8c,10223
318
319
  catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py,sha256=XCYUektYRLZaIzJAiAuSeuKg2DdAYio38t0niN8CkhA,5289
319
320
  catalystwan/models/configuration/feature_profile/sdwan/service/dual_router_ha.py,sha256=MMwnBKBth3E91EYCPLtGJqwQYilZPWelGF6KLJmtOPw,1134
320
321
  catalystwan/models/configuration/feature_profile/sdwan/service/eigrp.py,sha256=d02hMwUFq5ycoknQci0SAgRlxuiYh0kSKDBxOzn-ves,4075
@@ -324,7 +325,7 @@ catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py,sha256
324
325
  catalystwan/models/configuration/feature_profile/sdwan/service/lan/ipsec.py,sha256=jFwQK-xLl_l9aahCX326wRIcEobElfdFxeZY0ofXD5w,7043
325
326
  catalystwan/models/configuration/feature_profile/sdwan/service/lan/multilink.py,sha256=EKUIQDq40P01irYFWZ1fACFK6R8AusT6s96bH4qHWUg,5403
326
327
  catalystwan/models/configuration/feature_profile/sdwan/service/lan/svi.py,sha256=B9LmnmTNHUQUVYI7071Z2j4s5pJN9SUfWQEuNb1czV8,9114
327
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py,sha256=hM07iABYdTokFPNlwOz37ZBpta3BfX4cOdEpY9s-BBQ,24210
328
+ catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py,sha256=3CfGxWQ9R9YHRJpLHzdtpjGVoNqz2VwrioCXdzi5A7k,24231
328
329
  catalystwan/models/configuration/feature_profile/sdwan/service/multicast.py,sha256=DXvUUsPVNCmkN-YLqQArP9NKjL444UPfoZavC87i2fw,10821
329
330
  catalystwan/models/configuration/feature_profile/sdwan/service/object_tracker.py,sha256=WeKWXT54cyf5r9S-PZLe_M8b2iXgRNwujJVLxxeNnsw,3291
330
331
  catalystwan/models/configuration/feature_profile/sdwan/service/route_policy.py,sha256=JSThUK1D3PsCrJCwDL4vEkiPn01cAkBc9XX6IwzJuAY,15765
@@ -630,7 +631,7 @@ catalystwan/version.py,sha256=X5yIMPIrWPbdoF9eJfwxfjcvWr7JMfWQF98hQhlGB5I,3032
630
631
  catalystwan/vmanage_auth.py,sha256=UZ57lTihsLsXw4AdU7Vn8XuY1jo3732Vc9WuFoHSiiQ,10780
631
632
  catalystwan/workflows/backup_restore_device_templates.py,sha256=BoR2KlRbpCI6RxIWG7j7tucaLpw5w3ESN20dLhsrZFY,19796
632
633
  catalystwan/workflows/tenant_migration.py,sha256=4KLbqUwH4gEegE92PCGfRd226eZd_crCUpaYUWoGXDI,9790
633
- catalystwan-0.41.2.dev4.dist-info/LICENSE,sha256=97ROi91Vxrj_Jio2v8FI9E8-y6x2uYdQRaFlrEbVjkc,11375
634
- catalystwan-0.41.2.dev4.dist-info/METADATA,sha256=ZkC0Yt4J1N7cnoV_D_9X0FMsVLZEq2rhO1v7FFtfQ9M,21275
635
- catalystwan-0.41.2.dev4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
636
- catalystwan-0.41.2.dev4.dist-info/RECORD,,
634
+ catalystwan-0.41.2.dev6.dist-info/LICENSE,sha256=97ROi91Vxrj_Jio2v8FI9E8-y6x2uYdQRaFlrEbVjkc,11375
635
+ catalystwan-0.41.2.dev6.dist-info/METADATA,sha256=_U2izirHEsCyVz8rO2eGD5-YkcT7hmWw8DCCif5qRqQ,21275
636
+ catalystwan-0.41.2.dev6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
637
+ catalystwan-0.41.2.dev6.dist-info/RECORD,,