catalystwan 0.40.1.dev7__py3-none-any.whl → 2.0.0a0__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/core/__init__.py +2 -0
- catalystwan/core/abstractions.py +26 -0
- catalystwan/{apigw_auth.py → core/apigw_auth.py} +29 -14
- catalystwan/core/client.py +71 -0
- catalystwan/core/encoder.py +12 -0
- catalystwan/{exceptions.py → core/exceptions.py} +29 -9
- catalystwan/core/loader.py +37 -0
- catalystwan/{__init__.py → core/metadata.py} +9 -22
- catalystwan/core/models/deserialize.py +203 -0
- catalystwan/core/models/serialize.py +137 -0
- catalystwan/core/request_adapter.py +246 -0
- catalystwan/{request_limiter.py → core/request_limiter.py} +1 -2
- catalystwan/{response.py → core/response.py} +38 -85
- catalystwan/{session.py → core/session.py} +84 -101
- catalystwan/core/types.py +33 -0
- catalystwan/{version.py → core/version.py} +3 -5
- catalystwan/{vmanage_auth.py → core/vmanage_auth.py} +46 -21
- catalystwan-2.0.0a0.dist-info/METADATA +327 -0
- catalystwan-2.0.0a0.dist-info/RECORD +24 -0
- {catalystwan-0.40.1.dev7.dist-info → catalystwan-2.0.0a0.dist-info}/WHEEL +2 -1
- catalystwan-2.0.0a0.dist-info/top_level.txt +1 -0
- catalystwan/abstractions.py +0 -77
- catalystwan/api/admin_tech_api.py +0 -176
- catalystwan/api/administration.py +0 -434
- catalystwan/api/alarms_api.py +0 -186
- catalystwan/api/api_container.py +0 -73
- catalystwan/api/basic_api.py +0 -338
- catalystwan/api/builders/__init__.py +0 -14
- catalystwan/api/builders/feature_profiles/application_priority.py +0 -58
- catalystwan/api/builders/feature_profiles/builder_factory.py +0 -59
- catalystwan/api/builders/feature_profiles/cli.py +0 -76
- catalystwan/api/builders/feature_profiles/other.py +0 -79
- catalystwan/api/builders/feature_profiles/report.py +0 -137
- catalystwan/api/builders/feature_profiles/service.py +0 -213
- catalystwan/api/builders/feature_profiles/system.py +0 -80
- catalystwan/api/builders/feature_profiles/transport.py +0 -214
- catalystwan/api/builders/feature_profiles/uc_voice.py +0 -287
- catalystwan/api/config_device_inventory_api.py +0 -58
- catalystwan/api/config_group_api.py +0 -150
- catalystwan/api/configuration_groups/parcel.py +0 -206
- catalystwan/api/dashboard_api.py +0 -215
- catalystwan/api/device_action_api.py +0 -216
- catalystwan/api/feature_profile_api.py +0 -2401
- catalystwan/api/logs_api.py +0 -63
- catalystwan/api/monitoring_status_api.py +0 -76
- catalystwan/api/mtt_aaa_api.py +0 -197
- catalystwan/api/omp_api.py +0 -124
- catalystwan/api/packet_capture_api.py +0 -152
- catalystwan/api/parcel_api.py +0 -42
- catalystwan/api/partition_manager_api.py +0 -143
- catalystwan/api/policy_api.py +0 -1163
- catalystwan/api/resource_pool_api.py +0 -74
- catalystwan/api/software_action_api.py +0 -269
- catalystwan/api/speedtest_api.py +0 -153
- catalystwan/api/task_status_api.py +0 -171
- catalystwan/api/template_api.py +0 -761
- catalystwan/api/templates/README.md +0 -101
- catalystwan/api/templates/bool_str.py +0 -6
- catalystwan/api/templates/cli_template.py +0 -236
- catalystwan/api/templates/device_template/device_template.py +0 -181
- catalystwan/api/templates/device_variable.py +0 -7
- catalystwan/api/templates/feature_template.py +0 -133
- catalystwan/api/templates/feature_template_field.py +0 -175
- catalystwan/api/templates/feature_template_payload.py +0 -17
- catalystwan/api/templates/models/aaa_model.py +0 -387
- catalystwan/api/templates/models/cisco_aaa_model.py +0 -331
- catalystwan/api/templates/models/cisco_banner_model.py +0 -27
- catalystwan/api/templates/models/cisco_bfd_model.py +0 -61
- catalystwan/api/templates/models/cisco_bgp_model.py +0 -510
- catalystwan/api/templates/models/cisco_logging_model.py +0 -122
- catalystwan/api/templates/models/cisco_ntp_model.py +0 -60
- catalystwan/api/templates/models/cisco_omp_model.py +0 -121
- catalystwan/api/templates/models/cisco_ospf.py +0 -241
- catalystwan/api/templates/models/cisco_ospfv3.py +0 -498
- catalystwan/api/templates/models/cisco_secure_internet_gateway.py +0 -385
- catalystwan/api/templates/models/cisco_snmp_model.py +0 -102
- catalystwan/api/templates/models/cisco_system.py +0 -318
- catalystwan/api/templates/models/cisco_vpn_interface_model.py +0 -822
- catalystwan/api/templates/models/cisco_vpn_model.py +0 -603
- catalystwan/api/templates/models/cli_template.py +0 -18
- catalystwan/api/templates/models/omp_vsmart_model.py +0 -73
- catalystwan/api/templates/models/security_vsmart_model.py +0 -28
- catalystwan/api/templates/models/supported.py +0 -42
- catalystwan/api/templates/models/system_vsmart_model.py +0 -182
- catalystwan/api/templates/models/vpn_vsmart_interface_model.py +0 -198
- catalystwan/api/templates/models/vpn_vsmart_model.py +0 -124
- catalystwan/api/templates/payloads/aaa/aaa_model.py +0 -91
- catalystwan/api/templates/payloads/aaa/feature/aaa.json.j2 +0 -373
- catalystwan/api/templates/payloads/aaa/feature/accounting.json.j2 +0 -40
- catalystwan/api/templates/payloads/aaa/feature/radius.json.j2 +0 -107
- catalystwan/api/templates/payloads/aaa/feature/tacacs.json.j2 +0 -95
- catalystwan/api/templates/payloads/aaa/feature/user.json.j2 +0 -60
- catalystwan/api/templates/payloads/cisco_vpn/cisco_vpn_model.py +0 -92
- catalystwan/api/templates/payloads/cisco_vpn/feature/cisco_vpn.json.j2 +0 -224
- catalystwan/api/templates/payloads/cisco_vpn/feature/dns.json.j2 +0 -86
- catalystwan/api/templates/payloads/cisco_vpn/feature/ipv4route.json.j2 +0 -59
- catalystwan/api/templates/payloads/cisco_vpn/feature/ipv6route.json.j2 +0 -58
- catalystwan/api/templates/payloads/cisco_vpn/feature/mapping.json.j2 +0 -24
- catalystwan/api/templates/payloads/tenant/tenant.json.j2 +0 -127
- catalystwan/api/templates/payloads/tenant/tenant_model.py +0 -43
- catalystwan/api/tenant_backup_restore_api.py +0 -154
- catalystwan/api/tenant_management_api.py +0 -127
- catalystwan/api/tenant_migration_api.py +0 -121
- catalystwan/api/versions_utils.py +0 -414
- catalystwan/api/virtual_image_action_api.py +0 -200
- catalystwan/dataclasses.py +0 -493
- catalystwan/endpoints/__init__.py +0 -606
- catalystwan/endpoints/administration_user_and_group.py +0 -341
- catalystwan/endpoints/api_gateway.py +0 -24
- catalystwan/endpoints/certificate_management_device.py +0 -137
- catalystwan/endpoints/certificate_management_vmanage.py +0 -48
- catalystwan/endpoints/client.py +0 -96
- catalystwan/endpoints/cluster_management.py +0 -130
- catalystwan/endpoints/configuration/device/software_update.py +0 -31
- catalystwan/endpoints/configuration/disaster_recovery.py +0 -305
- catalystwan/endpoints/configuration/feature_profile/sdwan/application_priority.py +0 -107
- catalystwan/endpoints/configuration/feature_profile/sdwan/cli.py +0 -60
- catalystwan/endpoints/configuration/feature_profile/sdwan/dns_security.py +0 -83
- catalystwan/endpoints/configuration/feature_profile/sdwan/embedded_security.py +0 -88
- catalystwan/endpoints/configuration/feature_profile/sdwan/other.py +0 -62
- catalystwan/endpoints/configuration/feature_profile/sdwan/policy_object.py +0 -105
- catalystwan/endpoints/configuration/feature_profile/sdwan/service.py +0 -137
- catalystwan/endpoints/configuration/feature_profile/sdwan/sig_security.py +0 -88
- catalystwan/endpoints/configuration/feature_profile/sdwan/system.py +0 -205
- catalystwan/endpoints/configuration/feature_profile/sdwan/topology.py +0 -93
- catalystwan/endpoints/configuration/feature_profile/sdwan/transport.py +0 -214
- catalystwan/endpoints/configuration/feature_profile/sdwan/uc_voice.py +0 -77
- catalystwan/endpoints/configuration/network_hierarchy.py +0 -32
- catalystwan/endpoints/configuration/policy/abstractions.py +0 -49
- catalystwan/endpoints/configuration/policy/definition/access_control_list.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/access_control_list_ipv6.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/aip.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/amp.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/app_route.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/cflowd.py +0 -46
- catalystwan/endpoints/configuration/policy/definition/control.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/device_access.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/device_access_ipv6.py +0 -59
- catalystwan/endpoints/configuration/policy/definition/dial_peer.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/dns_security.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/fxo_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/fxs_did_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/fxs_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/hub_and_spoke.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/intrusion_prevention.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/mesh.py +0 -53
- catalystwan/endpoints/configuration/policy/definition/pri_isdn_port.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/qos_map.py +0 -53
- catalystwan/endpoints/configuration/policy/definition/rewrite.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/route_policy.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/rule_set.py +0 -53
- catalystwan/endpoints/configuration/policy/definition/security_group.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/srst_phone_profile.py +0 -59
- catalystwan/endpoints/configuration/policy/definition/ssl_decryption.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/ssl_decryption_utd_profile.py +0 -52
- catalystwan/endpoints/configuration/policy/definition/traffic_data.py +0 -58
- catalystwan/endpoints/configuration/policy/definition/url_filtering.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/vpn_membership.py +0 -57
- catalystwan/endpoints/configuration/policy/definition/vpn_qos_map.py +0 -50
- catalystwan/endpoints/configuration/policy/definition/zone_based_firewall.py +0 -57
- catalystwan/endpoints/configuration/policy/list/app.py +0 -48
- catalystwan/endpoints/configuration/policy/list/app_probe.py +0 -52
- catalystwan/endpoints/configuration/policy/list/as_path.py +0 -48
- catalystwan/endpoints/configuration/policy/list/class_map.py +0 -48
- catalystwan/endpoints/configuration/policy/list/color.py +0 -48
- catalystwan/endpoints/configuration/policy/list/community.py +0 -48
- catalystwan/endpoints/configuration/policy/list/data_ipv6_prefix.py +0 -52
- catalystwan/endpoints/configuration/policy/list/data_prefix.py +0 -48
- catalystwan/endpoints/configuration/policy/list/expanded_community.py +0 -52
- catalystwan/endpoints/configuration/policy/list/extended_community.py +0 -52
- catalystwan/endpoints/configuration/policy/list/fax_protocol.py +0 -48
- catalystwan/endpoints/configuration/policy/list/fqdn.py +0 -48
- catalystwan/endpoints/configuration/policy/list/geo_location.py +0 -48
- catalystwan/endpoints/configuration/policy/list/identity.py +0 -48
- catalystwan/endpoints/configuration/policy/list/ips_signature.py +0 -52
- catalystwan/endpoints/configuration/policy/list/ipv6_prefix.py +0 -48
- catalystwan/endpoints/configuration/policy/list/local_app.py +0 -48
- catalystwan/endpoints/configuration/policy/list/local_domain.py +0 -48
- catalystwan/endpoints/configuration/policy/list/media_profile.py +0 -52
- catalystwan/endpoints/configuration/policy/list/mirror.py +0 -48
- catalystwan/endpoints/configuration/policy/list/modem_pass_through.py +0 -52
- catalystwan/endpoints/configuration/policy/list/policer.py +0 -48
- catalystwan/endpoints/configuration/policy/list/port.py +0 -48
- catalystwan/endpoints/configuration/policy/list/preferred_color_group.py +0 -52
- catalystwan/endpoints/configuration/policy/list/prefix.py +0 -49
- catalystwan/endpoints/configuration/policy/list/protocol_name.py +0 -52
- catalystwan/endpoints/configuration/policy/list/region.py +0 -47
- catalystwan/endpoints/configuration/policy/list/scalable_group_tag.py +0 -52
- catalystwan/endpoints/configuration/policy/list/site.py +0 -52
- catalystwan/endpoints/configuration/policy/list/sla.py +0 -48
- catalystwan/endpoints/configuration/policy/list/supervisory_disconnect.py +0 -52
- catalystwan/endpoints/configuration/policy/list/threat_grid_api_key.py +0 -52
- catalystwan/endpoints/configuration/policy/list/tloc.py +0 -48
- catalystwan/endpoints/configuration/policy/list/translation_profile.py +0 -52
- catalystwan/endpoints/configuration/policy/list/translation_rules.py +0 -52
- catalystwan/endpoints/configuration/policy/list/trunkgroup.py +0 -48
- catalystwan/endpoints/configuration/policy/list/umbrella_data.py +0 -52
- catalystwan/endpoints/configuration/policy/list/url_allow_list.py +0 -48
- catalystwan/endpoints/configuration/policy/list/url_block_list.py +0 -48
- catalystwan/endpoints/configuration/policy/list/vpn.py +0 -50
- catalystwan/endpoints/configuration/policy/list/zone.py +0 -48
- catalystwan/endpoints/configuration/policy/security_template.py +0 -55
- catalystwan/endpoints/configuration/policy/vedge_template.py +0 -52
- catalystwan/endpoints/configuration/policy/voice_template.py +0 -39
- catalystwan/endpoints/configuration/policy/vsmart_template.py +0 -79
- catalystwan/endpoints/configuration/policy_group.py +0 -30
- catalystwan/endpoints/configuration/software_actions.py +0 -201
- catalystwan/endpoints/configuration/topology_group.py +0 -51
- catalystwan/endpoints/configuration_dashboard_status.py +0 -127
- catalystwan/endpoints/configuration_device_actions.py +0 -385
- catalystwan/endpoints/configuration_device_inventory.py +0 -309
- catalystwan/endpoints/configuration_device_template.py +0 -39
- catalystwan/endpoints/configuration_feature_profile.py +0 -135
- catalystwan/endpoints/configuration_general_template.py +0 -31
- catalystwan/endpoints/configuration_group.py +0 -197
- catalystwan/endpoints/configuration_settings.py +0 -749
- catalystwan/endpoints/configuration_template_master.py +0 -48
- catalystwan/endpoints/endpoints_container.py +0 -279
- catalystwan/endpoints/misc.py +0 -21
- catalystwan/endpoints/monitoring/device_details.py +0 -246
- catalystwan/endpoints/monitoring/security_policy.py +0 -12
- catalystwan/endpoints/monitoring/server_info.py +0 -12
- catalystwan/endpoints/monitoring/status.py +0 -76
- catalystwan/endpoints/real_time_monitoring/reboot_history.py +0 -35
- catalystwan/endpoints/sdavc_cloud_connector.py +0 -43
- catalystwan/endpoints/tenant_backup_restore.py +0 -40
- catalystwan/endpoints/tenant_management.py +0 -215
- catalystwan/endpoints/tenant_migration.py +0 -102
- catalystwan/endpoints/troubleshooting_tools/device_connectivity.py +0 -128
- catalystwan/endpoints/url_monitoring.py +0 -26
- catalystwan/integration_tests/__init__.py +0 -0
- catalystwan/integration_tests/base.py +0 -81
- catalystwan/integration_tests/feature_profile/sdwan/__init__.py +0 -0
- catalystwan/integration_tests/feature_profile/sdwan/policy/__init__.py +0 -0
- catalystwan/integration_tests/feature_profile/sdwan/policy/base.py +0 -33
- catalystwan/integration_tests/feature_profile/sdwan/policy/test_extended_community.py +0 -33
- catalystwan/integration_tests/feature_profile/sdwan/policy/test_security_app_list.py +0 -32
- catalystwan/integration_tests/feature_profile/sdwan/test_application_priority.py +0 -433
- catalystwan/integration_tests/feature_profile/sdwan/test_cli.py +0 -54
- catalystwan/integration_tests/feature_profile/sdwan/test_dns_security.py +0 -106
- catalystwan/integration_tests/feature_profile/sdwan/test_other.py +0 -49
- catalystwan/integration_tests/feature_profile/sdwan/test_service.py +0 -1078
- catalystwan/integration_tests/feature_profile/sdwan/test_sig_security.py +0 -322
- catalystwan/integration_tests/feature_profile/sdwan/test_ssl_decryption.py +0 -85
- catalystwan/integration_tests/feature_profile/sdwan/test_system.py +0 -368
- catalystwan/integration_tests/feature_profile/sdwan/test_transport.py +0 -1700
- catalystwan/integration_tests/feature_profile/sdwan/topology/test_topology.py +0 -93
- catalystwan/integration_tests/profile_builder/__init__.py +0 -0
- catalystwan/integration_tests/profile_builder/test_pb_service.py +0 -78
- catalystwan/integration_tests/profile_builder/test_pb_transport.py +0 -56
- catalystwan/integration_tests/profile_builder/test_pb_uc_voice.py +0 -277
- catalystwan/integration_tests/test_data/__init__.py +0 -117
- catalystwan/integration_tests/test_find_template_values.py +0 -38
- catalystwan/integration_tests/test_network_hierarchy.py +0 -82
- catalystwan/integration_tests/test_settings.py +0 -30
- catalystwan/logging.conf +0 -37
- catalystwan/models/common.py +0 -1508
- catalystwan/models/configuration/common.py +0 -11
- catalystwan/models/configuration/feature_profile/README.md +0 -344
- catalystwan/models/configuration/feature_profile/builder.py +0 -22
- catalystwan/models/configuration/feature_profile/common.py +0 -749
- catalystwan/models/configuration/feature_profile/parcel.py +0 -232
- catalystwan/models/configuration/feature_profile/sdwan/acl/__init__.py +0 -13
- catalystwan/models/configuration/feature_profile/sdwan/acl/ipv4acl.py +0 -298
- catalystwan/models/configuration/feature_profile/sdwan/acl/ipv6acl.py +0 -344
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/__init__.py +0 -215
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/policy_settings.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/qos_policy.py +0 -102
- catalystwan/models/configuration/feature_profile/sdwan/application_priority/traffic_policy.py +0 -1054
- catalystwan/models/configuration/feature_profile/sdwan/cli/__init__.py +0 -23
- catalystwan/models/configuration/feature_profile/sdwan/cli/config.py +0 -18
- catalystwan/models/configuration/feature_profile/sdwan/cli/full_config.py +0 -15
- catalystwan/models/configuration/feature_profile/sdwan/dns_security/__init__.py +0 -13
- catalystwan/models/configuration/feature_profile/sdwan/dns_security/dns.py +0 -107
- catalystwan/models/configuration/feature_profile/sdwan/embedded_security/__init__.py +0 -23
- catalystwan/models/configuration/feature_profile/sdwan/embedded_security/ngfirewall.py +0 -915
- catalystwan/models/configuration/feature_profile/sdwan/embedded_security/policy.py +0 -171
- catalystwan/models/configuration/feature_profile/sdwan/other/__init__.py +0 -23
- catalystwan/models/configuration/feature_profile/sdwan/other/thousandeyes.py +0 -147
- catalystwan/models/configuration/feature_profile/sdwan/other/ucse.py +0 -110
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/__init__.py +0 -175
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/app_probe.py +0 -56
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/application_list.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/as_path.py +0 -22
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/color_list.py +0 -21
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/data_prefix.py +0 -35
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/expanded_community_list.py +0 -25
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/extended_community.py +0 -34
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/fowarding_class.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_data_prefix.py +0 -28
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/ipv6_prefix_list.py +0 -38
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/mirror.py +0 -27
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/policer.py +0 -42
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefered_group_color.py +0 -83
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/prefix_list.py +0 -28
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/sla_class.py +0 -130
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/standard_community.py +0 -30
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/policy/tloc_list.py +0 -44
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/aip.py +0 -64
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/amp.py +0 -79
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/application_list.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/data_prefix.py +0 -22
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/fqdn.py +0 -24
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/geolocation_list.py +0 -32
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/identity.py +0 -30
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/intrusion_prevention.py +0 -58
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ips_signature.py +0 -44
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/local_domain.py +0 -24
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/protocol_list.py +0 -21
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/scalable_group_tag.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/security_port.py +0 -45
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption.py +0 -126
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/ssl_decryption_profile.py +0 -165
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url.py +0 -32
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/url_filtering.py +0 -148
- catalystwan/models/configuration/feature_profile/sdwan/policy_object/security/zone.py +0 -44
- catalystwan/models/configuration/feature_profile/sdwan/routing/__init__.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/routing/bgp.py +0 -594
- catalystwan/models/configuration/feature_profile/sdwan/routing/ospf.py +0 -170
- catalystwan/models/configuration/feature_profile/sdwan/routing/ospfv3.py +0 -298
- catalystwan/models/configuration/feature_profile/sdwan/service/__init__.py +0 -85
- catalystwan/models/configuration/feature_profile/sdwan/service/appqoe.py +0 -270
- catalystwan/models/configuration/feature_profile/sdwan/service/dhcp_server.py +0 -127
- catalystwan/models/configuration/feature_profile/sdwan/service/eigrp.py +0 -103
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/common.py +0 -33
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/ethernet.py +0 -275
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/gre.py +0 -136
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/ipsec.py +0 -119
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/multilink.py +0 -101
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/svi.py +0 -172
- catalystwan/models/configuration/feature_profile/sdwan/service/lan/vpn.py +0 -627
- catalystwan/models/configuration/feature_profile/sdwan/service/multicast.py +0 -242
- catalystwan/models/configuration/feature_profile/sdwan/service/object_tracker.py +0 -84
- catalystwan/models/configuration/feature_profile/sdwan/service/route_policy.py +0 -419
- catalystwan/models/configuration/feature_profile/sdwan/service/service_insertion_attachment.py +0 -184
- catalystwan/models/configuration/feature_profile/sdwan/service/switchport.py +0 -112
- catalystwan/models/configuration/feature_profile/sdwan/service/tracker.py +0 -92
- catalystwan/models/configuration/feature_profile/sdwan/service/wireless_lan.py +0 -216
- catalystwan/models/configuration/feature_profile/sdwan/sig_security/__init__.py +0 -19
- catalystwan/models/configuration/feature_profile/sdwan/sig_security/sig_security.py +0 -379
- catalystwan/models/configuration/feature_profile/sdwan/system/__init__.py +0 -59
- catalystwan/models/configuration/feature_profile/sdwan/system/aaa.py +0 -406
- catalystwan/models/configuration/feature_profile/sdwan/system/banner.py +0 -30
- catalystwan/models/configuration/feature_profile/sdwan/system/basic.py +0 -290
- catalystwan/models/configuration/feature_profile/sdwan/system/bfd.py +0 -69
- catalystwan/models/configuration/feature_profile/sdwan/system/device_access.py +0 -157
- catalystwan/models/configuration/feature_profile/sdwan/system/device_access_ipv6.py +0 -157
- catalystwan/models/configuration/feature_profile/sdwan/system/global_parcel.py +0 -149
- catalystwan/models/configuration/feature_profile/sdwan/system/logging_parcel.py +0 -162
- catalystwan/models/configuration/feature_profile/sdwan/system/mrf.py +0 -75
- catalystwan/models/configuration/feature_profile/sdwan/system/ntp.py +0 -103
- catalystwan/models/configuration/feature_profile/sdwan/system/omp.py +0 -111
- catalystwan/models/configuration/feature_profile/sdwan/system/security.py +0 -179
- catalystwan/models/configuration/feature_profile/sdwan/system/snmp.py +0 -173
- catalystwan/models/configuration/feature_profile/sdwan/topology/__init__.py +0 -29
- catalystwan/models/configuration/feature_profile/sdwan/topology/custom_control.py +0 -425
- catalystwan/models/configuration/feature_profile/sdwan/topology/hubspoke.py +0 -60
- catalystwan/models/configuration/feature_profile/sdwan/topology/mesh.py +0 -23
- catalystwan/models/configuration/feature_profile/sdwan/transport/__init__.py +0 -93
- catalystwan/models/configuration/feature_profile/sdwan/transport/cellular_controller.py +0 -58
- catalystwan/models/configuration/feature_profile/sdwan/transport/cellular_profile.py +0 -71
- catalystwan/models/configuration/feature_profile/sdwan/transport/gps.py +0 -37
- catalystwan/models/configuration/feature_profile/sdwan/transport/management/ethernet.py +0 -121
- catalystwan/models/configuration/feature_profile/sdwan/transport/t1e1controller.py +0 -124
- catalystwan/models/configuration/feature_profile/sdwan/transport/vpn.py +0 -285
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/cellular.py +0 -166
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/ethernet.py +0 -281
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/gre.py +0 -46
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/ipsec.py +0 -98
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/multilink.py +0 -219
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/protocol_over.py +0 -405
- catalystwan/models/configuration/feature_profile/sdwan/transport/wan/interface/t1e1serial.py +0 -195
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/__init__.py +0 -62
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/analog_interface.py +0 -436
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/call_routing.py +0 -179
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/digital_interface.py +0 -329
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/dsp_farm.py +0 -193
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/media_profile.py +0 -25
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/server_group.py +0 -51
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/srst.py +0 -86
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/supervisory_disconnect.py +0 -68
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/translation_profile.py +0 -42
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/translation_rule.py +0 -31
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/trunk_group.py +0 -26
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/voice_global.py +0 -55
- catalystwan/models/configuration/feature_profile/sdwan/uc_voice/voice_tenant.py +0 -40
- catalystwan/models/configuration/network_hierarchy/__init__.py +0 -22
- catalystwan/models/configuration/network_hierarchy/cflowd.py +0 -120
- catalystwan/models/configuration/network_hierarchy/node.py +0 -88
- catalystwan/models/configuration/policy_group.py +0 -74
- catalystwan/models/configuration/profile_type.py +0 -5
- catalystwan/models/configuration/topology_group.py +0 -52
- catalystwan/models/device_inventory.py +0 -30
- catalystwan/models/feature_profile_parcel.py +0 -15
- catalystwan/models/misc/application_protocols.py +0 -29
- catalystwan/models/monitoring/security_policy.py +0 -16
- catalystwan/models/monitoring/server_info.py +0 -12
- catalystwan/models/policy/__init__.py +0 -392
- catalystwan/models/policy/centralized.py +0 -265
- catalystwan/models/policy/definition/access_control_list.py +0 -193
- catalystwan/models/policy/definition/access_control_list_ipv6.py +0 -187
- catalystwan/models/policy/definition/aip.py +0 -60
- catalystwan/models/policy/definition/amp.py +0 -65
- catalystwan/models/policy/definition/app_route.py +0 -246
- catalystwan/models/policy/definition/cflowd.py +0 -95
- catalystwan/models/policy/definition/control.py +0 -366
- catalystwan/models/policy/definition/device_access.py +0 -117
- catalystwan/models/policy/definition/device_access_ipv6.py +0 -115
- catalystwan/models/policy/definition/dial_peer.py +0 -60
- catalystwan/models/policy/definition/dns_security.py +0 -130
- catalystwan/models/policy/definition/fxo_port.py +0 -63
- catalystwan/models/policy/definition/fxs_did_port.py +0 -58
- catalystwan/models/policy/definition/fxs_port.py +0 -56
- catalystwan/models/policy/definition/hub_and_spoke.py +0 -87
- catalystwan/models/policy/definition/intrusion_prevention.py +0 -55
- catalystwan/models/policy/definition/mesh.py +0 -47
- catalystwan/models/policy/definition/pri_isdn_port.py +0 -48
- catalystwan/models/policy/definition/qos_map.py +0 -111
- catalystwan/models/policy/definition/rewrite.py +0 -47
- catalystwan/models/policy/definition/route_policy.py +0 -187
- catalystwan/models/policy/definition/rule_set.py +0 -270
- catalystwan/models/policy/definition/security_group.py +0 -93
- catalystwan/models/policy/definition/srst_phone_profile.py +0 -37
- catalystwan/models/policy/definition/ssl_decryption.py +0 -209
- catalystwan/models/policy/definition/ssl_decryption_utd_profile.py +0 -87
- catalystwan/models/policy/definition/traffic_data.py +0 -496
- catalystwan/models/policy/definition/url_filtering.py +0 -70
- catalystwan/models/policy/definition/vpn_membership.py +0 -42
- catalystwan/models/policy/definition/vpn_qos_map.py +0 -46
- catalystwan/models/policy/definition/zone_based_firewall.py +0 -301
- catalystwan/models/policy/list/app.py +0 -44
- catalystwan/models/policy/list/app_probe.py +0 -42
- catalystwan/models/policy/list/as_path.py +0 -30
- catalystwan/models/policy/list/class_map.py +0 -30
- catalystwan/models/policy/list/color.py +0 -28
- catalystwan/models/policy/list/communities.py +0 -83
- catalystwan/models/policy/list/data_ipv6_prefix.py +0 -30
- catalystwan/models/policy/list/data_prefix.py +0 -30
- catalystwan/models/policy/list/fax_protocol.py +0 -45
- catalystwan/models/policy/list/fqdn.py +0 -24
- catalystwan/models/policy/list/geo_location.py +0 -33
- catalystwan/models/policy/list/identity.py +0 -29
- catalystwan/models/policy/list/ips_signature.py +0 -27
- catalystwan/models/policy/list/ipv6_prefix.py +0 -33
- catalystwan/models/policy/list/local_app.py +0 -45
- catalystwan/models/policy/list/local_domain.py +0 -36
- catalystwan/models/policy/list/media_profile.py +0 -44
- catalystwan/models/policy/list/mirror.py +0 -27
- catalystwan/models/policy/list/modem_pass_through.py +0 -27
- catalystwan/models/policy/list/policer.py +0 -39
- catalystwan/models/policy/list/port.py +0 -33
- catalystwan/models/policy/list/preferred_color_group.py +0 -82
- catalystwan/models/policy/list/prefix.py +0 -33
- catalystwan/models/policy/list/protocol_name.py +0 -26
- catalystwan/models/policy/list/region.py +0 -45
- catalystwan/models/policy/list/scalable_group_tag.py +0 -30
- catalystwan/models/policy/list/site.py +0 -34
- catalystwan/models/policy/list/sla.py +0 -77
- catalystwan/models/policy/list/supervisory_disconnect.py +0 -62
- catalystwan/models/policy/list/threat_grid_api_key.py +0 -32
- catalystwan/models/policy/list/tloc.py +0 -32
- catalystwan/models/policy/list/translation_profile.py +0 -32
- catalystwan/models/policy/list/translation_rules.py +0 -29
- catalystwan/models/policy/list/trunkgroup.py +0 -56
- catalystwan/models/policy/list/umbrella_data.py +0 -30
- catalystwan/models/policy/list/url.py +0 -39
- catalystwan/models/policy/list/vpn.py +0 -40
- catalystwan/models/policy/list/zone.py +0 -45
- catalystwan/models/policy/localized.py +0 -154
- catalystwan/models/policy/policy.py +0 -100
- catalystwan/models/policy/policy_definition.py +0 -1624
- catalystwan/models/policy/policy_list.py +0 -47
- catalystwan/models/policy/security.py +0 -279
- catalystwan/models/policy/voice.py +0 -71
- catalystwan/models/settings.py +0 -41
- catalystwan/models/templates.py +0 -79
- catalystwan/models/tenant.py +0 -105
- catalystwan/models/url_monitoring.py +0 -28
- catalystwan/tests/__init__.py +0 -0
- catalystwan/tests/builders/uc_voice.py +0 -85
- catalystwan/tests/models/__init__.py +0 -0
- catalystwan/tests/templates/__init__.py +0 -0
- catalystwan/tests/templates/definitions/__init__.py +0 -0
- catalystwan/tests/templates/definitions/aaa_basic.json +0 -96
- catalystwan/tests/templates/definitions/aaa_complex.json +0 -464
- catalystwan/tests/templates/definitions/basic/__init__.py +0 -0
- catalystwan/tests/templates/definitions/basic/alias.json +0 -7
- catalystwan/tests/templates/definitions/basic/basic.json +0 -7
- catalystwan/tests/templates/definitions/basic/basic_no_value.json +0 -7
- catalystwan/tests/templates/definitions/basic/children.json +0 -39
- catalystwan/tests/templates/definitions/basic/children_nested.json +0 -72
- catalystwan/tests/templates/definitions/basic/children_nested_datapath.json +0 -72
- catalystwan/tests/templates/definitions/basic/data_path.json +0 -13
- catalystwan/tests/templates/definitions/cisco_aaa.json +0 -178
- catalystwan/tests/templates/definitions/cisco_aaa_complex.json +0 -361
- catalystwan/tests/templates/definitions/cisco_banner.json +0 -20
- catalystwan/tests/templates/definitions/cisco_bfd.json +0 -90
- catalystwan/tests/templates/definitions/cisco_logging_complex.json +0 -268
- catalystwan/tests/templates/definitions/cisco_ntp_complex.json +0 -143
- catalystwan/tests/templates/definitions/cisco_omp_complex.json +0 -175
- catalystwan/tests/templates/definitions/cisco_ospf_complex.json +0 -302
- catalystwan/tests/templates/definitions/cisco_sig.json +0 -405
- catalystwan/tests/templates/definitions/cisco_snmp_complex.json +0 -258
- catalystwan/tests/templates/definitions/cisco_system_complex.json +0 -502
- catalystwan/tests/templates/definitions/cisco_vpn_basic.json +0 -17
- catalystwan/tests/templates/definitions/cisco_vpn_complex.json +0 -1081
- catalystwan/tests/templates/definitions/cisco_vpn_interface_complex.json +0 -821
- catalystwan/tests/templates/definitions/default_cisco_system.json +0 -184
- catalystwan/tests/templates/definitions/omp_vsmart_1.json +0 -26
- catalystwan/tests/templates/definitions/omp_vsmart_2.json +0 -48
- catalystwan/tests/templates/definitions/omp_vsmart_3.json +0 -71
- catalystwan/tests/templates/definitions/omp_vsmart_complex.json +0 -73
- catalystwan/tests/templates/definitions/security_vsmart_complex.json +0 -24
- catalystwan/tests/templates/definitions/system_vsmart_complex.json +0 -193
- catalystwan/tests/templates/definitions/vpn_vsmart_basic.json +0 -17
- catalystwan/tests/templates/definitions/vpn_vsmart_complex.json +0 -179
- catalystwan/tests/templates/definitions/vpn_vsmart_interface_basic.json +0 -42
- catalystwan/tests/templates/definitions/vpn_vsmart_interface_complex.json +0 -208
- catalystwan/tests/templates/models/__init__.py +0 -53
- catalystwan/tests/templates/models/aaa.py +0 -106
- catalystwan/tests/templates/models/cisco_aaa.py +0 -124
- catalystwan/tests/templates/models/cisco_banner.py +0 -7
- catalystwan/tests/templates/models/cisco_bfd.py +0 -15
- catalystwan/tests/templates/models/cisco_logging.py +0 -65
- catalystwan/tests/templates/models/cisco_ntp.py +0 -17
- catalystwan/tests/templates/models/cisco_omp.py +0 -37
- catalystwan/tests/templates/models/cisco_ospf.py +0 -60
- catalystwan/tests/templates/models/cisco_secure_internet_gateway.py +0 -95
- catalystwan/tests/templates/models/cisco_snmp.py +0 -40
- catalystwan/tests/templates/models/cisco_system.py +0 -113
- catalystwan/tests/templates/models/cisco_vpn.py +0 -240
- catalystwan/tests/templates/models/cisco_vpn_interface.py +0 -200
- catalystwan/tests/templates/models/omp_vsmart.py +0 -53
- catalystwan/tests/templates/models/security_vsmart.py +0 -11
- catalystwan/tests/templates/models/system_vsmart.py +0 -37
- catalystwan/tests/templates/models/vpn_vsmart.py +0 -32
- catalystwan/tests/templates/models/vpn_vsmart_interface.py +0 -54
- catalystwan/tests/templates/schemas/aaa.json +0 -1096
- catalystwan/tests/templates/schemas/basic/alias.json +0 -24
- catalystwan/tests/templates/schemas/basic/basic.json +0 -23
- catalystwan/tests/templates/schemas/basic/children.json +0 -59
- catalystwan/tests/templates/schemas/basic/children_nested.json +0 -112
- catalystwan/tests/templates/schemas/basic/children_nested_datapath.json +0 -112
- catalystwan/tests/templates/schemas/basic/data_path.json +0 -29
- catalystwan/tests/templates/schemas/cedge_aaa.json +0 -1185
- catalystwan/tests/templates/schemas/cisco_banner.json +0 -44
- catalystwan/tests/templates/schemas/cisco_bfd.json +0 -266
- catalystwan/tests/templates/schemas/cisco_logging.json +0 -577
- catalystwan/tests/templates/schemas/cisco_ntp.json +0 -265
- catalystwan/tests/templates/schemas/cisco_omp.json +0 -479
- catalystwan/tests/templates/schemas/cisco_ospf.json +0 -908
- catalystwan/tests/templates/schemas/cisco_secure_internet_gateway.json +0 -1520
- catalystwan/tests/templates/schemas/cisco_snmp.json +0 -561
- catalystwan/tests/templates/schemas/cisco_system.json +0 -3099
- catalystwan/tests/templates/schemas/cisco_vpn.json +0 -2504
- catalystwan/tests/templates/schemas/cisco_vpn_interface.json +0 -3348
- catalystwan/tests/templates/schemas/omp-vsmart.json +0 -222
- catalystwan/tests/templates/schemas/security-vsmart.json +0 -58
- catalystwan/tests/templates/schemas/system-vsmart.json +0 -2585
- catalystwan/tests/templates/schemas/vpn-vsmart-interface.json +0 -859
- catalystwan/tests/templates/schemas/vpn-vsmart.json +0 -445
- catalystwan/tests/templates/test_chose_model.py +0 -32
- catalystwan/tests/templates/test_deserialize_model.py +0 -69
- catalystwan/tests/templates/test_find_template_values.py +0 -193
- catalystwan/tests/templates/test_find_template_values_2.py +0 -193
- catalystwan/tests/templates/test_generate_payload.py +0 -137
- catalystwan/tests/templates/test_serialize_model.py +0 -52
- catalystwan/tests/test_admin_tech_api.py +0 -198
- catalystwan/tests/test_administration.py +0 -470
- catalystwan/tests/test_alarms_api.py +0 -251
- catalystwan/tests/test_cli_template.py +0 -218
- catalystwan/tests/test_creation_tools.py +0 -155
- catalystwan/tests/test_device_action_api.py +0 -117
- catalystwan/tests/test_devices_api.py +0 -674
- catalystwan/tests/test_endpoints.py +0 -907
- catalystwan/tests/test_feature_profile_api.py +0 -282
- catalystwan/tests/test_feature_template_field.py +0 -33
- catalystwan/tests/test_logs_api.py +0 -40
- catalystwan/tests/test_models_common.py +0 -53
- catalystwan/tests/test_monitoring_security_policy.py +0 -65
- catalystwan/tests/test_monitoring_server_info.py +0 -49
- catalystwan/tests/test_monitoring_status_api.py +0 -118
- catalystwan/tests/test_mtt_aaa_api.py +0 -293
- catalystwan/tests/test_omp_api.py +0 -438
- catalystwan/tests/test_packet_capture.py +0 -125
- catalystwan/tests/test_partition_manager_api.py +0 -121
- catalystwan/tests/test_response.py +0 -183
- catalystwan/tests/test_session.py +0 -102
- catalystwan/tests/test_software_action_api.py +0 -154
- catalystwan/tests/test_speed_test_api.py +0 -143
- catalystwan/tests/test_task_status_api.py +0 -381
- catalystwan/tests/test_templates.py +0 -405
- catalystwan/tests/test_tenant_backup_restore_api.py +0 -88
- catalystwan/tests/test_tenant_management_api.py +0 -153
- catalystwan/tests/test_tenant_migration_api.py +0 -102
- catalystwan/tests/test_typed_list.py +0 -426
- catalystwan/tests/test_url_monitoring.py +0 -80
- catalystwan/tests/test_version.py +0 -99
- catalystwan/tests/test_version_utils.py +0 -240
- catalystwan/tests/test_vmanage_auth.py +0 -149
- catalystwan/typed_list.py +0 -288
- catalystwan/utils/__init__.py +0 -0
- catalystwan/utils/alarm_status.py +0 -16
- catalystwan/utils/certificate_status.py +0 -13
- catalystwan/utils/colors.py +0 -12
- catalystwan/utils/config_status.py +0 -8
- catalystwan/utils/creation_tools.py +0 -136
- catalystwan/utils/dashboard.py +0 -255
- catalystwan/utils/device_model.py +0 -322
- catalystwan/utils/dict.py +0 -61
- catalystwan/utils/feature_template/choose_model.py +0 -30
- catalystwan/utils/feature_template/find_template_values.py +0 -111
- catalystwan/utils/model.py +0 -45
- catalystwan/utils/operation_status.py +0 -22
- catalystwan/utils/persona.py +0 -5
- catalystwan/utils/personality.py +0 -10
- catalystwan/utils/pydantic_field.py +0 -12
- catalystwan/utils/reachability.py +0 -14
- catalystwan/utils/session_type.py +0 -17
- catalystwan/utils/template_type.py +0 -8
- catalystwan/utils/type_check.py +0 -22
- catalystwan/utils/upgrades_helper.py +0 -95
- catalystwan/utils/validate_status.py +0 -8
- catalystwan/workflows/backup_restore_device_templates.py +0 -467
- catalystwan/workflows/tenant_migration.py +0 -203
- catalystwan-0.40.1.dev7.dist-info/METADATA +0 -539
- catalystwan-0.40.1.dev7.dist-info/RECORD +0 -618
- /catalystwan/{api → core/models}/__init__.py +0 -0
- /catalystwan/{api/builders/feature_profiles/__init__.py → core/py.typed} +0 -0
- {catalystwan-0.40.1.dev7.dist-info → catalystwan-2.0.0a0.dist-info}/LICENSE +0 -0
|
@@ -1,606 +0,0 @@
|
|
|
1
|
-
# Copyright 2023 Cisco Systems, Inc. and its affiliates
|
|
2
|
-
|
|
3
|
-
"""This modules defines APIEndpoints class which is used to define
|
|
4
|
-
vManage API endpoint handlers in declarative way.
|
|
5
|
-
Just create a sub-class and define endpoints using using included decorators: request, view, versions.
|
|
6
|
-
Method decorated with @request has no body, as decorator constructs and sends request.
|
|
7
|
-
>>> from catalystwan.endpoints import APIEndpoints, versions, view, request
|
|
8
|
-
>>> from catalystwan.utils.session_type import ProviderView
|
|
9
|
-
>>>
|
|
10
|
-
>>>
|
|
11
|
-
>>> class TenantBulkDeleteRequest(BaseModel):
|
|
12
|
-
>>> password: str
|
|
13
|
-
>>> tenant_id_list: List[str] = Field(alias="tenantIdList")
|
|
14
|
-
>>>
|
|
15
|
-
>>>
|
|
16
|
-
>>> class TenantTaskId(BaseModel):
|
|
17
|
-
>>> id: str
|
|
18
|
-
>>>
|
|
19
|
-
>>>
|
|
20
|
-
>>> class TenantManagementAPI(APIEndpoints):
|
|
21
|
-
>>> @versions(">=20.4")
|
|
22
|
-
>>> @view({ProviderView})
|
|
23
|
-
>>> @delete("/tenant/bulk/async")
|
|
24
|
-
>>> def delete_tenant_async_bulk(self, payload: TenantBulkDeleteRequest) -> TenantTaskId:
|
|
25
|
-
>>> ...
|
|
26
|
-
>>>
|
|
27
|
-
To send request instantiate API with logged ManagerSession:
|
|
28
|
-
>>> api = TenantManagementAPI(session)
|
|
29
|
-
>>> api.delete_tenant_async_bulk(TenantBulkDeleteRequest(password="", tenantIdList=["TNT00005"]))
|
|
30
|
-
"""
|
|
31
|
-
from __future__ import annotations
|
|
32
|
-
|
|
33
|
-
import json
|
|
34
|
-
import logging
|
|
35
|
-
from dataclasses import dataclass, fields
|
|
36
|
-
from enum import Enum
|
|
37
|
-
from inspect import _empty, isclass, signature
|
|
38
|
-
from io import BufferedReader
|
|
39
|
-
from string import Formatter
|
|
40
|
-
from typing import (
|
|
41
|
-
Any,
|
|
42
|
-
BinaryIO,
|
|
43
|
-
ClassVar,
|
|
44
|
-
Dict,
|
|
45
|
-
Final,
|
|
46
|
-
Iterable,
|
|
47
|
-
List,
|
|
48
|
-
Literal,
|
|
49
|
-
Mapping,
|
|
50
|
-
Optional,
|
|
51
|
-
Protocol,
|
|
52
|
-
Sequence,
|
|
53
|
-
Set,
|
|
54
|
-
Tuple,
|
|
55
|
-
TypeVar,
|
|
56
|
-
Union,
|
|
57
|
-
runtime_checkable,
|
|
58
|
-
)
|
|
59
|
-
from uuid import UUID
|
|
60
|
-
|
|
61
|
-
from packaging.specifiers import SpecifierSet # type: ignore
|
|
62
|
-
from packaging.version import Version # type: ignore
|
|
63
|
-
from pydantic import BaseModel
|
|
64
|
-
from typing_extensions import get_args, get_origin
|
|
65
|
-
|
|
66
|
-
from catalystwan.abstractions import APIEndpointClient, APIEndpointClientResponse
|
|
67
|
-
from catalystwan.exceptions import APIEndpointError, APIRequestPayloadTypeError, APIVersionError, APIViewError
|
|
68
|
-
from catalystwan.typed_list import DataSequence
|
|
69
|
-
from catalystwan.utils.model import resolve_nested_base_model_unions
|
|
70
|
-
from catalystwan.utils.session_type import SessionType
|
|
71
|
-
|
|
72
|
-
BASE_PATH: Final[str] = "/dataservice"
|
|
73
|
-
T = TypeVar("T")
|
|
74
|
-
logger = logging.getLogger(__name__)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@runtime_checkable
|
|
78
|
-
class CustomPayloadType(Protocol):
|
|
79
|
-
def prepared(self) -> PreparedPayload:
|
|
80
|
-
...
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
JSON = Union[str, int, float, bool, None, Dict[str, "JSON"], List["JSON"]]
|
|
84
|
-
ModelPayloadType = Union[BaseModel, Sequence[BaseModel]]
|
|
85
|
-
PayloadType = Union[None, JSON, str, bytes, dict, ModelPayloadType, CustomPayloadType]
|
|
86
|
-
ReturnType = Union[None, JSON, bytes, str, dict, BaseModel, DataSequence[BaseModel]]
|
|
87
|
-
RequestParamsType = Union[Dict[str, str], BaseModel]
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
@dataclass
|
|
91
|
-
class TypeSpecifier:
|
|
92
|
-
"""Holds type information extracted from signature. Common for payload and return values. Used for documentation"""
|
|
93
|
-
|
|
94
|
-
present: bool
|
|
95
|
-
sequence_type: Optional[type] = None
|
|
96
|
-
payload_type: Optional[type] = None
|
|
97
|
-
payload_union_model_types: Optional[Sequence[type]] = None
|
|
98
|
-
is_json: bool = False # JSON is treated specially as it is type-alias / <typing special form>
|
|
99
|
-
is_optional: bool = False
|
|
100
|
-
|
|
101
|
-
@classmethod
|
|
102
|
-
def not_present(cls) -> TypeSpecifier:
|
|
103
|
-
return TypeSpecifier(present=False)
|
|
104
|
-
|
|
105
|
-
@classmethod
|
|
106
|
-
def none_type(cls) -> TypeSpecifier:
|
|
107
|
-
return TypeSpecifier(present=True)
|
|
108
|
-
|
|
109
|
-
@classmethod
|
|
110
|
-
def json(cls) -> TypeSpecifier:
|
|
111
|
-
return TypeSpecifier(present=True, is_json=True)
|
|
112
|
-
|
|
113
|
-
@classmethod
|
|
114
|
-
def model_union(cls, models: Sequence[type]) -> TypeSpecifier:
|
|
115
|
-
return TypeSpecifier(present=True, payload_union_model_types=models)
|
|
116
|
-
|
|
117
|
-
@classmethod
|
|
118
|
-
def resolve_nested(cls, annotation: Any, models_types: List[type]) -> List[type]:
|
|
119
|
-
try:
|
|
120
|
-
return resolve_nested_base_model_unions(annotation)
|
|
121
|
-
except TypeError:
|
|
122
|
-
raise APIEndpointError(f"Expected: {PayloadType}")
|
|
123
|
-
|
|
124
|
-
@property
|
|
125
|
-
def payload_model_set(self) -> Optional[Set[type]]:
|
|
126
|
-
if self.payload_union_model_types is not None:
|
|
127
|
-
return set(self.payload_union_model_types)
|
|
128
|
-
return None
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
@dataclass
|
|
132
|
-
class APIEndpointRequestMeta:
|
|
133
|
-
"""Holds data for endpoints exctracted during decorating. Used for documentation"""
|
|
134
|
-
|
|
135
|
-
func: Any
|
|
136
|
-
http_request: str
|
|
137
|
-
payload_spec: TypeSpecifier
|
|
138
|
-
return_spec: TypeSpecifier
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
@dataclass(frozen=True)
|
|
142
|
-
class PreparedPayload:
|
|
143
|
-
"""Holds data prepared for sending in request"""
|
|
144
|
-
|
|
145
|
-
data: Union[Dict, str, bytes, None] = None
|
|
146
|
-
headers: Optional[Mapping[str, Any]] = None
|
|
147
|
-
files: Optional[Dict[str, Tuple[str, BufferedReader]]] = None
|
|
148
|
-
|
|
149
|
-
def asdict(self) -> Dict[str, Any]:
|
|
150
|
-
"""Needed because python builtin does deepcopy of objects (it is impossible for BufferedReader)"""
|
|
151
|
-
result = {}
|
|
152
|
-
for f in fields(self):
|
|
153
|
-
if value := getattr(self, f.name):
|
|
154
|
-
result[f.name] = value
|
|
155
|
-
return result
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
def dict_values_to_str(field_names: Set[str], kwargs: Dict[str, Any]) -> Dict[str, str]:
|
|
159
|
-
# this is to keep compatiblity and have seme behavior for (str, Enum) mixin after 3.11 for url formatting
|
|
160
|
-
result: Dict[str, str] = {}
|
|
161
|
-
for field_name in field_names:
|
|
162
|
-
field_value = kwargs.get(field_name)
|
|
163
|
-
if isinstance(field_value, Enum):
|
|
164
|
-
result[field_name] = str(field_value.value)
|
|
165
|
-
else:
|
|
166
|
-
result[field_name] = str(field_value)
|
|
167
|
-
return result
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
class APIEndpoints:
|
|
171
|
-
"""
|
|
172
|
-
Class to be used as base for all API endpoints.
|
|
173
|
-
Injects BASE_PATH url prefix as it is common for all known vManage API endpoints.
|
|
174
|
-
Introduces special keyword argument 'payload' in request call and handles sending of such object.
|
|
175
|
-
"""
|
|
176
|
-
|
|
177
|
-
@classmethod
|
|
178
|
-
def _prepare_payload(
|
|
179
|
-
cls, payload: PayloadType, force_json: bool = False, context: Dict[str, Any] = {}
|
|
180
|
-
) -> PreparedPayload:
|
|
181
|
-
"""Helper method to prepare data for sending based on type"""
|
|
182
|
-
if force_json or isinstance(payload, dict):
|
|
183
|
-
return PreparedPayload(data=json.dumps(payload), headers={"content-type": "application/json"})
|
|
184
|
-
if isinstance(payload, (str, bytes)):
|
|
185
|
-
return PreparedPayload(data=payload)
|
|
186
|
-
elif isinstance(payload, (BaseModel)):
|
|
187
|
-
return cls._prepare_basemodel_payload(payload, context)
|
|
188
|
-
elif isinstance(payload, Sequence) and not isinstance(payload, (str, bytes)):
|
|
189
|
-
return cls._prepare_sequence_payload(payload, context) # type: ignore[arg-type]
|
|
190
|
-
# offender is List[JSON] which is also a Sequence can be ignored as long as force_json is passed correctly
|
|
191
|
-
elif isinstance(payload, CustomPayloadType):
|
|
192
|
-
return payload.prepared()
|
|
193
|
-
else:
|
|
194
|
-
raise APIRequestPayloadTypeError(payload)
|
|
195
|
-
|
|
196
|
-
@classmethod
|
|
197
|
-
def _prepare_basemodel_payload(cls, payload: BaseModel, context: Dict[str, Any] = {}) -> PreparedPayload:
|
|
198
|
-
"""Helper method to prepare BaseModel instance for sending"""
|
|
199
|
-
return PreparedPayload(
|
|
200
|
-
data=payload.model_dump_json(exclude_none=True, by_alias=True, context=context),
|
|
201
|
-
headers={"content-type": "application/json"},
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
@classmethod
|
|
205
|
-
def _prepare_sequence_payload(cls, payload: Iterable[BaseModel], context: Dict[str, Any] = {}) -> PreparedPayload:
|
|
206
|
-
"""Helper method to prepare sequences for sending"""
|
|
207
|
-
items = []
|
|
208
|
-
for item in payload:
|
|
209
|
-
items.append(item.model_dump(exclude_none=True, by_alias=True, context=context))
|
|
210
|
-
data = json.dumps(items)
|
|
211
|
-
return PreparedPayload(data=data, headers={"content-type": "application/json"})
|
|
212
|
-
|
|
213
|
-
@classmethod
|
|
214
|
-
def _prepare_params(cls, params: RequestParamsType, context: Dict[str, Any] = {}) -> Dict[str, Any]:
|
|
215
|
-
"""Helper method to prepare params for sending"""
|
|
216
|
-
if isinstance(params, BaseModel):
|
|
217
|
-
return params.model_dump(exclude_none=True, by_alias=True, context=context)
|
|
218
|
-
return params
|
|
219
|
-
|
|
220
|
-
def __init__(self, client: APIEndpointClient):
|
|
221
|
-
self._client = client
|
|
222
|
-
self._basepath = BASE_PATH
|
|
223
|
-
|
|
224
|
-
def _request(
|
|
225
|
-
self,
|
|
226
|
-
method: str,
|
|
227
|
-
url: str,
|
|
228
|
-
payload: Optional[ModelPayloadType] = None,
|
|
229
|
-
params: Optional[RequestParamsType] = None,
|
|
230
|
-
force_json_payload: bool = False,
|
|
231
|
-
**kwargs,
|
|
232
|
-
) -> APIEndpointClientResponse:
|
|
233
|
-
"""Prepares and sends request using client protocol"""
|
|
234
|
-
_kwargs = dict(kwargs)
|
|
235
|
-
context = dict(api_version=self._api_version)
|
|
236
|
-
if payload is not None:
|
|
237
|
-
_kwargs.update(self._prepare_payload(payload, force_json_payload, context).asdict())
|
|
238
|
-
if params is not None:
|
|
239
|
-
_kwargs.update({"params": self._prepare_params(params, context)})
|
|
240
|
-
return self._client.request(method, self._basepath + url, **_kwargs)
|
|
241
|
-
|
|
242
|
-
@property
|
|
243
|
-
def _api_version(self) -> Optional[Version]:
|
|
244
|
-
return self._client.api_version
|
|
245
|
-
|
|
246
|
-
@property
|
|
247
|
-
def _session_type(self) -> Optional[SessionType]:
|
|
248
|
-
return self._client.session_type
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
class APIEndpointsDecorator:
|
|
252
|
-
@classmethod
|
|
253
|
-
def get_check_instance(cls, _self, *args, **kwargs) -> APIEndpoints:
|
|
254
|
-
"""Gets wrapped function instance (first argument)"""
|
|
255
|
-
if not isinstance(_self, APIEndpoints):
|
|
256
|
-
raise APIEndpointError("Only APIEndpointsDecorator instance methods can be annotated with @{cls} decorator")
|
|
257
|
-
return _self
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
class versions(APIEndpointsDecorator):
|
|
261
|
-
"""
|
|
262
|
-
Decorator to annotate endpoints with supported versions.
|
|
263
|
-
Logs warning or raises exception when incompatibility found during runtime.
|
|
264
|
-
"""
|
|
265
|
-
|
|
266
|
-
versions_lookup: ClassVar[
|
|
267
|
-
Dict[str, SpecifierSet]
|
|
268
|
-
] = {} # maps decorated method instance to it's supported verisions
|
|
269
|
-
|
|
270
|
-
def __init__(self, supported_versions: str, raises: bool = False):
|
|
271
|
-
self.supported_versions = SpecifierSet(supported_versions)
|
|
272
|
-
self.raises = raises
|
|
273
|
-
|
|
274
|
-
def __call__(self, func):
|
|
275
|
-
original_func = getattr(func, "_ofunc", func) # grab original function
|
|
276
|
-
self.versions_lookup[original_func.__qualname__] = self.supported_versions
|
|
277
|
-
|
|
278
|
-
def wrapper(*args, **kwargs):
|
|
279
|
-
"""Executes each time decorated method is called"""
|
|
280
|
-
_self = self.get_check_instance(*args, **kwargs) # _self refers to APIEndpoints instance
|
|
281
|
-
current = _self._api_version
|
|
282
|
-
supported = self.supported_versions
|
|
283
|
-
if current and current not in supported:
|
|
284
|
-
if self.raises:
|
|
285
|
-
raise APIVersionError(func, supported, current)
|
|
286
|
-
else:
|
|
287
|
-
logger.warning(
|
|
288
|
-
f"vManage runs: {current} but {func.__qualname__} only supported for API versions: {supported}"
|
|
289
|
-
)
|
|
290
|
-
return func(*args, **kwargs)
|
|
291
|
-
|
|
292
|
-
wrapper._ofunc = original_func # provide original function to next decorator in chain
|
|
293
|
-
return wrapper
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
class view(APIEndpointsDecorator):
|
|
297
|
-
"""
|
|
298
|
-
Decorator to annotate endpoints with session type (view) restriction
|
|
299
|
-
Logs warning or raises exception when incompatibility found during runtime.
|
|
300
|
-
"""
|
|
301
|
-
|
|
302
|
-
view_lookup: ClassVar[Dict[str, Set[SessionType]]] = {} # maps decorated method instance to it's allowed sessions
|
|
303
|
-
|
|
304
|
-
def __init__(self, allowed_session_types: Set[SessionType], raises: bool = False):
|
|
305
|
-
self.allowed_session_types = allowed_session_types
|
|
306
|
-
self.raises = raises
|
|
307
|
-
|
|
308
|
-
def __call__(self, func):
|
|
309
|
-
original_func = getattr(func, "_ofunc", func) # grab original function
|
|
310
|
-
self.view_lookup[original_func.__qualname__] = self.allowed_session_types
|
|
311
|
-
|
|
312
|
-
def wrapper(*args, **kwargs):
|
|
313
|
-
"""Executes each time decorated method is called"""
|
|
314
|
-
_self = self.get_check_instance(*args, **kwargs) # _self refers to APIEndpoints instance
|
|
315
|
-
current = _self._session_type
|
|
316
|
-
allowed = self.allowed_session_types
|
|
317
|
-
if current and current not in allowed:
|
|
318
|
-
if self.raises:
|
|
319
|
-
raise APIViewError(func, allowed, current)
|
|
320
|
-
else:
|
|
321
|
-
logger.warning(
|
|
322
|
-
f"Current view is: {current} but {func.__qualname__} only allowed for views: {allowed}"
|
|
323
|
-
)
|
|
324
|
-
return func(*args, **kwargs)
|
|
325
|
-
|
|
326
|
-
wrapper._ofunc = original_func # provide original function to next decorator in chain
|
|
327
|
-
return wrapper
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
class request(APIEndpointsDecorator):
|
|
331
|
-
"""
|
|
332
|
-
Decorator to annotate endpoints with HTTP method, URL and optionally json key from which
|
|
333
|
-
modelled data will be parsed (usually "data", but defaults to whole json payload).
|
|
334
|
-
Additional kwargs can be injected which will be passed to request method (eg. custom headers)
|
|
335
|
-
|
|
336
|
-
Decorated method parameters and return type annotations are checked:
|
|
337
|
-
|
|
338
|
-
Parameters:
|
|
339
|
-
|
|
340
|
-
"payload": argument with that name is used to send data in request
|
|
341
|
-
usually it is user defined subclass of: pydantic.BaseModel
|
|
342
|
-
other types are also supported please check: catalystwan.endpoints.PayloadType
|
|
343
|
-
|
|
344
|
-
"params": argument with that name is used to generate url query string
|
|
345
|
-
supports Dict[str, str] and pydantic.BaseModel
|
|
346
|
-
|
|
347
|
-
other parameter must be strings and are used to format url.
|
|
348
|
-
|
|
349
|
-
Return Type:
|
|
350
|
-
|
|
351
|
-
supports types defined in: catalystwan.endpoints.ReturnType
|
|
352
|
-
|
|
353
|
-
Raises:
|
|
354
|
-
APIEndpointError: when decorated method has unsupported parameters or response type
|
|
355
|
-
"""
|
|
356
|
-
|
|
357
|
-
forbidden_url_field_names = {"self", "payload", "params"}
|
|
358
|
-
request_lookup: ClassVar[
|
|
359
|
-
Dict[str, APIEndpointRequestMeta]
|
|
360
|
-
] = {} # maps decorated method instance to it's meta information
|
|
361
|
-
|
|
362
|
-
def __init__(self, http_method: str, url: str, resp_json_key: Optional[str] = None, **kwargs):
|
|
363
|
-
self.http_method = http_method
|
|
364
|
-
formatter = Formatter()
|
|
365
|
-
url_field_names = {item[1] for item in formatter.parse(url) if item[1] is not None}
|
|
366
|
-
if self.forbidden_url_field_names & url_field_names:
|
|
367
|
-
APIEndpointError(f"One of forbidden fields names: {self.forbidden_url_field_names} found in url: {url}")
|
|
368
|
-
self.url = url
|
|
369
|
-
self.url_field_names = url_field_names
|
|
370
|
-
self.resp_json_key = resp_json_key
|
|
371
|
-
self.return_spec = TypeSpecifier.not_present()
|
|
372
|
-
self.payload_spec = TypeSpecifier.not_present()
|
|
373
|
-
self.kwargs = kwargs
|
|
374
|
-
|
|
375
|
-
def specify_return_type(self) -> TypeSpecifier:
|
|
376
|
-
"""Specifies return type based on decorated method signature annotations.
|
|
377
|
-
Does basic checking of annotated types so problems can be detected early.
|
|
378
|
-
|
|
379
|
-
Raises:
|
|
380
|
-
APIEndpointError: when signature contains unexpected return annotation
|
|
381
|
-
|
|
382
|
-
Returns:
|
|
383
|
-
TypeSpecifier: Specification of return type
|
|
384
|
-
"""
|
|
385
|
-
annotation = self.sig.return_annotation
|
|
386
|
-
if annotation == JSON:
|
|
387
|
-
return TypeSpecifier.json()
|
|
388
|
-
if annotation is None:
|
|
389
|
-
return TypeSpecifier.none_type()
|
|
390
|
-
if annotation == _empty:
|
|
391
|
-
raise APIEndpointError(
|
|
392
|
-
"APIEndpoint methods decorated with @request must specify return type, "
|
|
393
|
-
"use None annotation if function does not return any value"
|
|
394
|
-
)
|
|
395
|
-
if (type_origin := get_origin(annotation)) and isclass(type_origin) and issubclass(type_origin, DataSequence):
|
|
396
|
-
if (
|
|
397
|
-
(type_args := get_args(annotation))
|
|
398
|
-
and (len(type_args) == 1)
|
|
399
|
-
and isclass(type_args[0])
|
|
400
|
-
and issubclass(type_args[0], BaseModel)
|
|
401
|
-
):
|
|
402
|
-
return TypeSpecifier(True, DataSequence, type_args[0])
|
|
403
|
-
raise APIEndpointError(f"Expected: {ReturnType} but return type {annotation}")
|
|
404
|
-
elif isclass(annotation):
|
|
405
|
-
try:
|
|
406
|
-
if issubclass(annotation, (bytes, str, dict, BinaryIO, BaseModel)):
|
|
407
|
-
return TypeSpecifier(True, None, annotation)
|
|
408
|
-
raise APIEndpointError(f"Expected: {ReturnType} but return type {annotation}")
|
|
409
|
-
except TypeError:
|
|
410
|
-
raise APIEndpointError(f"Expected: {ReturnType} but return type {annotation}")
|
|
411
|
-
raise APIEndpointError(f"Expected: {ReturnType} but return type {annotation}")
|
|
412
|
-
|
|
413
|
-
def specify_payload_type(self) -> TypeSpecifier:
|
|
414
|
-
"""Specifies payload type based on decorated method signature annotations.
|
|
415
|
-
Does basic checking of annotated types for 'payload' so problems can be detected early.
|
|
416
|
-
|
|
417
|
-
Raises:
|
|
418
|
-
APIEndpointError: when signature contains unexpected payload annotation
|
|
419
|
-
|
|
420
|
-
Returns:
|
|
421
|
-
TypeSpecifier: Specification of payload type
|
|
422
|
-
"""
|
|
423
|
-
payload_param = self.sig.parameters.get("payload")
|
|
424
|
-
if not payload_param:
|
|
425
|
-
return TypeSpecifier.not_present()
|
|
426
|
-
|
|
427
|
-
annotation = payload_param.annotation
|
|
428
|
-
is_optional = False
|
|
429
|
-
|
|
430
|
-
# Check if JSON
|
|
431
|
-
if annotation == JSON:
|
|
432
|
-
return TypeSpecifier.json()
|
|
433
|
-
|
|
434
|
-
# Check if Optional (flag and replace original annotation with optional type if exactly one is present)
|
|
435
|
-
if type_origin := get_origin(annotation):
|
|
436
|
-
type_args = get_args(annotation)
|
|
437
|
-
if type_origin == Union and (type(None) in type_args):
|
|
438
|
-
optional_type_args = tuple(arg for arg in get_args(annotation) if not arg == type(None)) # noqa: E721
|
|
439
|
-
# flake suggest using isinstance(arg, type(None)) above, but it doesn't match NoneType
|
|
440
|
-
if len(optional_type_args) == 1:
|
|
441
|
-
is_optional = True
|
|
442
|
-
annotation = optional_type_args[0]
|
|
443
|
-
|
|
444
|
-
# Check if regular class
|
|
445
|
-
if isclass(annotation):
|
|
446
|
-
if issubclass(annotation, (bytes, str, dict, BinaryIO, BaseModel, CustomPayloadType)):
|
|
447
|
-
return TypeSpecifier(True, None, annotation, None, False, is_optional)
|
|
448
|
-
else:
|
|
449
|
-
raise APIEndpointError(f"'payload' param must be annotated with supported type: {PayloadType}")
|
|
450
|
-
|
|
451
|
-
# Check for accepted alias types like List[...] and Union[...]
|
|
452
|
-
elif type_origin := get_origin(annotation):
|
|
453
|
-
# Check if Sequence[PayloadModelType] like List or DataSequence
|
|
454
|
-
if isclass(type_origin) and issubclass(type_origin, Sequence):
|
|
455
|
-
if (
|
|
456
|
-
(type_args := get_args(annotation))
|
|
457
|
-
and (len(type_args) == 1)
|
|
458
|
-
and isclass(type_args[0])
|
|
459
|
-
and issubclass(type_args[0], BaseModel)
|
|
460
|
-
):
|
|
461
|
-
return TypeSpecifier(True, type_origin, type_args[0], None, False, is_optional)
|
|
462
|
-
else:
|
|
463
|
-
models = TypeSpecifier.resolve_nested(annotation, [])
|
|
464
|
-
return TypeSpecifier.model_union(models)
|
|
465
|
-
raise APIEndpointError(f"'payload' param must be annotated with supported type: {PayloadType}")
|
|
466
|
-
|
|
467
|
-
def check_params(self):
|
|
468
|
-
"""Checks params in decorated method definition
|
|
469
|
-
|
|
470
|
-
Raises:
|
|
471
|
-
APIEndpointError: when decorated params not matching specification
|
|
472
|
-
"""
|
|
473
|
-
parameters = self.sig.parameters
|
|
474
|
-
|
|
475
|
-
if params_param := parameters.get("params"):
|
|
476
|
-
if not (isclass(params_param.annotation) and issubclass(params_param.annotation, (BaseModel, Dict))):
|
|
477
|
-
raise APIEndpointError(f"'params' param must be annotated with supported type: {RequestParamsType}")
|
|
478
|
-
|
|
479
|
-
general_purpose_arg_names = {
|
|
480
|
-
key for key in self.sig.parameters.keys() if key not in self.forbidden_url_field_names
|
|
481
|
-
}
|
|
482
|
-
if missing := self.url_field_names.difference(general_purpose_arg_names):
|
|
483
|
-
raise APIEndpointError(f"Missing parameters: {missing} to format url: {self.url}")
|
|
484
|
-
|
|
485
|
-
for parameter in [parameters.get(name) for name in self.url_field_names]:
|
|
486
|
-
# Check if 'params' is type of str, UUID or LIteral
|
|
487
|
-
if not (isclass(parameter.annotation) and issubclass(parameter.annotation, (str, UUID))):
|
|
488
|
-
if not get_origin(parameter.annotation) == Literal:
|
|
489
|
-
raise APIEndpointError(
|
|
490
|
-
f"Parameter {parameter} used for url formatting must be 'str', UUID or Literal sub-type"
|
|
491
|
-
)
|
|
492
|
-
|
|
493
|
-
elif p_args := get_args(parameter.annotation):
|
|
494
|
-
# Check if all 'params' Literal values are str
|
|
495
|
-
if not all((isinstance(arg, str) for arg in p_args)):
|
|
496
|
-
raise APIEndpointError(
|
|
497
|
-
f"Literal values for parameter {parameter} used for url formatting must be 'str'"
|
|
498
|
-
)
|
|
499
|
-
|
|
500
|
-
no_purpose_params = {
|
|
501
|
-
parameters.get(name) for name in general_purpose_arg_names.difference(self.url_field_names)
|
|
502
|
-
}
|
|
503
|
-
if no_purpose_params:
|
|
504
|
-
raise APIEndpointError(
|
|
505
|
-
f"Parameters {no_purpose_params} are not used as "
|
|
506
|
-
"request payload, request params nor to format url string!"
|
|
507
|
-
"remove unused parameter or fix by changing argument to purposeful name 'payload' or 'params'"
|
|
508
|
-
)
|
|
509
|
-
|
|
510
|
-
def merge_args(self, positional_args: Tuple, keyword_args: Dict[str, Any]) -> Dict[str, Any]:
|
|
511
|
-
"""Merges decorated method args and kwargs into one dictionary.
|
|
512
|
-
This is needed to identify all decorated method arguments by name inside wrapper body.
|
|
513
|
-
We can learn all arguments names from signature.
|
|
514
|
-
|
|
515
|
-
Returns: Dict[str, Any]: all passed args as keyword arguments (excluding "self")
|
|
516
|
-
"""
|
|
517
|
-
all_args_names = [key for key in self.sig.parameters.keys()]
|
|
518
|
-
all_args_dict = dict(self.defaults)
|
|
519
|
-
all_args_dict.update(dict(zip(all_args_names, positional_args)))
|
|
520
|
-
all_args_dict.update(keyword_args)
|
|
521
|
-
all_args_dict.pop("self", None)
|
|
522
|
-
return all_args_dict
|
|
523
|
-
|
|
524
|
-
def __call__(self, func):
|
|
525
|
-
original_func = getattr(func, "_ofunc", func) # grab original function
|
|
526
|
-
self.sig = signature(original_func)
|
|
527
|
-
self.defaults = {
|
|
528
|
-
key: value.default for (key, value) in self.sig.parameters.items() if value.default is not _empty
|
|
529
|
-
}
|
|
530
|
-
self.return_spec = self.specify_return_type()
|
|
531
|
-
self.payload_spec = self.specify_payload_type()
|
|
532
|
-
self.check_params()
|
|
533
|
-
self.request_lookup[original_func.__qualname__] = APIEndpointRequestMeta(
|
|
534
|
-
func=original_func,
|
|
535
|
-
http_request=f"{self.http_method} {self.url}",
|
|
536
|
-
payload_spec=self.payload_spec,
|
|
537
|
-
return_spec=self.return_spec,
|
|
538
|
-
)
|
|
539
|
-
|
|
540
|
-
def wrapper(*args, **kwargs):
|
|
541
|
-
"""Executes each time decorated method is called"""
|
|
542
|
-
_self = self.get_check_instance(*args, **kwargs) # _self refers to APIEndpoints instance
|
|
543
|
-
_kwargs = self.merge_args(args, kwargs)
|
|
544
|
-
payload = _kwargs.get("payload")
|
|
545
|
-
params = _kwargs.get("params")
|
|
546
|
-
url_kwargs = dict_values_to_str(self.url_field_names, _kwargs)
|
|
547
|
-
formatted_url = self.url.format_map(url_kwargs)
|
|
548
|
-
response = _self._request(
|
|
549
|
-
self.http_method,
|
|
550
|
-
formatted_url,
|
|
551
|
-
payload=payload,
|
|
552
|
-
force_json_payload=self.payload_spec.is_json,
|
|
553
|
-
params=params,
|
|
554
|
-
**self.kwargs,
|
|
555
|
-
)
|
|
556
|
-
if self.return_spec.present:
|
|
557
|
-
if self.return_spec.is_json:
|
|
558
|
-
full_json = response.json()
|
|
559
|
-
if self.resp_json_key is not None:
|
|
560
|
-
if isinstance(full_json, dict):
|
|
561
|
-
return full_json.get(self.resp_json_key)
|
|
562
|
-
else:
|
|
563
|
-
raise TypeError(f"Expected dictionary as json payload but found: {type(full_json)}")
|
|
564
|
-
return full_json
|
|
565
|
-
if self.return_spec.payload_type is None:
|
|
566
|
-
pass
|
|
567
|
-
elif issubclass(self.return_spec.payload_type, BaseModel):
|
|
568
|
-
if self.return_spec.sequence_type == DataSequence:
|
|
569
|
-
return response.dataseq(
|
|
570
|
-
cls=self.return_spec.payload_type,
|
|
571
|
-
sourcekey=self.resp_json_key,
|
|
572
|
-
validate=_self._client.validate_responses,
|
|
573
|
-
)
|
|
574
|
-
else:
|
|
575
|
-
return response.dataobj(
|
|
576
|
-
self.return_spec.payload_type, self.resp_json_key, validate=_self._client.validate_responses
|
|
577
|
-
)
|
|
578
|
-
elif issubclass(self.return_spec.payload_type, str):
|
|
579
|
-
return response.text
|
|
580
|
-
elif issubclass(self.return_spec.payload_type, bytes):
|
|
581
|
-
return response.content
|
|
582
|
-
elif issubclass(self.return_spec.payload_type, dict):
|
|
583
|
-
return response.json()
|
|
584
|
-
|
|
585
|
-
wrapper._ofunc = original_func # provide original function to next decorator in chain
|
|
586
|
-
return wrapper
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
class get(request):
|
|
590
|
-
def __init__(self, url: str, resp_json_key: Optional[str] = None, **kwargs):
|
|
591
|
-
super().__init__("GET", url, resp_json_key, **kwargs)
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
class put(request):
|
|
595
|
-
def __init__(self, url: str, resp_json_key: Optional[str] = None, **kwargs):
|
|
596
|
-
super().__init__("PUT", url, resp_json_key, **kwargs)
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
class post(request):
|
|
600
|
-
def __init__(self, url: str, resp_json_key: Optional[str] = None, **kwargs):
|
|
601
|
-
super().__init__("POST", url, resp_json_key, **kwargs)
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
class delete(request):
|
|
605
|
-
def __init__(self, url: str, resp_json_key: Optional[str] = None, **kwargs):
|
|
606
|
-
super().__init__("DELETE", url, resp_json_key, **kwargs)
|